From d6d69b4a0c1efdec7535487e41fa920a6a7d61b1 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 13 Mar 2020 19:11:29 +0000 Subject: [PATCH] --- server/AyaNova/PickList/PickListFetcher.cs | 130 ++++++++--------- server/AyaNova/PickList/PickListSqlBuilder.cs | 137 +++++------------- 2 files changed, 103 insertions(+), 164 deletions(-) diff --git a/server/AyaNova/PickList/PickListFetcher.cs b/server/AyaNova/PickList/PickListFetcher.cs index 62afa8e3..4410e967 100644 --- a/server/AyaNova/PickList/PickListFetcher.cs +++ b/server/AyaNova/PickList/PickListFetcher.cs @@ -15,9 +15,9 @@ namespace AyaNova.PickList { internal static class PickListFetcher { - internal static async Task> GetResponseAsync(AyaType ayaType, string query, AyContext ct, AuthorizationRoles userRoles) + internal static async Task> GetResponseAsync(AyaType ayaType, string autoCompleteQuery, AyContext ct, AuthorizationRoles userRoles) { - + var PickList = PickListFactory.GetAyaPickList(ayaType); //was the name not found as a list? @@ -52,14 +52,14 @@ namespace AyaNova.PickList List TemplateColumnNames = PickList.GetFieldListFromTemplate(jTemplate); //BUILD THE QUERY - - var q = PickListSqlBuilder.Build(PickList.ColumnDefinitions, TemplateColumnNames); - - + var q = PickListSqlBuilder.Build(PickList, TemplateColumnNames, autoCompleteQuery); + + + //RETURN OBJECTS - var ret=new List(); - + var ret = new List(); + //QUERY THE DB using (var command = ct.Database.GetDbConnection().CreateCommand()) @@ -72,80 +72,80 @@ namespace AyaNova.PickList { while (dr.Read()) { -// List row = new List(returnRowColumnCount); + // List row = new List(returnRowColumnCount); -// //INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST -// foreach (string TemplateField in ListViewFieldList) -// { + // //INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST + // foreach (string TemplateField in ListViewFieldList) + // { -// //get the AyaObjectFieldDefinition -// AyaPickListFieldDefinition f = PickList.FieldDefinitions.FirstOrDefault(x => x.FieldKey == TemplateField); -// if (f.IsCustomField) -// { + // //get the AyaObjectFieldDefinition + // AyaPickListFieldDefinition f = PickList.FieldDefinitions.FirstOrDefault(x => x.FieldKey == TemplateField); + // if (f.IsCustomField) + // { -// AyaFieldData AyaField = new AyaFieldData(); -// var cust = dr.GetString(SelectBuild.map[f.GetSqlValueColumnName()]); -// if (!string.IsNullOrWhiteSpace(cust)) -// { -// JObject j = JObject.Parse(cust); -// //convert field name to cust name then get value -// var InternalCustomFieldName = AyaFormFieldDefinitions.TranslateLTCustomFieldToInternalCustomFieldName(TemplateField); -// //Sometimes a custom field is specified but doesn't exist in the collection so don't assume it's there -// // AyaField.v = j[InternalCustomFieldName].Value(); -// JToken o = j[InternalCustomFieldName]; -// if (o != null) -// AyaField.v = o.Value(); -// else -// AyaField.v = null; + // AyaFieldData AyaField = new AyaFieldData(); + // var cust = dr.GetString(SelectBuild.map[f.GetSqlValueColumnName()]); + // if (!string.IsNullOrWhiteSpace(cust)) + // { + // JObject j = JObject.Parse(cust); + // //convert field name to cust name then get value + // var InternalCustomFieldName = AyaFormFieldDefinitions.TranslateLTCustomFieldToInternalCustomFieldName(TemplateField); + // //Sometimes a custom field is specified but doesn't exist in the collection so don't assume it's there + // // AyaField.v = j[InternalCustomFieldName].Value(); + // JToken o = j[InternalCustomFieldName]; + // if (o != null) + // AyaField.v = o.Value(); + // else + // AyaField.v = null; -// row.Add(AyaField); -// } + // row.Add(AyaField); + // } -// /* -// TODO: Custom field handling -// GetName works just not with multipart identifiers -// I could force naming by making all fields and AS, or -// I could map the ordinal when generating the Select fields so that I have a map to refer to here -// mapping in advance actually makes a lot of sense, then no more of this fragility of going by pointer index and hoping for the best -// it would just be premapped out. + // /* + // TODO: Custom field handling + // GetName works just not with multipart identifiers + // I could force naming by making all fields and AS, or + // I could map the ordinal when generating the Select fields so that I have a map to refer to here + // mapping in advance actually makes a lot of sense, then no more of this fragility of going by pointer index and hoping for the best + // it would just be premapped out. -// dr.GetOrdinal(f.SqlValueColumnName) -// 'dr.GetOrdinal(f.SqlValueColumnName)' threw an exception of type 'System.IndexOutOfRangeException' -// f.SqlValueColumnName -// "awidget.customfields" -// dr.GetName(nCurrentColumnPointer) -// "customfields" -// dr.GetOrdinal("customfields"); -// 5 + // dr.GetOrdinal(f.SqlValueColumnName) + // 'dr.GetOrdinal(f.SqlValueColumnName)' threw an exception of type 'System.IndexOutOfRangeException' + // f.SqlValueColumnName + // "awidget.customfields" + // dr.GetName(nCurrentColumnPointer) + // "customfields" + // dr.GetOrdinal("customfields"); + // 5 -// */ -// } -// else -// { -// AyaFieldData AyaField = new AyaFieldData(); -// AyaField.v = dr.GetValue(SelectBuild.map[f.GetSqlValueColumnName()]); + // */ + // } + // else + // { + // AyaFieldData AyaField = new AyaFieldData(); + // AyaField.v = dr.GetValue(SelectBuild.map[f.GetSqlValueColumnName()]); -// if (f.SqlIdColumnName != null) -// { -// var ordinal = SelectBuild.map[f.SqlIdColumnName]; -// if (!await dr.IsDBNullAsync(ordinal)) -// AyaField.i = dr.GetInt64(ordinal); + // if (f.SqlIdColumnName != null) + // { + // var ordinal = SelectBuild.map[f.SqlIdColumnName]; + // if (!await dr.IsDBNullAsync(ordinal)) + // AyaField.i = dr.GetInt64(ordinal); -// } -// row.Add(AyaField); -// } -// } -// rows.Add(row); + // } + // row.Add(AyaField); + // } + // } + // rows.Add(row); } } - + } - return ret; + return ret; } diff --git a/server/AyaNova/PickList/PickListSqlBuilder.cs b/server/AyaNova/PickList/PickListSqlBuilder.cs index d644a746..714c4493 100644 --- a/server/AyaNova/PickList/PickListSqlBuilder.cs +++ b/server/AyaNova/PickList/PickListSqlBuilder.cs @@ -9,120 +9,59 @@ using Microsoft.Extensions.Logging; namespace AyaNova.PickList { - + internal static class PickListSqlBuilder { - //Build the SELECT portion of a list query based on the ListView fields - internal static string Build(List objectFieldsList, List listViewFieldList) + //Build the query for a picklist request + internal static string Build(IAyaPickList pickList, List templateColumnNames, string autoCompleteQuery) { - -//TODO: build a sql select and order by and a where clause that searches appropriately in each field (tags) -//it should return results based on the query where there is a single name (display) column and an id column for rowid -//and the fields should be combined in a standard way separated by spaces "Widget widgetserial username" for compactness +//TODO: if no autocompletequery returns the first XX results without querying in natural order by column names +//if autocomplete returns teh first XX results with query in natural order by column names -// StringBuilder sb = new StringBuilder(); -// sb.Append("SELECT "); + //TODO: build a sql List columnDefinitionsselect and order by and a where clause that searches appropriately in each field (tags) + //it should return results based on the query where there is a single name (display) column and an id column for rowid + //and the fields should be combined in a standard way separated by spaces "Widget widgetserial username" for compactness -// //DEPRECATED -// // //Default ID column for each row (always is aliased as df) -// // AyaPickListFieldDefinition def = objectFieldsList.FirstOrDefault(x => x.FieldKey == "df"); -// // if (def == null) -// // { -// // throw new System.ArgumentNullException("PickListSqlSelectBuilder: objectFieldList is missing the df default field"); -// // } -// // if (string.IsNullOrEmpty(def.SqlIdColumnName)) -// // { -// // sb.Append("id");//default when no alternate column is specified -// // } -// // else -// // { -// // sb.Append(def.SqlIdColumnName); -// // } - -// // sb.Append(" AS df"); - -// //keep track of which custom fields columns were added already -// //this ensures that if there is more than one set of custom fields like from two different objects in the list -// //only unique ones will be returned by query -// // Dictionary CustomFieldColumnsAddedToQuery = new Dictionary(); -// //map sql column name to ordinal name -// Dictionary map = new Dictionary(); - -// //DEPRECATED map.Add("df", 0); -// int nOrdinal = 0; - -// var firstColumnAdded = false; -// foreach (string ColumnName in listViewFieldList) -// { -// // //skip the df column, it's already been processed above -// // if (ColumnName == "df") -// // continue; -// AyaPickListFieldDefinition o = objectFieldsList.FirstOrDefault(x => x.FieldKey == ColumnName); -// #if (DEBUG) -// //Developers little helper -// if (o == null) -// { -// throw new System.ArgumentNullException($"DEV ERROR in PickListSqlSelectBuilder.cs: field {ColumnName} specified in template was NOT found in ObjectFields list"); -// } -// #endif -// if (o != null) -// {//Ignore missing fields in production + //lists to collect the clauses so to avoid comma fuckery + List lSelect = new List(); + List lWhere = new List(); -// if (o.IsCustomField) -// { //if any are custom field then add custom fields column to query -// var CustomFieldSqlColumnName = o.GetSqlValueColumnName(); -// //has it been added yet? -// if (!map.ContainsKey(CustomFieldSqlColumnName)) -// { //nope -// if (firstColumnAdded) -// sb.Append(", "); -// sb.Append(CustomFieldSqlColumnName); -// firstColumnAdded = true; -// map.Add(CustomFieldSqlColumnName, nOrdinal++); -// } -// //if it was already added then can just ignore it -// // else -// // { -// // map.Add(ColumnName, CustomFieldColumnsAddedToQuery[CustomFieldSqlColumnName]); -// // } + //Add rowid column as it's always required + AyaPickListFieldDefinition rowIdColumn = pickList.ColumnDefinitions.FirstOrDefault(x => x.IsRowId == true); + lSelect.Add(rowIdColumn.SqlIdColumnName + " AS rowid"); -// } -// else -// { -// var valueColumnName = o.GetSqlValueColumnName(); -// if (!map.ContainsKey(valueColumnName)) -// { -// if (firstColumnAdded) -// sb.Append(", "); -// sb.Append(valueColumnName); -// firstColumnAdded = true; -// map.Add(valueColumnName, nOrdinal++); -// } + foreach (string ColumnName in templateColumnNames) + { -// //does it also have an ID column? -// var idColumnName = o.SqlIdColumnName; -// if (!string.IsNullOrWhiteSpace(idColumnName)) -// { -// if (!map.ContainsKey(idColumnName)) -// { -// if (firstColumnAdded) -// sb.Append(", "); -// sb.Append(idColumnName); -// firstColumnAdded = true; -// map.Add(idColumnName, nOrdinal++); -// } -// } + AyaPickListFieldDefinition o = pickList.ColumnDefinitions.FirstOrDefault(x => x.FieldKey == ColumnName); +#if (DEBUG) + if (o == null) + { + throw new System.ArgumentNullException($"DEV ERROR in PickListSqlBuilder.cs: field {ColumnName} specified in template was NOT found in columnDefinitions list"); + } +#endif + if (o != null) + {//Ignore missing fields in production -// } + var valueColumnName = o.GetSqlValueColumnName(); + + lSelect.Add(valueColumnName); + string sWhere=$"{valueColumnName} LIKE '%{autoCompleteQuery" -// } -// } -// // return new SqlSelectBuilderResult() { map = map, Select = sb.ToString() }; + + + + } + } + + + return sbSelect.ToString() + pickList.SQLFrom + sbWhere.ToString(); + }