public string[] GenerateSql(IStructureSchema structureSchema, IndexesTableNames names, IndexesTableStatuses statuses)
		{
			if(statuses.AllExists)
				return new string[0];

			var structureTableName = structureSchema.GetStructureTableName();
			var sqlTemplateNameSuffix = GetSqlTemplateNameSuffix(structureSchema.IdAccessor.IdType);
			var generators = new Func<string>[]
			{
				() => !statuses.IntegersTableExists 
					? GenerateSqlFor("CreateIntegersIndexes", sqlTemplateNameSuffix, structureTableName, names.IntegersTableName) 
					: string.Empty,
				() => !statuses.FractalsTableExists 
					? GenerateSqlFor("CreateFractalsIndexes", sqlTemplateNameSuffix, structureTableName, names.FractalsTableName) 
					: string.Empty,
				() => !statuses.BooleansTableExists 
					? GenerateSqlFor("CreateBooleansIndexes", sqlTemplateNameSuffix, structureTableName, names.BooleansTableName) 
					: string.Empty,
				() => !statuses.DatesTableExists 
					? GenerateSqlFor("CreateDatesIndexes", sqlTemplateNameSuffix, structureTableName, names.DatesTableName) 
					: string.Empty,
				() => !statuses.GuidsTableExists 
					? GenerateSqlFor("CreateGuidsIndexes", sqlTemplateNameSuffix, structureTableName, names.GuidsTableName) 
					: string.Empty,
				() => !statuses.StringsTableExists 
					? GenerateSqlFor("CreateStringsIndexes", sqlTemplateNameSuffix, structureTableName, names.StringsTableName) 
					: string.Empty,
				() => !statuses.TextsTableExists 
					? GenerateSqlFor("CreateTextsIndexes", sqlTemplateNameSuffix, structureTableName, names.TextsTableName) 
					: string.Empty
			};

			return generators.Select(generator => generator()).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
		}
        protected override void OnAfterRenameOfStructureSet(string newStructureTableName, string newUniquesTableName, IndexesTableNames newIndexesTableNames)
        {
            var addFkContraintSqlFormat = SqlStatements.GetSql("AddFkContraintAgainstStructureId");

            ExecuteNonQuery(addFkContraintSqlFormat.Inject(newUniquesTableName, newStructureTableName));

            foreach (var newIndexTableName in newIndexesTableNames.All)
                ExecuteNonQuery(addFkContraintSqlFormat.Inject(newIndexTableName, newStructureTableName));
        }
        protected override void OnBeforeRenameOfStructureSet(string oldStructureTableName, string oldUniquesTableName, IndexesTableNames oldIndexesTableNames)
        {
            var dropFkContraintSqlFormat = SqlStatements.GetSql("DropFkContraint");

            ExecuteNonQuery(dropFkContraintSqlFormat.Inject(oldUniquesTableName, oldStructureTableName));
            
            foreach (var oldIndexTableName in oldIndexesTableNames.All)
                ExecuteNonQuery(dropFkContraintSqlFormat.Inject(oldIndexTableName, oldStructureTableName));
        }
        private void OnInitialize(string structureName)
        {
            StructureTableName = DbSchemas.GenerateStructureTableName(structureName);
            UniquesTableName = DbSchemas.GenerateUniquesTableName(structureName);
            IndexesTableNames = new IndexesTableNames(structureName);

            AllTableNames = new[]
	        {
	            StructureTableName,
                UniquesTableName
	        }
            .MergeWith(IndexesTableNames.All)
            .ToArray();
        }
        private void OnInitialize(string structureName)
        {
            StructureTableName = DbSchemaInfo.GenerateStructureTableName(structureName);
            SpatialTableName   = DbSchemaInfo.GenerateSpatialTableName(structureName);
            UniquesTableName   = DbSchemaInfo.GenerateUniquesTableName(structureName);
            IndexesTableNames  = new IndexesTableNames(structureName);

            AllTableNames = new[]
            {
                StructureTableName,
                SpatialTableName,
                UniquesTableName
            }
            .MergeWith(IndexesTableNames.All)
            .ToArray();
        }
        public string[] GenerateSql(IStructureSchema structureSchema, IndexesTableNames names, IndexesTableStatuses statuses)
        {
            if (statuses.AllExists)
            {
                return(new string[0]);
            }

            var structureTableName    = structureSchema.GetStructureTableName();
            var sqlTemplateNameSuffix = GetSqlTemplateNameSuffix(structureSchema.IdAccessor.IdType);
            var generators            = new Func <string>[]
            {
                () => !statuses.IntegersTableExists
                                        ? GenerateSqlFor("CreateIntegersIndexes", sqlTemplateNameSuffix, structureTableName, names.IntegersTableName)
                                        : string.Empty,
                () => !statuses.FractalsTableExists
                                        ? GenerateSqlFor("CreateFractalsIndexes", sqlTemplateNameSuffix, structureTableName, names.FractalsTableName)
                                        : string.Empty,
                () => !statuses.BooleansTableExists
                                        ? GenerateSqlFor("CreateBooleansIndexes", sqlTemplateNameSuffix, structureTableName, names.BooleansTableName)
                                        : string.Empty,
                () => !statuses.DatesTableExists
                                        ? GenerateSqlFor("CreateDatesIndexes", sqlTemplateNameSuffix, structureTableName, names.DatesTableName)
                                        : string.Empty,
                () => !statuses.GuidsTableExists
                                        ? GenerateSqlFor("CreateGuidsIndexes", sqlTemplateNameSuffix, structureTableName, names.GuidsTableName)
                                        : string.Empty,
                () => !statuses.StringsTableExists
                                        ? GenerateSqlFor("CreateStringsIndexes", sqlTemplateNameSuffix, structureTableName, names.StringsTableName)
                                        : string.Empty,
                () => !statuses.TextsTableExists
                                        ? GenerateSqlFor("CreateTextsIndexes", sqlTemplateNameSuffix, structureTableName, names.TextsTableName)
                                        : string.Empty
            };

            return(generators.Select(generator => generator()).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray());
        }
        protected override void OnRenameIndexesTables(IndexesTableNames oldIndexesTableNames, IndexesTableNames newIndexesTableNames, string oldStructureTableName, string newStructureTableName)
        {
            using (var cmd = CreateCommand(null))
            {
                for (var i = 0; i < oldIndexesTableNames.All.Length; i++)
                {
                    var oldTableName = oldIndexesTableNames[i];
                    var newTableName = newIndexesTableNames[i];

                    cmd.Parameters.Clear();
                    Driver.AddCommandParametersTo(cmd,
                        new DacParameter("objname", oldTableName),
                        new DacParameter("newname", newTableName),
                        new DacParameter("objtype", "OBJECT"));
                    cmd.CommandText = "sp_rename @objname=@objname, @newname=@newname, @objtype=@objtype";
                    cmd.ExecuteNonQuery();
                }
            }
        }
        private void DropIndexesTables(IDbCommand cmd, IndexesTableStatuses statuses, IndexesTableNames names)
        {
            var sqlDropTableFormat = SqlStatements.GetSql("DropTable");

            if (statuses.IntegersTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.IntegersTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.FractalsTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.FractalsTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.BooleansTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.BooleansTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.DatesTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.DatesTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.GuidsTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.GuidsTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.StringsTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.StringsTableName);
                cmd.ExecuteNonQuery();
            }

            if (statuses.TextsTableExists)
            {
                cmd.CommandText = sqlDropTableFormat.Inject(names.TextsTableName);
                cmd.ExecuteNonQuery();
            }
        }
        protected virtual IndexInsertAction CreateIndexInsertActionGroup(IStructureSchema structureSchema, IndexesTableNames indexesTableNames, DataTypeCode dataTypeCode, IStructureIndex[] indexes)
        {
            var container = new IndexInsertAction { Data = indexes };

            switch (dataTypeCode)
            {
                case DataTypeCode.IntegerNumber:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.IntegersTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.IntegersTableName);
                    break;
                case DataTypeCode.FractalNumber:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.FractalsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.FractalsTableName);
                    break;
                case DataTypeCode.Bool:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.BooleansTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.BooleansTableName);
                    break;
                case DataTypeCode.DateTime:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.DatesTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.DatesTableName);
                    break;
                case DataTypeCode.Guid:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.GuidsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.GuidsTableName);
                    break;
                case DataTypeCode.String:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                    break;
                case DataTypeCode.Enum:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                    break;
                case DataTypeCode.Text:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new TextIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.TextsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.TextsTableName);
                    break;
                default:
                    container.Action = null;
                    break;
            }

            return container;
        }