static void Main(string[] args) { Authentication authentication = new Authentication(); //Load additional data connctors like Kusto MashupLibraryProvider mp = MashupLibraryProvider.Assembly(new AssemblyName("PowerBIExtensions")); MashupLibraryProvider.SetProviders(mp); string code = File.ReadAllText(args[0]); PQDocument pqDoc = new PQDocument(code); PrintQueries(pqDoc); Console.Write("Select Query:"); string queryName = Console.ReadLine(); var queryParameters = pqDoc.Parameters; List <NamedExpression> parameterReplacements = new List <NamedExpression>(); foreach (var queryParameter in queryParameters) { object defaultQueryValue = queryParameter.DefaultValue; Console.Write($"{queryParameter.Name} ({queryParameter.DefaultValue ?? "null"}):"); string newQueryParameter = Console.ReadLine(); if (newQueryParameter != "") { parameterReplacements.Add(new NamedExpression(queryParameter.Name, PQLiteral.FromInput(queryParameter.Type, newQueryParameter).Code)); } } pqDoc = pqDoc.UpdateExpressions(parameterReplacements); //Engine MashupConnectionStringBuilder connectionString = new MashupConnectionStringBuilder() { //Choose either Mashup or Package Mashup = pqDoc.Code, //Full document, like when a pq is extracted from a pbit //Package = MashupPackage.ToBase64String(queryName, "#shared"), //Single expression, as seen in Advanced view //Query to evaluate Location = queryName, }; MashupConnection connection = new MashupConnection(connectionString.ToString()); QueryExecutionStatus queryStatus = QueryExecutionStatus.NotStarted; Action authUpdateTask = null; object authUpdateLock = new object(); DataSourceSetting ds = null; connection.DataSourceSettingNeeded += (missingAuthSender, e) => { authUpdateTask = () => { Guid activityId = Guid.NewGuid(); Console.WriteLine(e.Details); foreach (var dataSource in e.Details.DataSources) { DataSourceSetting dataSourceSetting; if (dataSource.TryFindBestMatch(e.NewSettings.Keys, out var matchingDataSource)) { dataSourceSetting = e.NewSettings[matchingDataSource]; } else { bool success; queryStatus = QueryExecutionStatus.AwaitingUserAuthentication; (success, dataSourceSetting) = authentication.UserAAD(dataSource); if (!success) { queryStatus = QueryExecutionStatus.Failed; break; } } e.NewSettings[dataSource] = dataSourceSetting; ds = dataSourceSetting; } queryStatus = QueryExecutionStatus.RetryPending; }; lock (authUpdateLock) { queryStatus = QueryExecutionStatus.AuthenticationNeeded; Monitor.PulseAll(authUpdateLock); while (queryStatus == QueryExecutionStatus.AuthenticationNeeded) { Monitor.Wait(authUpdateLock); } } }; connection.Open(); MashupCommand cmd = connection.CreateCommand(); cmd.MashupCommandTextDialect = MashupCommandTextDialect.M; cmd.CommandText = connectionString.Location; cmd.CommandType = System.Data.CommandType.TableDirect; new Thread(() => { while (queryStatus != QueryExecutionStatus.Complete) { try { lock (authUpdateLock) { queryStatus = QueryExecutionStatus.Running; Monitor.PulseAll(authUpdateLock); } using (var reader = cmd.ExecuteReader(CommandBehavior.Default, MashupCommandBehavior.Default)) { lock (authUpdateLock) { queryStatus = QueryExecutionStatus.Serializing; Monitor.PulseAll(authUpdateLock); } object[] rowValues = new object[reader.VisibleFieldCount]; while (reader.Read()) { reader.GetValues(rowValues); Console.WriteLine(string.Join(", ", rowValues)); } } lock (authUpdateLock) { queryStatus = QueryExecutionStatus.Complete; Monitor.PulseAll(authUpdateLock); } } catch (MashupCredentialException) { queryStatus = QueryExecutionStatus.NotStarted; } catch (MashupValueException) { queryStatus = QueryExecutionStatus.NotStarted; } } }).Start(); lock (authUpdateLock) { while (queryStatus != QueryExecutionStatus.Complete && queryStatus != QueryExecutionStatus.Failed && queryStatus != QueryExecutionStatus.RetryReady) { if (queryStatus == QueryExecutionStatus.AuthenticationNeeded) { authUpdateTask(); Monitor.PulseAll(authUpdateLock); } else { Monitor.Wait(authUpdateLock); } } } }