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); }
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); }
public void AddRemoveColumnsTest() { var column = new StorageColumnInfo(table, "c"); Assert.AreEqual(1, table.Columns.Count); column.Remove(); Assert.AreEqual(0, table.Columns.Count); }
public void ValidateDoubleColumnRefs() { var column = new StorageColumnInfo(table, "c"); new KeyColumnRef(index, column, Direction.Positive); new ValueColumnRef(index, column); AssertEx.Throws <AggregateException>(index.Validate); }
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); }
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(); }
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); }
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); }
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 }); }
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); }
public void DenyAddColumnTest() { var column = new StorageColumnInfo(table, "c"); AssertEx.Throws <ArgumentException>(() => new StorageColumnInfo(table, "c")); }