private void VisitIndexInfo(IndexInfo primaryIndex, IndexInfo index)
        {
            TableInfo table          = currentTable;
            var       secondaryIndex = CreateSecondaryIndex(table, index.MappingName, index);

            secondaryIndex.IsUnique = index.IsUnique;
            var isClustered = index.IsClustered && providerInfo.Supports(ProviderFeatures.ClusteredIndexes);

            secondaryIndex.IsClustered = isClustered;
            foreach (KeyValuePair <ColumnInfo, Direction> pair in index.KeyColumns)
            {
                string            columName = GetPrimaryIndexColumnName(primaryIndex, pair.Key, index);
                StorageColumnInfo column    = table.Columns[columName];
                new KeyColumnRef(secondaryIndex, column,
                                 providerInfo.Supports(ProviderFeatures.KeyColumnSortOrder)
            ? pair.Value
            : Direction.Positive);
            }
            // At least SQL Server does not support clustered indexes with included columns.
            // For now this is the only RDBMS that have support for clustered indexes in DO.
            // Let's omit additional checks for ServerFeatures here
            // and simply ignore included columns for clustered indexes.
            if (providerInfo.Supports(ProviderFeatures.IncludedColumns) && !isClustered)
            {
                foreach (var includedColumn in index.IncludedColumns)
                {
                    string            columName = GetPrimaryIndexColumnName(primaryIndex, includedColumn, index);
                    StorageColumnInfo column    = table.Columns[columName];
                    new IncludedColumnRef(secondaryIndex, column);
                }
            }
            secondaryIndex.PopulatePrimaryKeyColumns();
        }
        private void CreateColumn(StorageColumnInfo columnInfo, Table table)
        {
            var type               = columnInfo.Type.NativeType;
            var column             = table.CreateColumn(columnInfo.Name, type);
            var isPrimaryKeyColumn =
                columnInfo.Parent.PrimaryIndex != null &&
                columnInfo.Parent.PrimaryIndex.KeyColumns.Any(keyColumn => keyColumn.Value == columnInfo);

            if (!column.IsNullable && column.Name != typeIdColumnName)
            {
                if (!isPrimaryKeyColumn)
                {
                    column.DefaultValue = GetDefaultValueExpression(columnInfo);
                }
                else if (!string.IsNullOrEmpty(columnInfo.DefaultSqlExpression))
                {
                    column.DefaultValue = SqlDml.Native(columnInfo.DefaultSqlExpression);
                }
            }

            column.IsNullable = columnInfo.Type.IsNullable;

            if (columnInfo.Type.Type == typeof(string) && collationName != null)
            {
                column.Collation = table.Schema.Collations[collationName] ?? new Collation(table.Schema, collationName);
            }
        }
        /// <inheritdoc/>
        protected override IPathNode VisitTableColumn(TableColumn tableColumn)
        {
            var tableInfo  = currentTable;
            var typeInfo   = ExtractType(tableColumn);
            var columnInfo = new StorageColumnInfo(tableInfo, tableColumn.Name, typeInfo);

            return(columnInfo);
        }
Exemple #4
0
        public void ValidateNullableKeyColumns()
        {
            var col = new StorageColumnInfo(table, "c2", new StorageTypeInfo(typeof(string), null, true));

            new KeyColumnRef(index, col, Direction.Positive);

            AssertEx.Throws <AggregateException>(index.Validate);
        }
Exemple #5
0
        public void AddRemoveColumnsTest()
        {
            var column = new StorageColumnInfo(table, "c");

            Assert.AreEqual(1, table.Columns.Count);
            column.Remove();
            Assert.AreEqual(0, table.Columns.Count);
        }
Exemple #6
0
        public void ValidateDoubleColumnRefs()
        {
            var column = new StorageColumnInfo(table, "c");

            new KeyColumnRef(index, column, Direction.Positive);
            new ValueColumnRef(index, column);

            AssertEx.Throws <AggregateException>(index.Validate);
        }
Exemple #7
0
        public void AddRemoveValueColumnRefs()
        {
            var column = new StorageColumnInfo(table, "col1");
            var colRef = new ValueColumnRef(index, column);

            Assert.AreEqual(1, index.ValueColumns.Count);
            colRef.Remove();
            Assert.AreEqual(0, index.ValueColumns.Count);
        }
Exemple #8
0
        public void AddRemoveKeyColumnRefs()
        {
            var column = new StorageColumnInfo(table, "col1");
            var colRef = new KeyColumnRef(index, column, Direction.Positive);

            Assert.AreEqual(1, index.KeyColumns.Count);
            colRef.Remove();
            Assert.AreEqual(0, index.KeyColumns.Count);
            column.Remove();
        }
Exemple #9
0
        public void ValidateRefToColumnFromAnotherIndex()
        {
            var anoterTable = new TableInfo(storage, "t2");
            var key         = new StorageColumnInfo(anoterTable, "key");
            var value       = new StorageColumnInfo(anoterTable, "value");

            new KeyColumnRef(index, key, Direction.Positive);
            new ValueColumnRef(index, value);

            AssertEx.Throws <AggregateException>(index.Validate);
        }
Exemple #10
0
        public void ValidateDoubleKeysAndValuesColumnRefs()
        {
            var key   = new StorageColumnInfo(table, "key");
            var value = new StorageColumnInfo(table, "value");

            new KeyColumnRef(index, key, Direction.Positive);
            new KeyColumnRef(index, key, Direction.Negative);
            new ValueColumnRef(index, value);
            new ValueColumnRef(index, value);

            AssertEx.Throws <AggregateException>(index.Validate);
        }
 public void CreateModel()
 {
     storage       = new StorageModel("storage1");
     table         = new TableInfo(storage, "table");
     primary       = new PrimaryIndexInfo(table, "primary1");
     secondary     = new SecondaryIndexInfo(table, "secondary1");
     primaryKey    = new StorageColumnInfo(table, "key", new StorageTypeInfo(typeof(int), null));
     primaryValue1 = new StorageColumnInfo(table, "value1", new StorageTypeInfo(typeof(int), null));
     primaryValue2 = new StorageColumnInfo(table, "value2", new StorageTypeInfo(typeof(int), null));
     new KeyColumnRef(primary, primaryKey, Direction.Positive);
     new ValueColumnRef(primary, primaryValue1);
     new ValueColumnRef(primary, primaryValue2);
 }
        private SqlExpression GetDefaultValueExpression(StorageColumnInfo columnInfo)
        {
            if (!string.IsNullOrEmpty(columnInfo.DefaultSqlExpression))
            {
                return(SqlDml.Native(columnInfo.DefaultSqlExpression));
            }
            if (columnInfo.DefaultValue != null)
            {
                return(SqlDml.Literal(columnInfo.DefaultValue));
            }
            var type = columnInfo.Type.Type;

            return(type.IsValueType && !type.IsNullable() ? SqlDml.Literal(Activator.CreateInstance(type)) : null);
        }
        public void CreateModel()
        {
            storage = new StorageModel("STORAGE")
            {
                Actions = new ActionSequence()
            };
            table         = new TableInfo(storage, "TABLE");
            primary       = new PrimaryIndexInfo(table, "PK");
            secondary     = new SecondaryIndexInfo(table, "IX");
            primaryKey    = new StorageColumnInfo(table, "ID", new StorageTypeInfo(typeof(int), null));
            primaryValue1 = new StorageColumnInfo(table, "AGE", new StorageTypeInfo(typeof(int), null));
            primaryValue2 = new StorageColumnInfo(table, "NAME", new StorageTypeInfo(typeof(int), null));
            new KeyColumnRef(primary, primaryKey, Direction.Positive);
            new ValueColumnRef(primary, primaryValue1);
            new ValueColumnRef(primary, primaryValue2);
            new KeyColumnRef(secondary, primaryValue1, Direction.Positive);

            storage.Dump();
        }
        private StorageTypeInfo GetStorageTypeInfo(StorageTypeInfo typeInfo, StorageColumnInfo extractedConnectedColumn, ColumnInfo column)
        {
            if (!isUpgradingStage)
            {
                return(typeInfo);
            }
            if (extractedConnectedColumn == null)
            {
                return(typeInfo);
            }
            var extractedTypeInfo = extractedConnectedColumn.Type;

            if (IsOnlyNullableChanged(typeInfo, extractedTypeInfo))
            {
                var underlyingType = Nullable.GetUnderlyingType(typeInfo.Type);
                var type           = underlyingType ?? typeInfo.Type;
                var isNullable     = column.Field.Attributes.HasFlag(FieldAttributes.DeclaredAsNullable);
                return(new StorageTypeInfo(ToNullable(type, isNullable), typeInfo.NativeType, isNullable, typeInfo.Length, typeInfo.Precision, typeInfo.Scale));
            }
            return(typeInfo);
        }
Exemple #15
0
        public void BuildStorageModel()
        {
            storage          = new StorageModel("storage");
            referencingTable = new TableInfo(storage, "referencingTable");
            var pkColumn   = new StorageColumnInfo(referencingTable, "Id", new StorageTypeInfo(typeof(int), null));
            var fkColumn   = new StorageColumnInfo(referencingTable, "foreignId", new StorageTypeInfo(typeof(int?), null));
            var fkColumn2  = new StorageColumnInfo(referencingTable, "invalideForeignId", new StorageTypeInfo(typeof(string), null));
            var primaryKey = new PrimaryIndexInfo(referencingTable, "PK1");

            new KeyColumnRef(primaryKey, pkColumn);
            referencingIndex = new SecondaryIndexInfo(referencingTable, "FK");
            new KeyColumnRef(referencingIndex, fkColumn);
            referencingIndex.PopulatePrimaryKeyColumns();
            invalideReferencingIndex = new SecondaryIndexInfo(referencingTable, "FK2");
            invalideReferencingIndex.PopulatePrimaryKeyColumns();
            new KeyColumnRef(invalideReferencingIndex, fkColumn2);
            primaryKey.PopulateValueColumns();

            referencedTable = new TableInfo(storage, "referencedTable");
            pkColumn        = new StorageColumnInfo(referencedTable, "Id", new StorageTypeInfo(typeof(int), null));
            foreignPrimary  = new PrimaryIndexInfo(referencedTable, "Id");
            new KeyColumnRef(foreignPrimary, pkColumn);
        }
        /// <inheritdoc/>
        protected override IPathNode VisitColumnInfo(ColumnInfo column)
        {
            var nonNullableType = column.ValueType;
            var nullableType    = ToNullable(nonNullableType, column.IsNullable);

            StorageColumnInfo extractedConnectedColumn = null;

            if (isUpgradingStage && ShouldGetExtractedColumnInformation(column))
            {
                extractedConnectedColumn = GetExtractedStorageColumnInfoFor(column);
            }

            var typeInfoPrototype = new StorageTypeInfo(nullableType, null, column.IsNullable, column.Length, column.Precision, column.Scale);
            var nativeTypeInfo    = CreateType(nonNullableType, column.Length, column.Precision, column.Scale);

            // We need the same type as in SQL database here (i.e. the same as native)
            var typeInfo      = new StorageTypeInfo(ToNullable(nativeTypeInfo.Type, column.IsNullable), nativeTypeInfo.NativeType, column.IsNullable, nativeTypeInfo.Length, nativeTypeInfo.Precision, nativeTypeInfo.Scale);
            var finalTypeInfo = GetStorageTypeInfo(typeInfo, extractedConnectedColumn, column);

            var defaultValue         = GetColumnDefaultValue(column, finalTypeInfo);
            var defaultSqlExpression = GetColumnDefaultSqlExpression(column);

            if (column.IsSystem && column.Field.IsTypeId)
            {
                var type = column.Field.ReflectedType;
                if (type.IsEntity && type == type.Hierarchy.Root)
                {
                    defaultValue = typeIdProvider.GetTypeId(type.UnderlyingType);
                }
            }
            return(new StorageColumnInfo(currentTable, column.Name, finalTypeInfo)
            {
                DefaultValue = defaultValue,
                DefaultSqlExpression = defaultSqlExpression
            });
        }
Exemple #17
0
        public void CreateModel()
        {
            storage = new StorageModel("storage")
            {
                Actions = new ActionSequence()
            };
            // Table 1
            table1  = new TableInfo(storage, "table1");
            pi1     = new PrimaryIndexInfo(table1, "pk1");
            column1 = new StorageColumnInfo(table1, "col1", new StorageTypeInfo(typeof(string), null, false));
            column2 = new StorageColumnInfo(table1, "col2", new StorageTypeInfo(typeof(string), null));
            column3 = new StorageColumnInfo(table1, "col3", new StorageTypeInfo(typeof(string), null));
            new KeyColumnRef(pi1, column1, Direction.Positive);
            pi1.PopulateValueColumns();
            si1 = new SecondaryIndexInfo(table1, "ix1");
            new KeyColumnRef(si1, column2, Direction.Positive);
            si1.PopulatePrimaryKeyColumns();

            // Table 2
            table2  = new TableInfo(storage, "table2");
            pi2     = new PrimaryIndexInfo(table2, "pk2");
            column4 = new StorageColumnInfo(table2, "col4", new StorageTypeInfo(typeof(int), null));
            column5 = new StorageColumnInfo(table2, "col5", new StorageTypeInfo(typeof(string), null));
            new KeyColumnRef(pi2, column4, Direction.Negative);
            pi2.PopulateValueColumns();
            si2 = new SecondaryIndexInfo(table2, "ix2");
            new KeyColumnRef(si2, column5, Direction.Positive);
            si2.PopulatePrimaryKeyColumns();

            // Foreign keys
            fk1 = new ForeignKeyInfo(table2, "fk1")
            {
                PrimaryKey = pi1
            };
            fk1.ForeignKeyColumns.Set(si2);
        }
Exemple #18
0
        public void DenyAddColumnTest()
        {
            var column = new StorageColumnInfo(table, "c");

            AssertEx.Throws <ArgumentException>(() => new StorageColumnInfo(table, "c"));
        }