private InterfaceGeneratedClassesInfo InitializeStoreTypes(InterfaceConfigurationElement element, Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes, Type dataContextClass, bool forceCompile, ref bool dataContextRecompilationNeeded) { HelperClassesGenerationInfo toCompile = null; var result = InitializeStoreTypes(element, allSqlDataTypeStoreDataScopes, dataContextClass, null, forceCompile, ref dataContextRecompilationNeeded, ref toCompile); if (result != null && toCompile != null) { var codeGenerationBuilder = new CodeGenerationBuilder(_dataProviderContext.ProviderName + ":" + result.InterfaceType.FullName); toCompile.GenerateCodeAction(codeGenerationBuilder); var types = CodeGenerationManager.CompileRuntimeTempTypes(codeGenerationBuilder, false).ToArray(); toCompile.PopulateFieldsAction(types); } return(result); }
private InterfaceGeneratedClassesInfo InitializeStoreTypes(InterfaceConfigurationElement element, Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes, Type dataContextClass, Dictionary <Guid, Type> dataTypes, bool forceCompile, ref bool dataContextRecompilationNeeded, ref HelperClassesGenerationInfo helperClassesGenerationInfo) { var result = new InterfaceGeneratedClassesInfo(); var dataScopes = new List <SqlDataTypeStoreDataScope>(); foreach (StorageInformation storageInformation in element.Stores) { var sqlDataTypeStoreDataScope = new SqlDataTypeStoreDataScope { DataScopeName = storageInformation.DataScope, CultureName = storageInformation.CultureName, TableName = storageInformation.TableName }; dataScopes.Add(sqlDataTypeStoreDataScope); } result.DataScopes = dataScopes; Guid dataTypeId = element.DataTypeId; var dataTypeDescriptor = DataMetaDataFacade.GetDataTypeDescriptor(dataTypeId, true); if (dataTypeDescriptor == null) { throw NewConfigurationException(element, "Failed to get a DataTypeDescriptor by id '{0}'".FormatWith(dataTypeId)); } result.DataTypeDescriptor = dataTypeDescriptor; Type interfaceType = null; try { if (dataTypes == null || !dataTypes.TryGetValue(dataTypeId, out interfaceType) || interfaceType == null) { interfaceType = DataTypeTypesManager.GetDataType(dataTypeDescriptor); } if (interfaceType == null) { Log.LogWarning(LogTitle, "The data interface type '{0}' does not exists and is not code generated. It will not be unusable", dataTypeDescriptor.TypeManagerTypeName); return(result); } result.InterfaceType = interfaceType; string validationMessage; bool isValid = DataTypeValidationRegistry.Validate(interfaceType, dataTypeDescriptor, out validationMessage); if (!isValid) { Log.LogCritical(LogTitle, validationMessage); throw new InvalidOperationException(validationMessage); } Dictionary <SqlDataTypeStoreTableKey, StoreTypeInfo> fields; helperClassesGenerationInfo = EnsureNeededTypes(dataTypeDescriptor, dataScopes, allSqlDataTypeStoreDataScopes, dataContextClass, out fields, ref dataContextRecompilationNeeded, forceCompile); result.Fields = fields; return(result); } catch (Exception ex) { if (interfaceType != null) { DataProviderRegistry.RegisterDataTypeInitializationError(interfaceType, ex); DataProviderRegistry.AddKnownDataType(interfaceType, _dataProviderContext.ProviderName); Log.LogError(LogTitle, "Failed initialization for the datatype {0}", dataTypeDescriptor.TypeManagerTypeName); } Log.LogError(LogTitle, ex); result.Fields = new Dictionary <SqlDataTypeStoreTableKey, StoreTypeInfo>(); return(result); } }
private void InitializeExistingStores() { _compositeGeneratedAssembly = _compositeGeneratedAssembly ?? AssemblyFacade.GetGeneratedAssemblyFromBin(); _sqlDataTypeStoresContainer = new SqlDataTypeStoresContainer(_dataProviderContext.ProviderName, _connectionString, _sqlLoggingContext); Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes = BuildAllExistingDataTypeStoreDataScopes(); var initializedStores = new List <InterfaceGeneratedClassesInfo>(); bool dataContextRecompilationNeeded = false; Type dataContextClass = TryLoadDataContext(ref dataContextRecompilationNeeded); var dataTypes = LoadDataTypes(_interfaceConfigurationElements); var compilationData = new List <HelperClassesGenerationInfo>(); foreach (InterfaceConfigurationElement element in _interfaceConfigurationElements) { HelperClassesGenerationInfo toCompile = null; var generatedClassesInfo = InitializeStoreTypes(element, allSqlDataTypeStoreDataScopes, dataContextClass, dataTypes, false, ref dataContextRecompilationNeeded, ref toCompile); if (generatedClassesInfo == null) { continue; } if (toCompile != null) { compilationData.Add(toCompile); } initializedStores.Add(generatedClassesInfo); } if (compilationData.Any()) { var codeGenerationBuilder = new CodeGenerationBuilder(_dataProviderContext.ProviderName + " : compiling missing classes"); foreach (var toCompile in compilationData) { toCompile.GenerateCodeAction(codeGenerationBuilder); } // Precompiling DataWrapper classes as well to improve loading time foreach (var interfaceType in dataTypes.Values) { if (DataWrapperTypeManager.TryGetWrapperType(interfaceType.FullName) == null) { DataWrapperCodeGenerator.AddDataWrapperClassCode(codeGenerationBuilder, interfaceType); } } var types = CodeGenerationManager.CompileRuntimeTempTypes(codeGenerationBuilder, false).ToArray(); foreach (var toCompile in compilationData) { toCompile.PopulateFieldsAction(types); } } if (dataContextRecompilationNeeded) { dataContextClass = DataContextAssembler.EmitDataContextClass( initializedStores .Where(s => s.Fields != null) .SelectMany(s => s.Fields.Values).Evaluate()); } _sqlDataTypeStoresContainer.DataContextClass = dataContextClass; foreach (var typeInfo in initializedStores) { var store = EmbedDataContextInfo(typeInfo, dataContextClass); AddDataTypeStore(store, true, true); } }
public void CreateStores(IReadOnlyCollection <DataTypeDescriptor> dataTypeDescriptors) { var types = DataTypeTypesManager.GetDataTypes(dataTypeDescriptors); foreach (var dataTypeDescriptor in dataTypeDescriptors) { if (InterfaceConfigurationManipulator.ConfigurationExists(_dataProviderContext.ProviderName, dataTypeDescriptor)) { var filePath = InterfaceConfigurationManipulator.GetConfigurationFilePath(_dataProviderContext.ProviderName); throw new InvalidOperationException( $"SqlDataProvider configuration already contains a interface named '{dataTypeDescriptor.TypeManagerTypeName}', Id: '{dataTypeDescriptor.DataTypeId}'. Remove it from the configuration file '{filePath}' and restart the application."); } } // Creating Sql tables and adding to the configuration var configElements = new Dictionary <DataTypeDescriptor, InterfaceConfigurationElement>(); foreach (var dataTypeDescriptor in dataTypeDescriptors) { Type type = types[dataTypeDescriptor.DataTypeId]; Action <string> existingTablesValidator = tableName => { var errors = new StringBuilder(); var interfaceType = type; if (!ValidateTable(interfaceType, tableName, errors)) { throw new InvalidOperationException("Table '{0}' already exist but isn't valid: {1}".FormatWith(tableName, errors.ToString())); } }; SqlStoreManipulator.CreateStoresForType(dataTypeDescriptor, existingTablesValidator); InterfaceConfigurationElement element = InterfaceConfigurationManipulator.AddNew(_dataProviderContext.ProviderName, dataTypeDescriptor); _interfaceConfigurationElements.Add(element); configElements.Add(dataTypeDescriptor, element); } // Generating necessary classes and performing validation Dictionary <DataTypeDescriptor, IEnumerable <SqlDataTypeStoreDataScope> > allSqlDataTypeStoreDataScopes = BuildAllExistingDataTypeStoreDataScopes(); bool dataContextRecompilationNeeded = false; var toCompileList = new List <HelperClassesGenerationInfo>(); var generatedClassesInfo = new Dictionary <DataTypeDescriptor, InterfaceGeneratedClassesInfo>(); Type dataContextClass = _sqlDataTypeStoresContainer.DataContextClass; foreach (var dataTypeDescriptor in dataTypeDescriptors) { var element = configElements[dataTypeDescriptor]; // InitializeStoreResult initializeStoreResult = InitializeStore(element, allSqlDataTypeStoreDataScopes); HelperClassesGenerationInfo toCompile = null; var classesInfo = InitializeStoreTypes(element, allSqlDataTypeStoreDataScopes, dataContextClass, null, false, ref dataContextRecompilationNeeded, ref toCompile); if (classesInfo != null && toCompile != null) { toCompileList.Add(toCompile); generatedClassesInfo[dataTypeDescriptor] = classesInfo; } } // Compiling missing classes if (toCompileList.Any()) { var codeGenerationBuilder = new CodeGenerationBuilder(_dataProviderContext.ProviderName + ":CreateStores"); foreach (var toCompile in toCompileList) { toCompile.GenerateCodeAction(codeGenerationBuilder); } var generatedHelperClasses = CodeGenerationManager.CompileRuntimeTempTypes(codeGenerationBuilder, false).ToArray(); foreach (var toCompile in toCompileList) { toCompile.PopulateFieldsAction(generatedHelperClasses); } } // Emitting a new DataContext class if (dataContextRecompilationNeeded) { var newDataTypeIds = new HashSet <Guid>(dataTypeDescriptors.Select(d => d.DataTypeId)); _createdSqlDataTypeStoreTables.RemoveAll(f => newDataTypeIds.Contains(f.DataTypeId)); var fields = _createdSqlDataTypeStoreTables.Select(s => new Tuple <string, Type>(s.DataContextFieldName, s.DataContextFieldType)).ToList(); foreach (var classesInfo in generatedClassesInfo.Values) { fields.AddRange(classesInfo.Fields.Select(f => new Tuple <string, Type>(f.Value.FieldName, f.Value.FieldType))); } dataContextClass = DataContextAssembler.EmitDataContextClass(fields); UpdateCreatedSqlDataTypeStoreTables(dataContextClass); } _sqlDataTypeStoresContainer.DataContextClass = dataContextClass; // Registering the new type/tables foreach (var dataTypeDescriptor in dataTypeDescriptors) { InterfaceGeneratedClassesInfo classesInfo; if (!generatedClassesInfo.TryGetValue(dataTypeDescriptor, out classesInfo)) { throw new InvalidOperationException("No generated classes for data type '{0}' found".FormatWith(dataTypeDescriptor.Name)); } InitializeStoreResult initInfo = EmbedDataContextInfo(classesInfo, dataContextClass); AddDataTypeStore(initInfo, false); } }
private InterfaceGeneratedClassesInfo InitializeStoreTypes(InterfaceConfigurationElement element, Dictionary<DataTypeDescriptor, IEnumerable<SqlDataTypeStoreDataScope>> allSqlDataTypeStoreDataScopes, Type dataContextClass, Dictionary<Guid, Type> dataTypes, bool forceCompile, ref bool dataContextRecompilationNeeded, ref HelperClassesGenerationInfo helperClassesGenerationInfo) { var result = new InterfaceGeneratedClassesInfo(); var dataScopes = new List<SqlDataTypeStoreDataScope>(); foreach (StorageInformation storageInformation in element.Stores) { var sqlDataTypeStoreDataScope = new SqlDataTypeStoreDataScope { DataScopeName = storageInformation.DataScope, CultureName = storageInformation.CultureName, TableName = storageInformation.TableName }; dataScopes.Add(sqlDataTypeStoreDataScope); } result.DataScopes = dataScopes; Guid dataTypeId = element.DataTypeId; var dataTypeDescriptor = DataMetaDataFacade.GetDataTypeDescriptor(dataTypeId, true); if (dataTypeDescriptor == null) { throw NewConfigurationException(element, "Failed to get a DataTypeDescriptor by id '{0}'".FormatWith(dataTypeId)); } result.DataTypeDescriptor = dataTypeDescriptor; Type interfaceType = null; try { interfaceType = dataTypes != null ? dataTypes[dataTypeId] : DataTypeTypesManager.GetDataType(dataTypeDescriptor); if (interfaceType == null) { Log.LogError(LogTitle, "The data interface type '{0}' does not exists and is not code generated. It will not be unusable", dataTypeDescriptor.TypeManagerTypeName); return result; } result.InterfaceType = interfaceType; string validationMessage; bool isValid = DataTypeValidationRegistry.Validate(interfaceType, dataTypeDescriptor, out validationMessage); if (!isValid) { Log.LogCritical(LogTitle, validationMessage); throw new InvalidOperationException(validationMessage); } Dictionary<SqlDataTypeStoreTableKey, StoreTypeInfo> fields; helperClassesGenerationInfo = EnsureNeededTypes(dataTypeDescriptor, dataScopes, allSqlDataTypeStoreDataScopes, dataContextClass, out fields, ref dataContextRecompilationNeeded, forceCompile); result.Fields = fields; return result; } catch (Exception ex) { if (interfaceType != null) { DataProviderRegistry.RegisterDataTypeInitializationError(interfaceType, ex); DataProviderRegistry.AddKnownDataType(interfaceType, _dataProviderContext.ProviderName); Log.LogError(LogTitle, "Failed initialization for the datatype {0}", dataTypeDescriptor.TypeManagerTypeName); } Log.LogError(LogTitle, ex); result.Fields = new Dictionary<SqlDataTypeStoreTableKey, StoreTypeInfo>(); return result; } }