Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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;
            }
        }