private void BuildScriptwordTree( IBdoScriptwordDictionaryDto dictionaryDto, List <BdoScriptwordDefinition> allDefinitions, IBdoLog log = null, IBdoScriptwordDefinition parentDefinition = null) { if (dictionaryDto == null) { return; } List <BdoScriptwordDefinitionDto> scriptWordDefinitionDtos = parentDefinition == null ? dictionaryDto.Definitions : parentDefinition?.Dto.Children; // we recursively retrieve the sub script words foreach (IBdoScriptwordDefinitionDto definitionDto in scriptWordDefinitionDtos) { // if the current script word is a reference then if (!string.IsNullOrEmpty(definitionDto.ReferenceUniqueName)) { // we retrieve the reference script word IBdoScriptwordDefinition referenceScriptwordDefinition = allDefinitions.Find(p => p.KeyEquals(definitionDto.ReferenceUniqueName) == true); if (referenceScriptwordDefinition == null) { log?.AddError( title: "Child reference '" + definitionDto.ReferenceUniqueName + "' not found in index for script word '" + definitionDto.Key() + "'"); } else { parentDefinition?.Children?.Add(referenceScriptwordDefinition.UniqueId?.ToUpper(), referenceScriptwordDefinition); } } else { IBdoScriptwordDefinition definition = allDefinitions.Find(p => p.Dto?.KeyEquals(definitionDto) == true); if (definition == null) { log?.AddError(title: "Script word '" + definitionDto.Key() + "' not found in code"); } else { if (parentDefinition != null) { parentDefinition.Children.Add(definition.UniqueId?.ToUpper(), definition); definition.Parent = parentDefinition; } else { _store.Add <IBdoScriptwordDefinition>(definition); } BuildScriptwordTree(dictionaryDto, allDefinitions, log, definition); } } } }
/// <summary> /// Extract extension definition from the specified assembly. /// </summary> /// <param name="assembly">The assembly to consider.</param> /// <param name="resourceFullName">The full name of the resouce to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>The created library.</returns> private IBdoExtensionDefinition ExtractExtensionDefinition( Assembly assembly, string resourceFullName = null, IBdoLog log = null) { IBdoExtensionDefinition definition = null; if (assembly != null) { if (resourceFullName == null) { resourceFullName = Array.Find( assembly.GetManifestResourceNames(), p => p.EndsWith(__DefaultResourceFileName, StringComparison.OrdinalIgnoreCase)); } Stream stream = null; if (resourceFullName == null) { log?.AddError("Could not find any library definition in assembly (default named '" + __DefaultResourceFileName.ToLower() + "')"); } else { try { stream = assembly.GetManifestResourceStream(resourceFullName); if (stream == null) { log?.AddError("Could not find the library definition named '" + resourceFullName + "' in assembly"); } else { IBdoExtensionDefinitionDto definitionDto = null; XmlSerializer serializer = new XmlSerializer(typeof(BdoExtensionDefinitionDto)); definitionDto = (BdoExtensionDefinitionDto)serializer.Deserialize(stream); definitionDto?.Initialize(); definition = new BdoExtensionDefinition(definitionDto); } } catch (Exception ex) { log?.AddException(ex); } finally { stream?.Close(); } } } return(definition); }
/// <summary> /// Sorts the specified query considering the specified query script. /// </summary> /// <param name="query">The database query to consider.</param> /// <param name="sortQuery">The sort query text to consider.</param> /// <param name="definition">The definition to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>The built query.</returns> public static IDbSingleQuery Sort( this IDbSingleQuery query, string sortQuery, DbApiSortDefinition definition = null, IBdoLog log = null) { if (query != null && !string.IsNullOrEmpty(sortQuery)) { query.OrderByClause = new DbQueryOrderByClause(); foreach (string fieldItem in sortQuery.Split(',')) { var statement = new DbQueryOrderByStatement(); var fieldItemParams = fieldItem?.Trim().Split(' '); if (fieldItemParams.Length > 0) { string fieldName = fieldItemParams[0]?.Trim(); if (!definition.ContainsKey(fieldName)) { log?.AddError("Undefined field '" + fieldName + "' in order statement", resultCode: "user"); } else { statement.Field = definition?[fieldName]?.Field ?? DbFluent.Field(fieldName); statement.Sorting = DataSortingModes.Ascending; if (fieldItemParams.Length > 1) { string direction = fieldItemParams[1]?.Trim(); if (string.Equals(direction, "desc")) { statement.Sorting = DataSortingModes.Descending; query.OrderByClause.Statements.Add(statement); } else if (!string.Equals(direction, "asc")) { log?.AddError("Invalid order direction '" + direction + "'", resultCode: "user"); } else { query.OrderByClause.Statements.Add(statement); } } } } } } return(query); }
/// <summary> /// Gets the assembly of this instance from embed resource. /// </summary> /// <param name="appDomain">Application domain to consider.</param> /// <param name="assemblyName">The assembly name to use.</param> /// <param name="log">The loading log to consider.</param> /// <returns>The assembly of this instance.</returns> public static Assembly LoadAssembly(AppDomain appDomain, string assemblyName, IBdoLog log = null) { Assembly assembly = null; if ((appDomain != null) && (!string.IsNullOrEmpty(assemblyName))) { assembly = Array.Find(appDomain.GetAssemblies(), p => p.GetName().Name.KeyEquals(assemblyName)); if (assembly == null) { try { assembly = Assembly.Load(assemblyName); } catch (FileNotFoundException) { log?.AddError("Could not find the assembly '" + assemblyName + "'"); } catch (Exception ex) { log?.AddException("Error while attempting to load assembly '" + assemblyName + "'", description: ex.ToString()); } } } return(assembly); }
// ------------------------------------------ // ACCESSORS // ------------------------------------------ #region Accessors // SQL commands /// <summary> /// Gets the SQL text of the specified query. /// </summary> /// <param name="query">The query to consider.</param> /// <param name="parameterMode">Indicates whether parameters are replaced.</param> /// <param name="parameterSet">The parameter set to consider.</param> /// <param name="scriptVariableSet">The script variable set to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>Returns the SQL text of the specified query.</returns> public string CreateCommandText( IDbQuery query, DbQueryParameterMode parameterMode = DbQueryParameterMode.ValueInjected, IDataElementSet parameterSet = null, IScriptVariableSet scriptVariableSet = null, IBdoLog log = null) { string sqlText = ""; if (QueryBuilder == null) { log?.AddError("Data builder missing"); } else { var subLog = new BdoLog(); sqlText = QueryBuilder.BuildQuery(query, parameterMode, parameterSet, scriptVariableSet, subLog); log?.AddEvents(subLog); if (subLog.HasErrorsOrExceptions()) { return(StringHelper.__NoneString); } } return(sqlText); }
// Deserialiaze ---------------------------- /// <summary> /// Loads a data item from the specified file path. /// </summary> /// <param name="filePath">The path of the Xml file to load.</param> /// <param name="scope">The scope to consider.</param> /// <param name="scriptVariableSet">The set of script variables to consider.</param> /// <param name="log">The output log of the method.</param> /// <param name="xmlSchemaSet">The XML schema set to consider for checking.</param> /// <param name="mustFileExist">Indicates whether the file must exist.</param> /// <param name="isRuntimeUpdated">Indicates whether it is updated in runtime.</param> /// <returns>The loaded log.</returns> /// <remarks>If the XML schema set is null then the schema is not checked.</remarks> public static T Load <T>( String filePath, IBdoScope scope = null, IScriptVariableSet scriptVariableSet = null, IBdoLog log = null, XmlSchemaSet xmlSchemaSet = null, bool mustFileExist = true, bool isRuntimeUpdated = true) where T : class, IDataItem { T dataItem = default; StreamReader streamReader = null; if (!File.Exists(filePath)) { if (mustFileExist) { log?.AddError("File not found ('" + filePath + "'). Could not load '" + typeof(T).Name + "' object"); } } else { try { IBdoLog checkLog = new BdoLog(); if (xmlSchemaSet != null) { XDocument xDocument = XDocument.Load(filePath); xDocument.Validate(xmlSchemaSet, (o, e) => checkLog.AddError("File not valid ('" + filePath + "'). Could not load '" + typeof(T).Name + "' object")); log?.AddEvents(checkLog); } if (!checkLog.HasErrorsOrExceptions()) { // then we load XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); streamReader = new StreamReader(filePath); dataItem = xmlSerializer.Deserialize(XmlReader.Create(streamReader)) as T; if (isRuntimeUpdated) { dataItem?.UpdateRuntimeInfo(scope, scriptVariableSet, log); } } } catch (Exception ex) { log?.AddException(ex); } finally { streamReader?.Close(); } } return(dataItem); }
/// <summary> /// Gets the target objects from the specified source. /// </summary> /// <param name="sourceElement">The source element to consider.</param> /// <param name="pathDetail">The path detail to consider.</param> /// <param name="scope">The scope to consider.</param> /// <param name="scriptVariableSet">The script variable set to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>Returns the target objects.</returns> public static List <object> Get( DataElement sourceElement = null, DataElementSet pathDetail = null, IBdoScope scope = null, IScriptVariableSet scriptVariableSet = null, IBdoLog log = null) { List <object> objects = new List <object>(); if (sourceElement == null) { log?.AddError("Source element missing"); } else { if (!(sourceElement.Items[0] is RepositoryFile file)) { log?.AddError("Source file missing"); } } return(objects); }
// ------------------------------------------ // CHECK, UPDATE, REPAIR // ------------------------------------------ #region Check Repair /// <summary> /// Checks this instance. /// </summary> /// <param name="isExistenceChecked">Indicates whether the carrier existence is checked.</param> /// <param name="item">The item to consider.</param> /// <param name="specificationAreas">The specification areas to consider.</param> /// <returns>Returns the check log.</returns> public override IBdoLog Check <T>( bool isExistenceChecked = true, T item = default, string[] specificationAreas = null) { IBdoLog log = base.Check <T>(isExistenceChecked); if (string.IsNullOrEmpty(Path)) { log.AddError("Folder path missing"); } return(log); }
/// <summary> /// Loads the data item from the specified file path. /// </summary> /// <typeparam name="T">The data item class to consider.</typeparam> /// <param name="xmlString">The Xml string to load.</param> /// <param name="scope">The scope to consider.</param> /// <param name="scriptVariableSet">The set of script variables to consider.</param> /// <param name="log">The output log of the load method.</param> /// <param name="xmlSchemaSet">The XML schema set to consider for checking.</param> /// <returns>The loaded log.</returns> /// <remarks>If the XML schema set is null then the schema is not checked.</remarks> public static T LoadFromString <T>( String xmlString, IBdoScope scope = null, IScriptVariableSet scriptVariableSet = null, IBdoLog log = null, XmlSchemaSet xmlSchemaSet = null) where T : DataItem { T dataItem = null; if (xmlString != null) { StreamReader streamReader = null; try { IBdoLog checkLog = new BdoLog(); if (xmlSchemaSet != null) { XDocument xDocument = XDocument.Parse(xmlString); xDocument.Validate(xmlSchemaSet, (o, e) => { log?.AddError( title: "Xml string not valid", description: e.Message); }); log?.AddEvents(checkLog); } if (!checkLog.HasErrorsOrExceptions()) { // then we load XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringReader stringReader = new StringReader(xmlString); dataItem = xmlSerializer.Deserialize(XmlReader.Create(stringReader)) as T; dataItem?.UpdateRuntimeInfo(scope, scriptVariableSet, log); } } catch (Exception ex) { log?.AddException(ex); } finally { streamReader?.Close(); } } return(dataItem); }
public void CreateEventsTest() { _log = new BdoLog(); for (int i = 0; i < _testData.itemNumber; i++) { _log.AddError("Error" + i); _log.AddException("Exception" + i); _log.AddMessage("Message" + i); _log.AddWarning("Warning" + i); _log.AddSubLog(new BdoLog()); } Test(_log); }
/// <summary> /// Loads the specified BindOpen extension dictionary. /// </summary> /// <param name="assembly">The assembly to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>The created library.</returns> private ITBdoExtensionDictionaryDto <T> ExtractDictionaryFromAssembly <T>( Assembly assembly, IBdoLog log = null) where T : BdoExtensionItemDefinitionDto { TBdoExtensionDictionaryDto <T> dictionary = default; if (assembly != null) { string resourceFileName = GetDictionaryResourceName <T>(); string resourceFullName = Array.Find( assembly.GetManifestResourceNames(), p => p.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase)); Stream stream = null; if (resourceFullName == null) { log?.AddWarning("No dictionary named '" + resourceFileName + "' found in assembly"); } else { try { stream = assembly.GetManifestResourceStream(resourceFullName); if (stream == null) { log?.AddError("Could not open the item dictionary named '" + resourceFullName + "' in assembly"); } else { Type type = GetDictionaryType <T>(); XmlSerializer serializer = new XmlSerializer(type); dictionary = (TBdoExtensionDictionaryDto <T>)serializer.Deserialize(stream); } } catch (Exception ex) { log?.AddException(ex); } finally { stream?.Close(); } } } return(dictionary); }
/// <summary> /// Deletes a local folder. /// </summary> /// <param name="localfolderUri">The local Uri to consider.</param> /// <param name="log">The log to consider.</param> public static void DeleteFolder( string localfolderUri, IBdoLog log = null) { try { if (Directory.Exists(localfolderUri)) { Directory.Delete(localfolderUri, true); log?.AddMessage("Folder '" + localfolderUri + "' deleted"); } else { log?.AddError("Could not delete folder '" + localfolderUri + "'"); } } catch (IOException exception) { log?.AddException("Could not delete folder '" + localfolderUri + "'", description: exception.ToString()); } }
// ----------------------------------------------- // OTHER METHODS // ----------------------------------------------- #region Other_Methods // Delete --------------------------------------------------- /// <summary> /// Deletes a local file. /// </summary> /// <param name="localFileUri">The local Uri to consider.</param> /// <param name="log">The log to consider.</param> public static void DeleteFile( string localFileUri, IBdoLog log = null) { try { if (File.Exists(localFileUri)) { Directory.Delete(localFileUri, true); log?.AddMessage("File '" + localFileUri + "' deleted"); } else { log?.AddError("Could not delete file '" + localFileUri + "'"); } } catch (IOException exception) { log?.AddException(exception); } }
// Entities ------------------------------------------------ /// <summary> /// Creates the instance of the specified definition. /// </summary> /// <param name="scope">The scope to consider.</param> /// <param name="definitionUniqueId">The unique ID of the definition to consider.</param> /// <param name="log">The log to consider.</param> public static IBdoEntityConfiguration CreateEntityConfiguration( this IBdoScope scope, string definitionUniqueId, IBdoLog log = null) { IBdoEntityConfiguration configuration = null; IBdoEntityDefinition definition = scope.ExtensionStore.GetItemDefinitionWithUniqueId <BdoEntityDefinition>(definitionUniqueId); if (definition == null) { log?.AddError("Could not retrieve the extension item '" + definitionUniqueId + "' of kind '" + BdoExtensionItemKind.Entity.ToString() + "'"); } else { configuration = BdoExtensionFactory.CreateEntityConfiguration(definitionUniqueId); configuration.Update(definition); } return(configuration); }
/// <summary> /// Creates the instance of the specified definition. /// </summary> /// <param name="scope">The scope to consider.</param> /// <param name="configuration">The configuration to consider.</param> /// <param name="name">The name to consider.</param> /// <param name="log">The log to consider.</param> /// <param name="scriptVariableSet">The script variable set to use.</param> /// <returns>Returns the created task.</returns> public static BdoTask CreateTask( this IBdoScope scope, IBdoTaskConfiguration configuration = null, string name = null, IBdoLog log = null, IScriptVariableSet scriptVariableSet = null) { BdoTask task = null; if (scope?.Check(true).HasErrorsOrExceptions() == false) { if (configuration != null) { // we get the task class reference IBdoTaskDefinition definition = scope.ExtensionStore.GetItemDefinitionWithUniqueId <IBdoTaskDefinition>(configuration?.DefinitionUniqueId); if (definition == null) { log?.AddError("Could not retrieve the extension task '" + configuration.DefinitionUniqueId + "' definition"); } else { // we intantiate the task AssemblyHelper.CreateInstance(definition.RuntimeType, out object item).AddEventsTo(log); if (!log.HasErrorsOrExceptions()) { task = item as BdoTask; task.Name = name ?? configuration?.Name; task.UpdateFromElementSet <TaskInputAttribute>(configuration, scope, scriptVariableSet); task.UpdateFromElementSet <TaskOutputAttribute>(configuration, scope, scriptVariableSet); } } } } return(task); }
/// <summary> /// Creates the instance of the specified definition. /// </summary> /// <param name="scope">The scope to consider.</param> /// <param name="configuration">The configuration to consider.</param> /// <param name="name">The name to consider.</param> /// <param name="log">The log to consider.</param> /// <param name="scriptVariableSet">The script variable set to use.</param> /// <returns>Returns the created carrier.</returns> public static BdoCarrier CreateCarrier( this IBdoScope scope, IBdoCarrierConfiguration configuration = null, string name = null, IBdoLog log = null, IScriptVariableSet scriptVariableSet = null) { BdoCarrier carrier = null; if (scope?.Check(true).HasErrorsOrExceptions() == false) { if (configuration != null) { // we get the carrier class reference IBdoCarrierDefinition definition = scope.ExtensionStore.GetItemDefinitionWithUniqueId <IBdoCarrierDefinition>(configuration.DefinitionUniqueId); if (definition == null) { log?.AddError("Could not retrieve the extension carrier '" + configuration.DefinitionUniqueId + "' definition"); } else { // we intantiate the carrier AssemblyHelper.CreateInstance(definition.RuntimeType, out object item).AddEventsTo(log); if (item != null) { carrier = item as BdoCarrier; carrier.Name = name ?? configuration?.Name; carrier.UpdateFromElementSet <DetailPropertyAttribute>(configuration, scope, scriptVariableSet); } } } } return(carrier); }
/// <summary> /// Builds the SQL text from the specified database query. /// </summary> /// <param name="query">The database data query to build.</param> /// <param name="parameterMode">The display mode of parameters to consider.</param> /// <param name="parameterSet">The parameter set to consider.</param> /// <param name="scriptVariableSet">The interpretation variables to consider.</param> /// <param name="log">The log to consider.</param> /// <returns>Returns the built query text.</returns> public string BuildQuery( IDbQuery query, DbQueryParameterMode parameterMode = DbQueryParameterMode.ValueInjected, IDataElementSet parameterSet = null, IScriptVariableSet scriptVariableSet = null, IBdoLog log = null) { var queryString = ""; if (query != null) { try { if (query is DbSingleQuery singleDbQuery) { (scriptVariableSet ??= new ScriptVariableSet()).SetDbBuilder(this); queryString = GetSqlText_Query(singleDbQuery, parameterSet, scriptVariableSet, log); } else if (query is DbCompositeQuery compositeDbQuery) { (scriptVariableSet ??= new ScriptVariableSet()).SetDbBuilder(this); queryString = GetSqlText_Query(compositeDbQuery, parameterSet, scriptVariableSet, log); } else if (query is DbStoredQuery storedDbQuery) { if (!storedDbQuery.QueryTexts.TryGetValue(Id, out queryString)) { queryString = BuildQuery(storedDbQuery.Query, DbQueryParameterMode.Scripted, parameterSet, scriptVariableSet, log); storedDbQuery.QueryTexts.Add(Id, queryString); } } if (query.SubQueries != null) { for (int i = 0; i < query.SubQueries.Count; i++) { var subQuery = query.SubQueries[i]; var subQueryString = BuildQuery(subQuery, parameterMode, parameterSet, scriptVariableSet, log); queryString = queryString.Replace((i + 1).ToString().AsQueryWildString(), subQueryString); } } if (parameterMode != DbQueryParameterMode.Scripted) { parameterSet ??= new DataElementSet(); UpdateParameterSet(parameterSet, query); if (query is DbStoredQuery storedDbQuery) { UpdateParameterSet(parameterSet, storedDbQuery.Query); } if (parameterSet?.Items != null) { foreach (var parameter in parameterSet.Items) { if (parameterMode == DbQueryParameterMode.ValueInjected) { queryString = queryString.Replace((parameter?.Name ?? parameter.Index.ToString())?.AsParameterWildString(), GetSqlText_Value(parameter?.GetValue(Scope, scriptVariableSet, log), parameter.ValueType)); } else { queryString = queryString.Replace((parameter?.Name ?? parameter.Index.ToString())?.AsParameterWildString(), "@" + parameter?.Name ?? parameter.Index.ToString()); } } } } } catch (Exception ex) { log?.AddError( "Error trying to build query '" + (query?.Name ?? "(Undefinied)") + "'", description: ex.ToString() + ". Built query is : '" + queryString + "'."); } } return(queryString); }
/// <summary> /// Loads the specified library. /// </summary> /// <param name="libraryReference">The library reference to consider.</param> /// <returns>Returns the loaded library.</returns> private IBdoLog LoadLibrary(IBdoAssemblyReference libraryReference) { var log = new BdoLog(); if (libraryReference != null && _loadOptions?.SourceKinds != null) { try { Assembly assembly = null; // first we load the assembly IBdoLog firstLog = new BdoLog() { DisplayName = "Loading library '" + libraryReference.Name + "'" }; foreach (DatasourceKind dataSourceKind in _loadOptions?.SourceKinds) { IBdoLog subLog = firstLog.AddSubLog(title: "Loading assembly from '" + dataSourceKind.ToString() + "'", eventKind: EventKinds.Message); switch (dataSourceKind) { case DatasourceKind.Memory: if (!string.IsNullOrEmpty(libraryReference.Name)) { assembly = AppDomainPool.LoadAssembly(_appDomain, libraryReference.Name, subLog); } else { subLog?.AddWarning("File name missing"); } break; case DatasourceKind.Repository: string fileName = libraryReference.FileName; if (string.IsNullOrEmpty(fileName)) { fileName = libraryReference.Name + ".dll"; } string filePath = _loadOptions.LibraryFolderPath.EndingWith(@"\").ToPath() + fileName; if (!File.Exists(filePath)) { subLog?.AddError("Could not find the assembly file path '" + filePath + "'"); } else { assembly = AppDomainPool.LoadAssemblyFromFile(_appDomain, filePath, subLog); if (assembly == null) { subLog?.AddError("Could not load assembly '" + filePath + "'"); } else { subLog?.AddCheckpoint("Loading assembly from file '" + filePath + "'"); assembly = Assembly.LoadFrom(filePath); } } break; case DatasourceKind.RestApi: break; } if (assembly != null) { subLog?.AddMessage("Assembly loaded"); break; } } // if we have an assembly then we index library items if (assembly == null) { log?.AddSubLog(firstLog, p => p.HasErrorsOrExceptionsOrWarnings()); } else { firstLog.GetEvents(true, EventKinds.Error, EventKinds.Exception).ForEach(p => p.Kind = EventKinds.Warning); log?.AddSubLog(firstLog); // we get the extension definition IBdoExtensionDefinition extensionDefinition = ExtractExtensionDefinition(assembly, null, log); // we load the using assemblies if (extensionDefinition?.Dto?.UsingAssemblyFileNames != null) { foreach (var st in extensionDefinition.Dto.UsingAssemblyFileNames) { var fileName = st; if (!fileName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { fileName += ".dll"; } IBdoAssemblyReference reference = BdoAssemblyReferenceFactory.Create(st).WithFileName(fileName); log.AddSubLog(LoadExtensionsInStore(reference), title: "Loading using extensions..."); } } // we load the item definition specifiying the extension definition foreach (BdoExtensionItemKind kind in new[] { BdoExtensionItemKind.Carrier, BdoExtensionItemKind.Connector, BdoExtensionItemKind.Entity, BdoExtensionItemKind.Handler, BdoExtensionItemKind.Metrics, BdoExtensionItemKind.Routine, BdoExtensionItemKind.Scriptword, BdoExtensionItemKind.Task }) { IBdoLog subSubLog = new BdoLog(); int count = LoadDictionary(assembly, kind, extensionDefinition, subSubLog); if (subSubLog.HasErrorsOrExceptionsOrWarnings()) { log.AddSubLog( subSubLog, title: "Dictionary '" + kind.ToString() + "' loaded (" + count.ToString() + " items added)"); } else { log.AddMessage("Dictionary '" + kind.ToString() + "' loaded (" + count.ToString() + " items added)"); } } } } catch (Exception exception) { log?.AddException(exception); } } return(log); }
/// <summary> /// Loads the script word dictionary from the specified assembly. /// </summary> /// <param name="assembly">The assembly to consider.</param> /// <param name="extensionDefinition">The extension definition to consider.</param> /// <param name="log">The log to consider.</param> /// <returns></returns> private int LoadScripwordDictionaryFromAssembly( Assembly assembly, IBdoExtensionDefinition extensionDefinition, IBdoLog log = null) { if (assembly == null) { return(-1); } // we load the carrier dictionary from the assembly IBdoScriptwordDictionaryDto dictionaryDto = (IBdoScriptwordDictionaryDto)ExtractDictionaryFromAssembly <BdoScriptwordDefinitionDto>(assembly, log); // we define definitions int count = 0; if (dictionaryDto == null) { log?.AddWarning(title: "No script word dictionary was found"); } else { List <BdoScriptwordDefinition> scriptwordDefinitions = new List <BdoScriptwordDefinition>(); var types = assembly.GetTypes().Where(p => p.GetCustomAttributes(typeof(BdoScriptwordDefinitionAttribute)).Any()); foreach (Type type in types) { // we feach methods var methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.Static); foreach (MethodInfo methodInfo in methodInfos) { if (methodInfo.GetCustomAttribute(typeof(BdoScriptwordAttribute)) is BdoScriptwordAttribute scriptWordAttribute) { // we determine the name of the definition string definitionName = scriptWordAttribute.Name; // we update the definition with the dictionary if there is one if (dictionaryDto != null) { IBdoScriptwordDefinitionDto definitionDto = dictionaryDto.GetDefinition(definitionName, methodInfo.Name); if (definitionDto == null) { log?.AddError(title: "Script word '" + methodInfo.Name + "' not found in dictionary"); } else { definitionDto.CallingClass = type.FullName; definitionDto.LibraryId = extensionDefinition?.Dto?.Id; // we create the runtime definition BdoScriptwordDefinition itemDefinition = new BdoScriptwordDefinition(extensionDefinition, definitionDto); try { if (methodInfo.GetParameters().Length == 0) { itemDefinition.RuntimeBasicFunction += methodInfo.CreateDelegate( typeof(BdoScriptwordBasicDelegare)) as BdoScriptwordBasicDelegare; } else { itemDefinition.RuntimeScopedFunction += methodInfo.CreateDelegate( typeof(BdoScriptwordScopedDelegate)) as BdoScriptwordScopedDelegate; } scriptwordDefinitions.Add(itemDefinition); count++; } catch (ArgumentException) { log?.AddError( title: "Incompatible function ('" + methodInfo.Name + "')", description: "Function '" + definitionDto.RuntimeFunctionName + "' in class '" + definitionDto.CallingClass + "' has inexpected parameters."); } } } } } } // we build the script word tree BuildScriptwordTree(dictionaryDto, scriptwordDefinitions, log); } return(count); }
/// <summary> /// Converts the specifed search query into an extension script. /// </summary> /// <param name="searchQuery">The search query to consider.</param> /// <param name="log">The </param> /// <param name="definition">The clause statement to consider.</param> /// <param name="i"></param> /// <returns></returns> internal static string ConvertToExtensionScript( this string searchQuery, IBdoLog log = null, DbApiFilterDefinition definition = null, int i = 0) { string script = searchQuery; if (!string.IsNullOrEmpty(script)) { // boolean instructions foreach (string instruction in new string[] { "Or", "And", "Not" }) { int j = i; List <string> clauses = new List <string>(); script.IndexOfNextString(" " + instruction + " ", ref j); while (j < script.Length - 1) { string clause = script.Substring(i, j - i + 1); clause = clause.ConvertToExtensionScript(log, definition, 0); clauses.Add(clause); j = i = j + (" " + instruction + " ").Length; script.IndexOfNextString(" " + instruction + " ", ref j); if (j == script.Length) { clause = script.Substring(i); clause = clause.ConvertToExtensionScript(log, definition, 0); clauses.Add(clause); } } if (clauses.Count > 0) { script = "$sql" + instruction + "(" + clauses.Aggregate((p, q) => p + "," + q) + ")"; } } if (i == 0) { DataOperators aOperator = DataOperators.None; int k = script.Length; string scriptOperator = null; foreach (DataOperators currentOperator in new DataOperators[] { DataOperators.Exists, DataOperators.Contains, DataOperators.Different, DataOperators.Equal, DataOperators.GreaterOrEqual, DataOperators.Greater, DataOperators.LesserOrEqual, DataOperators.Lesser, DataOperators.Has, DataOperators.In }) { int k1 = 0; string currentScriptOperator = DbQueryExtension.GetInstruction(currentOperator); script.IndexOfNextString(currentScriptOperator, ref k1); if (k1 < k) { scriptOperator = currentScriptOperator; aOperator = currentOperator; k = k1; } } if (k == script.Length) { log.AddError("No operator found in clause '" + searchQuery + "'", resultCode: "user"); } else { string scriptFunction = DbQueryExtension.GetScriptFunction(aOperator)?.Trim(); string fieldName = script.Substring(0, k)?.Trim(); string value = script.Substring(k + scriptOperator.Length)?.Trim(); if (value.Length > 2 && value.StartsWith("'") && value.EndsWith("'")) { value = "$sqlText('" + value.Substring(1, value.Length - 2) + "')"; } // check that the field is in the dictionary if (!definition.ContainsKey(fieldName)) { log.AddError("Undefined field '" + fieldName + "' in clause '" + searchQuery + "''", resultCode: "user"); } else { DbApiFilterClause clause = definition?[fieldName]; // check the instruction found corresponds to the definition in dictionary if (!clause.Operators.Any(p => p == aOperator)) { log.AddError("Undefined operator '" + aOperator.ToString() + "' for field '" + fieldName + "'", resultCode: "user"); } else { if (clause.Field == null) { clause.Field = DbFluent.Field(fieldName); } if (aOperator == DataOperators.Has) { if (value.Length > 2 && value.StartsWith("{") && value.EndsWith("}")) { value = value.Substring(1, value.Length - 2); } value = value.ConvertToExtensionScript(log, clause.FilterDefinition, 0); script = "(" + value + ")"; } else { script = scriptFunction + clause.Field; } } } } } } return(script); }