internal string GetColumnInfo(string tableName, string columnName, DataFieldDescriptor fieldDescriptor, bool includeDefault, bool forceNullable)
        {
            string defaultInfo = string.Empty;

            if (TranslatesIntoDefaultConstraint(fieldDescriptor.DefaultValue))
            {
                if (includeDefault)
                {
                    defaultInfo = string.Format("CONSTRAINT [{0}] DEFAULT {1}", SqlSafeName("DF", tableName, columnName), GetDefaultValueText(fieldDescriptor.DefaultValue));
                }
            }

            // Enabling case sensitive comparison for the random string fields

            var defaultValue = fieldDescriptor.DefaultValue;

            string collation = string.Empty;

            if (defaultValue != null && defaultValue.ValueType == DefaultValueType.RandomString)
            {
                collation = "COLLATE Latin1_General_CS_AS";
            }

            return(string.Format(
                       "[{0}] {1} {2} {3} {4}",
                       fieldDescriptor.Name,
                       DynamicTypesCommon.MapStoreTypeToSqlDataType(fieldDescriptor.StoreType),
                       collation,
                       fieldDescriptor.IsNullable || forceNullable ? "NULL" : "NOT NULL",
                       defaultInfo));
        }
Example #2
0
        private static InterfaceConfigurationElement BuildInterfaceConfigurationElement(
            DataTypeDescriptor dataTypeDescriptor,
            InterfaceConfigurationElement existingElement = null,
            bool updateTableNames = false)
        {
            var propertyMappings = new PropertyNameMappingConfigurationElementCollection();
            //foreach (DataFieldDescriptor field in dataTypeDescriptor.Fields)
            //{
            //    propertyMappings.Add(field.Name, field.Name);
            //}

            var keyInfo = new SimpleNameTypeConfigurationElementCollection();

            foreach (DataFieldDescriptor field in dataTypeDescriptor.KeyFields)
            {
                keyInfo.Add(field.Name, field.InstanceType);
            }

            var stores = new StoreConfigurationElementCollection();

            // Fix logic for the case of a localized interface without languages
            foreach (DataScopeIdentifier dataScope in dataTypeDescriptor.DataScopes)
            {
                foreach (var culture in SqlDataProviderStoreManipulator.GetCultures(dataTypeDescriptor))
                {
                    string tableName = null;

                    if (!updateTableNames && existingElement != null)
                    {
                        foreach (StoreConfigurationElement table  in existingElement.ConfigurationStores)
                        {
                            if (table.DataScope == dataScope.Name && table.CultureName == culture.Name)
                            {
                                tableName = table.TableName;
                                break;
                            }
                        }
                    }

                    tableName = tableName ?? DynamicTypesCommon.GenerateTableName(dataTypeDescriptor, dataScope, culture);

                    stores.Add(new StoreConfigurationElement {
                        TableName = tableName, DataScope = dataScope.Name, CultureName = culture.Name
                    });
                }
            }

            return(new InterfaceConfigurationElement
            {
                DataTypeId = dataTypeDescriptor.DataTypeId,
                IsGeneratedType = dataTypeDescriptor.IsCodeGenerated,
                ConfigurationStores = stores,
                ConfigurationPropertyNameMappings = propertyMappings,
                ConfigurationDataIdProperties = keyInfo,
                ConfigurationPropertyInitializers = new SimpleNameTypeConfigurationElementCollection()
            });
        }
        internal void CreateStore(DataTypeDescriptor typeDescriptor, DataScopeIdentifier dataScope, CultureInfo cultureInfo,
                                  Action <string> existingTablesValidator = null)
        {
            string tableName = DynamicTypesCommon.GenerateTableName(typeDescriptor, dataScope, cultureInfo);
            var    tables    = GetTablesList();

            if (tables.Contains(tableName))
            {
                if (existingTablesValidator != null)
                {
                    existingTablesValidator(tableName);
                    return;
                }

                throw new InvalidOperationException("Database already contains a table named {0}".FormatWith(tableName));
            }

            var sql        = new StringBuilder();
            var sqlColumns = typeDescriptor.Fields.Select(fieldDescriptor
                                                          => GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, true, false)
                                                          ).ToList();

            sql.AppendFormat("CREATE TABLE dbo.[{0}]({1});", tableName, string.Join(",", sqlColumns));
            sql.Append(SetPrimaryKey(tableName, typeDescriptor.KeyPropertyNames, typeDescriptor.PrimaryKeyIsClusteredIndex));

            try
            {
                ExecuteNonQuery(sql.ToString());
            }
            catch (Exception ex)
            {
                throw MakeVerboseException(ex);
            }

            foreach (var index in typeDescriptor.Indexes)
            {
                CreateIndex(tableName, index);
            }

            SqlTableInformationStore.ClearCache(_connectionString, tableName);
        }
        private void HandleDisablingOfPublication(DataTypeChangeDescriptor changeDescriptor)
        {
            IEnumerable <CultureInfo> locales = GetCultures(changeDescriptor.OriginalType);

            foreach (CultureInfo locale in locales)
            {
                string oldTableName = GetConfiguredTableName(changeDescriptor.OriginalType, DataScopeIdentifier.Administrated, locale.Name);
                string newTableName = DynamicTypesCommon.GenerateTableName(changeDescriptor.AlteredType, DataScopeIdentifier.Public, locale);

                StringBuilder fieldList = GetCommonFields(changeDescriptor);

                string removeCommandText = string.Format(@"DELETE FROM [{0}];", newTableName);
                ExecuteNonQuery(removeCommandText);

                string copyCommandText = string.Format(@"
                            INSERT INTO [{0}] ({2})
                            SELECT {2}                             
                            FROM [{1}];", newTableName, oldTableName, fieldList);
                ExecuteNonQuery(copyCommandText);
            }
        }
        private void HandleEnablingOfPublication(DataTypeChangeDescriptor changeDescriptor)
        {
            IEnumerable <CultureInfo> locales = GetCultures(changeDescriptor.OriginalType);

            foreach (CultureInfo locale in locales)
            {
                string oldTableName = GetConfiguredTableName(changeDescriptor.OriginalType, DataScopeIdentifier.Public, locale.Name);
                string newTableName = DynamicTypesCommon.GenerateTableName(changeDescriptor.AlteredType, DataScopeIdentifier.Administrated, locale);

                StringBuilder fieldList = GetCommonFields(changeDescriptor);

                string copyCommandText = string.Format(@"
                            INSERT INTO [{0}] ({2})
                            SELECT {2}                             
                            FROM [{1}];", newTableName, oldTableName, fieldList);
                ExecuteNonQuery(copyCommandText);

                string updateOldCommandText = string.Format("UPDATE [{0}] SET [{1}] = '{2}'", oldTableName, "PublicationStatus", GenericPublishProcessController.Published);
                ExecuteNonQuery(updateOldCommandText);

                string updateNewCommandText = string.Format("UPDATE [{0}] SET [{1}] = '{2}'", newTableName, "PublicationStatus", GenericPublishProcessController.Published);
                ExecuteNonQuery(updateNewCommandText);
            }
        }
        private void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataTypeChangeDescriptor changeDescriptor, DataScopeIdentifier dataScope, CultureInfo culture)
        {
            try
            {
                string originalTableName = GetConfiguredTableName(changeDescriptor.OriginalType, dataScope, culture.Name);
                string alteredTableName  = originalTableName;

                // This could be done more nicely! But only give the table a new name if the type has changed its name and not because we changed the naming scheme
                if (updateDataTypeDescriptor.OldDataTypeDescriptor.Name != updateDataTypeDescriptor.NewDataTypeDescriptor.Name ||
                    updateDataTypeDescriptor.OldDataTypeDescriptor.Namespace != updateDataTypeDescriptor.NewDataTypeDescriptor.Namespace)
                {
                    alteredTableName = DynamicTypesCommon.GenerateTableName(changeDescriptor.AlteredType, dataScope, culture);
                }

                var tables = GetTablesList();

                if (!tables.Contains(originalTableName))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Unable to alter data type store. The database does not contain expected table {0}",
                                  originalTableName));
                }


                bool primaryKeyChanged = changeDescriptor.AddedKeyFields.Any() ||
                                         changeDescriptor.DeletedKeyFields.Any() ||
                                         changeDescriptor.KeyFieldsOrderChanged ||
                                         changeDescriptor.OriginalType.PrimaryKeyIsClusteredIndex != changeDescriptor.AlteredType.PrimaryKeyIsClusteredIndex;

                DropConstraints(originalTableName, primaryKeyChanged);

                if (originalTableName != alteredTableName)
                {
                    if (tables.Contains(alteredTableName))
                    {
                        throw new InvalidOperationException(
                                  string.Format("Can not rename table to {0}. A table with that name already exists",
                                                alteredTableName));
                    }
                    RenameTable(originalTableName, alteredTableName);
                }

                var newIndexes = changeDescriptor.AlteredType.Indexes.Select(i => i.ToString()).ToList();
                foreach (var oldIndex in changeDescriptor.OriginalType.Indexes)
                {
                    if (!newIndexes.Contains(oldIndex.ToString()))
                    {
                        DropIndex(alteredTableName, oldIndex);
                    }
                }

                DropFields(alteredTableName, changeDescriptor.DeletedFields, changeDescriptor.OriginalType.Fields);
                ImplementFieldChanges(alteredTableName, changeDescriptor.ExistingFields);


                Dictionary <string, object> defaultValues = null;
                if (updateDataTypeDescriptor.PublicationAdded)
                {
                    defaultValues = new Dictionary <string, object>
                    {
                        { "PublicationStatus", GenericPublishProcessController.Draft }
                    };
                }

                AppendFields(alteredTableName, changeDescriptor.AddedFields, defaultValues);

                // Clustered index has to be created first.
                var createIndexActions = new List <Tuple <bool, Action> >();

                if (primaryKeyChanged)
                {
                    bool isClusteredIndex = changeDescriptor.AlteredType.PrimaryKeyIsClusteredIndex;

                    createIndexActions.Add(new Tuple <bool, Action>(isClusteredIndex,
                                                                    () => ExecuteNonQuery(SetPrimaryKey(alteredTableName, changeDescriptor.AlteredType.KeyPropertyNames, isClusteredIndex))
                                                                    ));
                }

                var oldIndexes = changeDescriptor.OriginalType.Indexes.Select(i => i.ToString()).ToList();
                foreach (var newIndex in changeDescriptor.AlteredType.Indexes)
                {
                    if (!oldIndexes.Contains(newIndex.ToString()))
                    {
                        var index = newIndex;

                        createIndexActions.Add(new Tuple <bool, Action>(newIndex.Clustered,
                                                                        () => CreateIndex(alteredTableName, index)));
                    }
                }

                createIndexActions.Sort((a, b) => b.Item1.CompareTo(a.Item1));

                foreach (var createIndex in createIndexActions)
                {
                    createIndex.Item2();
                }

                SqlTableInformationStore.ClearCache(_connectionString, originalTableName);
                SqlTableInformationStore.ClearCache(_connectionString, alteredTableName);
            }
            catch (Exception ex)
            {
                throw MakeVerboseException(ex);
            }
        }
        private void AlterScopeData(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataTypeChangeDescriptor changeDescriptor, DataScopeIdentifier dataScope)
        {
            var culturesToDelete = new List <CultureInfo>();
            var culturesToChange = new List <CultureInfo>();

            var oldCultures = GetCultures(changeDescriptor.OriginalType).Evaluate();
            var newCultures = GetCultures(changeDescriptor.AlteredType).Evaluate();

            foreach (var culture in oldCultures)
            {
                if (newCultures.Contains(culture))
                {
                    culturesToChange.Add(culture);
                }
                else
                {
                    culturesToDelete.Add(culture);
                }
            }

            var culturesToAdd = newCultures.Where(culture => !oldCultures.Contains(culture)).ToList();


            culturesToAdd.ForEach(culture => CreateStore(changeDescriptor.AlteredType, dataScope, culture));
            culturesToChange.ForEach(culture => AlterStore(updateDataTypeDescriptor, changeDescriptor, dataScope, culture));

            if (updateDataTypeDescriptor.LocalesToCopyTo != null)
            {
                StringBuilder fieldList = GetCommonFields(changeDescriptor);

                string fromTableName = GetConfiguredTableName(changeDescriptor.OriginalType, dataScope, "");

                foreach (CultureInfo locale in updateDataTypeDescriptor.LocalesToCopyTo)
                {
                    string toTableName = DynamicTypesCommon.GenerateTableName(changeDescriptor.AlteredType, dataScope, locale);

                    string copyCommandText = string.Format(@"
                            INSERT INTO [{0}] ({2})
                            SELECT {2}                             
                            FROM [{1}];", toTableName, fromTableName, fieldList);
                    ExecuteNonQuery(copyCommandText);

                    string updateCommandText = string.Format("UPDATE [{0}] SET [{1}] = '{2}'", toTableName, "SourceCultureName", locale.Name);
                    ExecuteNonQuery(updateCommandText);
                }

                string removeCommandText = string.Format(@"DELETE FROM [{0}];", fromTableName);
                ExecuteNonQuery(removeCommandText);
            }

            if (updateDataTypeDescriptor.LocaleToCopyFrom != null)
            {
                StringBuilder fieldList = GetCommonFields(changeDescriptor);

                string fromTableName = GetConfiguredTableName(changeDescriptor.OriginalType, dataScope, updateDataTypeDescriptor.LocaleToCopyFrom.Name);
                string toTableName   = DynamicTypesCommon.GenerateTableName(changeDescriptor.AlteredType, dataScope, CultureInfo.InvariantCulture);

                string copyCommandText = string.Format(@"
                            INSERT INTO [{0}] ({2})
                            SELECT {2}                             
                            FROM [{1}];", toTableName, fromTableName, fieldList);
                ExecuteNonQuery(copyCommandText);
            }


            culturesToDelete.ForEach(culture => DropStore(changeDescriptor.OriginalType, dataScope, culture));
        }