//#define AYSHOWKPIQUERYINFO using AyaNova.Biz; using Newtonsoft.Json.Linq; using Microsoft.Extensions.Logging; using AyaNova.Models; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace AyaNova.KPI { internal static class KPIFetcher { #if (AYSHOWKPIQUERYINFO) #if (DEBUG) #warning FYI AYSHOWKPIQUERYINFO is defined #else #error ### HOLDUP: AYSHOWKPIQUERYINFO is defined in a RELEASE BUILD!!!! #endif #endif //case 4200 //### WARNING: IF CHANGE HERE **must** update CLIENT dash-base.js same named constant as it relies on it's own copy of this CONSTANT value to indicate if there are possibly more internal const int KPI_LIST_MAX_ITEMS_TO_RETURN = 100;//Maximum number of items to return from a KPI dashboard query so as not to overwhelm the client with too much data //////////////////////////////////////////////// // Get the kpi data requested // // internal static async Task GetResponseAsync(AyContext ct, KPIRequestOptions options, AuthorizationRoles userRoles, ILogger log, long userId) { /* return a jobject like: { error: "if error this key present", meta: {username:"joe blow","date range:blah to blah"} data:[{r1},{r2},{r3}] } */ //instantiate the list var kpi = KPIFactory.GetAyaKPI(options.KPIName); if (!AyaNova.Api.ControllerHelpers.Authorized.HasAnyRole(userRoles, kpi.AllowedRoles)) { return JObject.FromObject(new { error = "NOT AUTHORIZED" }); } kpi.BuildQuery(options, userId); if (!string.IsNullOrWhiteSpace(kpi.ErrorMessage)) { return JObject.FromObject(new { error = kpi.ErrorMessage }); } JArray jData = new JArray(); JArray jMeta = new JArray(); #if (DEBUG && AYSHOWKPIQUERYINFO) System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); #endif //QUERY THE DB using (var command = ct.Database.GetDbConnection().CreateCommand()) { await ct.Database.OpenConnectionAsync(); //GET DATA RETURN ROWS command.CommandText = kpi.DataQuery; try { #if (DEBUG && AYSHOWKPIQUERYINFO) stopWatch.Start(); #endif using (var dr = await command.ExecuteReaderAsync()) { #if (DEBUG && AYSHOWKPIQUERYINFO) stopWatch.Stop(); log.LogInformation($"(debug) KPIFetcher:GetResponse DATA query took {stopWatch.ElapsedMilliseconds}ms to execute: {kpi.DataQuery}"); stopWatch.Reset(); #endif while (dr.Read()) { //only one column and it's the zeroth json string column if (!dr.IsDBNull(0)) jData.Add(JObject.Parse(dr.GetString(0))); } } if (!string.IsNullOrWhiteSpace(kpi.MetaQuery)) { //GET META DATA ROWS command.CommandText = kpi.MetaQuery; #if (DEBUG && AYSHOWQUERYINFO) stopWatch.Start(); #endif using (var dr = await command.ExecuteReaderAsync()) { #if (DEBUG && AYSHOWQUERYINFO) stopWatch.Stop(); log.LogInformation($"(debug) KPIFetcher:GetResponse META query took {stopWatch.ElapsedMilliseconds}ms to execute: {qTotalRecordsQuery}"); #endif while (dr.Read()) { //only one column and it's the zeroth json string column if (!dr.IsDBNull(0)) jMeta.Add(JObject.Parse(dr.GetString(0))); } } } } catch (Npgsql.PostgresException e) { //log out the exception and the query log.LogError("KPIFetcher:GetResponseAsync query failed. Data Query was:"); log.LogError(kpi.DataQuery); log.LogError("Meta Query was:"); log.LogError(kpi.MetaQuery); log.LogError(e, "DB Exception"); throw new System.Exception("KPIFetcher:GetResponseAsync - Query failed see log"); } catch (System.Exception e) { //ensure any other type of exception gets surfaced properly //log out the exception and the query log.LogError("KPIFetcher:GetResponseAsync unexpected failure. Data Query was:"); log.LogError(kpi.DataQuery); log.LogError("Meta Query was:"); log.LogError(kpi.MetaQuery); log.LogError(e, "Exception"); throw new System.Exception("KPIFetcher:GetResponseAsync - unexpected failure see log"); } return JObject.FromObject(new { meta = jMeta, data = jData }); } } }//eoc }//eons