コード例 #1
0
 public override string DropIndex(DatabaseTable databaseTable, DatabaseIndex index)
 {
     return string.Format(CultureInfo.InvariantCulture,
         "DROP INDEX {0}{1};",
         SchemaPrefix(index.SchemaOwner),
         Escape(index.Name));
 }
コード例 #2
0
        public void TriggerWithNoQuotes()
        {
            //arrange
            var osr = new OracleSchemaReader(ConnectionStrings.OracleHr, "System.Data.OracleClient");
            var dt = new DatabaseTable();
            dt
                .AddColumn("ID")
                .AddPrimaryKey()
                .AddColumn("NAME");
            dt.Triggers.Add(new DatabaseTrigger
            {
                //with spaces, line breaks
                TriggerBody = @"BEGIN
    SELECT MY_SEQ.NEXTVAL
    INTO :NEW.ID
    FROM DUAL;
END;"
            });

            //act
            osr.PostProcessing(dt);

            //assert
            Assert.IsTrue(dt.HasAutoNumberColumn);
        }
コード例 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProcedureGenerator"/> class.
 /// </summary>
 /// <param name="table">The table.</param>
 public ProcedureGenerator(DatabaseTable table)
     : base(table)
 {
     SqlWriter = new SqlWriter(table, SqlType.Oracle);
     SqlWriter.InStoredProcedure = true;
     PackageName = "PACK_" + TableName;
 }
コード例 #4
0
 protected TableGeneratorBase(DatabaseTable table)
 {
     Table = table;
     TableName = table.Name;
     IncludeSchema = true;
     IncludeDefaultValues = true;
 }
コード例 #5
0
        public DatabaseTable Load(string tableName, CancellationToken ct)
        {
            if (ct.IsCancellationRequested) return new DatabaseTable();
            ReaderEventArgs.RaiseEvent(ReaderProgress, this, ProgressType.ReadingSchema, SchemaObjectType.Tables, tableName, null, null);

            var schemaOwner = _schemaReader.Owner;
            DatabaseTable table;
            using (var ds = _schemaReader.Table(tableName))
            {
                if (ds == null) return null;
                if (ds.Tables.Count == 0) return null;
                ReaderEventArgs.RaiseEvent(ReaderProgress, this, ProgressType.Processing, SchemaObjectType.Tables, tableName, null, null);

                table = _databaseSchema.FindTableByName(tableName, schemaOwner);
                if (table == null)
                {
                    table = new DatabaseTable();
                    _databaseSchema.Tables.Add(table);
                }
                table.Name = tableName;
                table.SchemaOwner = schemaOwner;
                //columns must be done first as it is updated by the others
                schemaOwner = AddColumns(schemaOwner, tableName, table, ds);
                AddConstraints(ds, table);
                AddOthers(schemaOwner, tableName, table, ds);

                _schemaReader.PostProcessing(table);
            }
            return table;
        }
コード例 #6
0
        public override string AlterColumn(DatabaseTable databaseTable, DatabaseColumn databaseColumn, DatabaseColumn originalColumn)
        {
            var sb = new StringBuilder();
            var defaultName = "DF_" + databaseTable.Name + "_" + databaseColumn.Name;
            if (originalColumn != null)
            {
                if (originalColumn.DefaultValue != null)
                {
                    //have to drop default contraint
                    var df = FindDefaultConstraint(databaseTable, databaseColumn.Name);
                    if (df != null)
                    {
                        defaultName = df.Name;
                        sb.AppendLine("ALTER TABLE " + TableName(databaseTable)
                                      + " DROP CONSTRAINT " + Escape(defaultName) + ";");
                    }
                }
            }
            //we could check if any of the properties are changed here
            sb.AppendLine(base.AlterColumn(databaseTable, databaseColumn, originalColumn));
            if (databaseColumn.DefaultValue != null)
            {
                //add default contraint
                sb.AppendLine("ALTER TABLE " + TableName(databaseTable) +
                    " ADD CONSTRAINT " + Escape(defaultName) +
                    " DEFAULT " + databaseColumn.DefaultValue +
                    " FOR " + Escape(databaseColumn.Name) + ";");
            }

            return sb.ToString();
        }
コード例 #7
0
        public void Execute(DatabaseTable databaseTable, DatabaseTable compareTable)
        {
            var firstTriggers = databaseTable.Triggers;
            var secondTriggers = compareTable.Triggers;
            foreach (var trigger in firstTriggers)
            {
                var indexName = trigger.Name;
                var match = secondTriggers.FirstOrDefault(c => c.Name == indexName);
                if (match == null)
                {
                    CreateResult(ResultType.Delete, databaseTable, indexName, 
                        _writer.DropTrigger(databaseTable, trigger));
                    continue;
                }
                if (trigger.TriggerBody != match.TriggerBody || 
                    trigger.TriggerType != match.TriggerType || 
                    trigger.TriggerEvent != match.TriggerEvent)
                {
                    CreateResult(ResultType.Change, databaseTable, indexName,
                        _writer.DropTrigger(databaseTable, trigger) + Environment.NewLine +
                        _writer.AddTrigger(databaseTable, match));
                }
            }

            foreach (var trigger in secondTriggers)
            {
                var indexName = trigger.Name;
                var firstConstraint = firstTriggers.FirstOrDefault(c => c.Name == indexName);
                if (firstConstraint == null)
                {
                    CreateResult(ResultType.Add, databaseTable, indexName, 
                        _writer.AddTrigger(databaseTable, trigger));
                }
            }
        }
コード例 #8
0
        public void WithBidirectionalDepndencyTopologicalSort()
        {
            //arrange
            var schema = new DatabaseSchema(null, null);

            var orders = new DatabaseTable();
            orders.Name = "countries";
            var productsFk = new DatabaseConstraint();
            productsFk.ConstraintType = ConstraintType.ForeignKey;
            productsFk.RefersToTable = "capitalcities";
            orders.AddConstraint(productsFk);
            schema.Tables.Add(orders);

            var products = new DatabaseTable();
            products.Name = "capitalcities";
            var categoriesFk = new DatabaseConstraint();
            categoriesFk.ConstraintType = ConstraintType.ForeignKey;
            categoriesFk.RefersToTable = "countries";
            products.AddConstraint(categoriesFk);
            schema.Tables.Add(products);

            //a country has one capital city
            //a capital city is in one country
            //But bidirectional foreign keys is terrible database design - you really only need one direction.
            //(you have to save the country with a null capital, then the capital, then update the country again).
            //Topological sorts don't support cycles, so we should just get back the original list

            //act
            var sortedTables = SchemaTablesSorter.TopologicalSort(schema);

            //assert
            Assert.AreEqual(2, sortedTables.Count());
            //non-deterministic order
        }
コード例 #9
0
        /// <summary>
        /// Finds the trigger that uses a sequence for autonumbering. May return NULL.
        /// </summary>
        /// <param name="databaseTable">The database table.</param>
        /// <returns></returns>
        public static OracleSequenceTrigger FindTrigger(DatabaseTable databaseTable)
        {
            var triggers = databaseTable.Triggers;
            if (triggers.Count == 0) return null;
            var pk = databaseTable.PrimaryKeyColumn ?? databaseTable.Columns.Find(x => x.IsAutoNumber);
            if (pk == null) return null;
            //the trigger body will look something like "SELECT MYSEQ.NEXTVAL INTO :NEW.ID FROM DUAL;"
            var pattern = ".NEXTVAL\\s+?INTO\\s+?:NEW.\"?" + pk.Name;
            var regex = new Regex(pattern, RegexOptions.IgnoreCase);

            foreach (var databaseTrigger in databaseTable.Triggers)
            {
                var body = databaseTrigger.TriggerBody;
                var match = regex.Match(body);
                if (!match.Success) continue;
                var result = new OracleSequenceTrigger(databaseTrigger);

                //let's write the sequence if we can find it
                var seqName = ParseSequenceName(body, match.Index);
                if (seqName == null) return result;
                result.SequenceName = seqName;
                if (databaseTable.DatabaseSchema != null)
                {
                    result.DatabaseSequence = databaseTable.DatabaseSchema.Sequences
                        .FirstOrDefault(x => seqName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));
                }
                return result;
            }

            return null;
        }
コード例 #10
0
ファイル: TaskRunner.cs プロジェクト: Petran15/dbschemareader
        public bool RunSprocs(DirectoryInfo directory, SqlType dialect, DatabaseTable table)
        {
            if (table == null)
            {
                Message = "No table";
                return false;
            }

            var gen = new DdlGeneratorFactory(dialect).ProcedureGenerator(table);
            if (gen == null)
            {
                //there is no sproc provider (SQLite)
                Message = @"There is no sproc generator";
                return false;
            }
            var path = Path.Combine(directory.FullName, table.Name + "_sprocs.sql");
            try
            {
                gen.WriteToScript(path);
                Message = @"Wrote " + path;
                return true;
            }
            catch (Exception exception)
            {
                Message =
                    @"An error occurred while creating the script.\n" + exception.Message;
            }
            return false;
        }
コード例 #11
0
        private static IList<DatabaseTable> Convert(DataTable dataTable)
        {
            var list = new List<DatabaseTable>();
            if ((dataTable == null) || (dataTable.Columns.Count == 0) || (dataTable.Rows.Count == 0))
            {
                return list;
            }

            const string schemaKey = "SchemaOwner";
            const string tableKey = "TableName";
            const string descKey = "ColumnDescription";
            const string columnKey = "ColumnName";

            foreach (DataRow row in dataTable.Rows)
            {
                var schema = row[schemaKey].ToString();
                var name = row[tableKey].ToString();
                var col = row[columnKey].ToString();
                var desc = row[descKey].ToString();
                var table = list.FirstOrDefault(t => t.SchemaOwner == schema && t.Name == name);
                if (table == null)
                {
                    table = new DatabaseTable();
                    table.Name = name;
                    table.SchemaOwner = schema;
                    list.Add(table);
                }
                table.AddColumn(col).Description = desc;
            }
            return list;
        }
コード例 #12
0
 public virtual string AddColumn(DatabaseTable databaseTable, DatabaseColumn databaseColumn)
 {
     var tableGenerator = CreateTableGenerator(databaseTable);
     var addColumn = tableGenerator.WriteColumn(databaseColumn).Trim();
     if (string.IsNullOrEmpty(databaseColumn.DefaultValue) && !databaseColumn.Nullable)
     {
         var dt = databaseColumn.DataType;
         if (dt == null || dt.IsString)
         {
             addColumn += " DEFAULT ''"; //empty string
         }
         else if (dt.IsNumeric)
         {
             addColumn += " DEFAULT 0";
         }
         else if (dt.IsDateTime)
         {
             addColumn += " DEFAULT CURRENT_TIMESTAMP";
         }
         //make sure the NOT NULL is AFTER the default
         addColumn = addColumn.Replace(" NOT NULL ", " ") + " NOT NULL";
     }
     return string.Format(CultureInfo.InvariantCulture,
         "ALTER TABLE {0} ADD {1}",
         TableName(databaseTable),
         addColumn) + LineEnding();
 }
コード例 #13
0
        public string Write()
        {

            WriteUsings();

            MappingClassName = _mappingNamer.NameMappingClass(_table.NetName);

            _inheritanceTable = _table.FindInheritanceTable();

            using (_cb.BeginNest("namespace " + _codeWriterSettings.Namespace + ".Mapping"))
            {
                using (_cb.BeginNest("public class " + MappingClassName + " : EntityTypeConfiguration<" + _table.NetName + ">", "Class mapping to " + _table.Name + " table"))
                {
                    using (_cb.BeginNest("public " + MappingClassName + "()", "Constructor"))
                    {
                        MapTableName();

                        AddPrimaryKey();

                        _cb.AppendLine("// Properties");
                        WriteColumns();

                        WriteForeignKeys();

                        WriteNavigationProperties();
                    }
                }
            }

            return _cb.ToString();
        }
コード例 #14
0
 public OverrideWriter(ClassBuilder classBuilder, DatabaseTable table, INamer namer)
 {
     _cb = classBuilder;
     _table = table;
     _namer = namer;
     NetName = table.NetName;
 }
コード例 #15
0
 public override string DropColumn(DatabaseTable databaseTable, DatabaseColumn databaseColumn)
 {
     return string.Format(CultureInfo.InvariantCulture,
         "ALTER TABLE {0} DROP COLUMN {1} CASCADE;",
         TableName(databaseTable),
         Escape(databaseColumn.Name));
 }
コード例 #16
0
        private void AddConstraints(DataSet ds, DatabaseTable table)
        {
            if (ds.Tables.Contains(_schemaReader.PrimaryKeysCollectionName))
            {
                var converter = new SchemaConstraintConverter(ds.Tables[_schemaReader.PrimaryKeysCollectionName],
                    ConstraintType.PrimaryKey);
                var pkConstraints = converter.Constraints();
                PrimaryKeyLogic.AddPrimaryKey(table, pkConstraints);
            }
            if (ds.Tables.Contains(_schemaReader.ForeignKeysCollectionName))
            {
                var converter = new SchemaConstraintConverter(ds.Tables[_schemaReader.ForeignKeysCollectionName],
                    ConstraintType.ForeignKey);
                table.AddConstraints(converter.Constraints());
            }
            if (ds.Tables.Contains(_schemaReader.ForeignKeyColumnsCollectionName))
            {
                var fkConverter = new ForeignKeyColumnConverter(ds.Tables[_schemaReader.ForeignKeyColumnsCollectionName]);
                fkConverter.AddForeignKeyColumns(table.ForeignKeys);
            }

            if (ds.Tables.Contains(_schemaReader.UniqueKeysCollectionName))
            {
                var converter = new SchemaConstraintConverter(ds.Tables[_schemaReader.UniqueKeysCollectionName],
                    ConstraintType.UniqueKey);
                table.AddConstraints(converter.Constraints());
            }
        }
コード例 #17
0
 private void ComparePrimaryKey(DatabaseTable databaseTable, DatabaseTable match)
 {
     if (databaseTable.PrimaryKey == null && match.PrimaryKey == null)
     {
         //no primary key before or after. Oh dear.
         Trace.TraceWarning("-- NB: " + databaseTable.Name + " has no primary key!");
         return;
     }
     if (databaseTable.PrimaryKey == null)
     {
         //forgot to put pk on it
         CreateResult(ResultType.Add, databaseTable, match.PrimaryKey.Name,
             _writer.AddConstraint(databaseTable, match.PrimaryKey));
     }
     else if (match.PrimaryKey == null)
     {
         //why oh why would you want to drop the primary key?
         CreateResult(ResultType.Change, databaseTable, databaseTable.PrimaryKey.Name,
             _writer.DropConstraint(databaseTable, databaseTable.PrimaryKey) + Environment.NewLine +
             "-- NB: " + databaseTable.Name + " has no primary key!");
     }
     else if (!ConstraintColumnsEqual(databaseTable.PrimaryKey, match.PrimaryKey))
     {
         CreateResult(ResultType.Change, databaseTable, databaseTable.PrimaryKey.Name,
             _writer.DropConstraint(databaseTable, databaseTable.PrimaryKey) + Environment.NewLine +
             _writer.AddConstraint(match, match.PrimaryKey));
     }
 }
コード例 #18
0
        private static IList<DatabaseTable> Convert(DataTable dataTable)
        {
            var list = new List<DatabaseTable>();
            if ((dataTable == null) || (dataTable.Columns.Count == 0) || (dataTable.Rows.Count == 0))
            {
                return list;
            }

            const string schemaKey = "SchemaOwner";
            const string tableKey = "TableName";
            const string descKey = "TableDescription";

            foreach (DataRow row in dataTable.Rows)
            {
                var schema = row[schemaKey].ToString();
                var name = row[tableKey].ToString();
                var desc = row[descKey].ToString();
                var table = new DatabaseTable();
                table.Name = name;
                table.SchemaOwner = schema;
                table.Description = desc;
                list.Add(table);
            }
            return list;
        }
コード例 #19
0
        /// <summary>
        /// Converts the "Tables" DataTable into <see cref="DatabaseTable"/> objects.
        /// </summary>
        /// <remarks>
        /// Note the SqlServer DataTable includes views, which we explicitly remove. 
        /// </remarks>
        public static List<DatabaseTable> Tables(DataTable dt)
        {
            List<DatabaseTable> list = new List<DatabaseTable>();

            TableKeyMap keyMap = new TableKeyMap(dt);

            foreach (DataRow row in dt.Rows)
            {
                string type = row[keyMap.TypeKey].ToString();
                //Sql server has base tables and views. Oracle has system and user
                if (IsNotTable(type)) continue;
                DatabaseTable t = new DatabaseTable();
                t.Name = row[keyMap.TableName].ToString();
                //exclude Oracle bin tables
                if (t.Name.StartsWith("BIN$", StringComparison.OrdinalIgnoreCase)) continue;
                if (!string.IsNullOrEmpty(keyMap.OwnerKey))
                {
                    t.SchemaOwner = row[keyMap.OwnerKey].ToString();
                    //Db2 system tables creeping in
                    if (keyMap.IsDb2 && t.SchemaOwner.Equals("SYSTOOLS", StringComparison.OrdinalIgnoreCase)) continue;
                }
                list.Add(t);
            }
            return list;
        }
コード例 #20
0
 public void Execute(DatabaseTable baseTable, DatabaseTable compareTable)
 {
     ComparePrimaryKey(baseTable, compareTable);
     Compare(baseTable, baseTable.UniqueKeys, compareTable.UniqueKeys);
     Compare(baseTable, baseTable.CheckConstraints, compareTable.CheckConstraints);
     Compare(baseTable, baseTable.ForeignKeys, compareTable.ForeignKeys);
 }
コード例 #21
0
 public SqlWriterCommonTest(SqlType sqlType, DatabaseTable table, DbProviderFactory factory, string connectionString)
 {
     _connectionString = connectionString;
     _factory = factory;
     _table = table;
     _sqlType = sqlType;
 }
コード例 #22
0
 public DatabaseInserter CreateDatabaseInserter(DbConnection connection, string insertSql, DatabaseTable databaseTable)
 {
     if (_useSqlServerCe)
     {
         return new SqlServerInserter(connection, insertSql, databaseTable);
     }
     return new DatabaseInserter(connection, insertSql);
 }
コード例 #23
0
 public override string DropIndex(DatabaseTable databaseTable, DatabaseIndex index)
 {
     //no "ON table" syntax
     return string.Format(CultureInfo.InvariantCulture,
         "DROP INDEX {0}.{1}",
         databaseTable.Name,
         Escape(index.Name));
 }
コード例 #24
0
 public ProcedureGenerator(DatabaseTable table)
     : base(table)
 {
     SqlWriter = new SqlWriter(table, SqlType.Db2);
     SqlWriter.InStoredProcedure = true;
     SqlWriter.FormatParameter = x => { return "p_" + x; };
     FormatParameter = SqlWriter.FormatParameter;
 }
コード例 #25
0
 //private CodeInserter _codeInserter;
 /// <summary>
 /// Initializes a new instance of the <see cref="ClassWriter"/> class.
 /// </summary>
 /// <param name="table">The table.</param>
 /// <param name="codeWriterSettings">The code writer settings.</param>
 public ClassWriter(DatabaseTable table, CodeWriterSettings codeWriterSettings)
 {
     _codeWriterSettings = codeWriterSettings;
     _table = table;
     _cb = new ClassBuilder();
     //_codeInserter = codeWriterSettings.CodeInserter;
     //if (_codeInserter == null) _codeInserter = new CodeInserter();
 }
コード例 #26
0
        public override string AddTrigger(DatabaseTable databaseTable, DatabaseTrigger trigger)
        {
            if (string.IsNullOrEmpty(trigger.TriggerBody))
                return "-- add trigger " + trigger.Name;

            //db2 returns the entire "Create trigger" statement, so this is very easy
            return trigger.TriggerBody + ";";
        }
コード例 #27
0
        public TableGenerator(DatabaseTable table)
            : base(table)
        {
            SqlType? originSqlType = null;
            if (table.DatabaseSchema != null)
                originSqlType = ProviderToSqlType.Convert(table.DatabaseSchema.Provider);

            DataTypeWriter = new DataTypeWriter(originSqlType);
        }
コード例 #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProcedureGenerator"/> class.
 /// </summary>
 /// <param name="table">The table.</param>
 public ProcedureGenerator(DatabaseTable table)
     : base(table)
 {
     SqlWriter = new SqlWriter(table, SqlType.SqlServer);
     SqlType? originSqlType = null;
     if (table.DatabaseSchema != null)
         originSqlType = ProviderToSqlType.Convert(table.DatabaseSchema.Provider);
     _dataTypeWriter = new DataTypeWriter(originSqlType);
 }
コード例 #29
0
ファイル: Namer.cs プロジェクト: faddiv/dbschemareader
        /// <summary>
        /// Returns the name of an inverse foreign key property. Uses <see cref="NameCollection"/>
        /// For single fks, it's a collection using the name of the fk table.
        /// For multiple fks, it's a collection using the name of the fk columns
        /// </summary>
        /// <param name="targetTable">The target table.</param>
        /// <param name="table">The table.</param>
        /// <param name="foreignKey">The foreign key.</param>
        /// <returns>
        /// Eg OrderLine has fk to Order. Order will have an ICollection&lt;OrderLine&gt; called "OrderLineCollection".
        /// Multiple fk eg Order has Delivery Address and Billing Address. 
        /// Address will have an ICollection&lt;Order&gt; called "DeliveryAddressCollection", 
        /// and another ICollection&lt;Order&gt; called "BillingAddressCollection"
        /// </returns>
        public virtual string ForeignKeyCollectionName(string targetTable, DatabaseTable table, DatabaseConstraint foreignKey)
        {
            var fksToTarget = table.ForeignKeys.Where(x => x.RefersToTable == targetTable).ToList();
            string name = table.NetName;
            if (fksToTarget.Count > 1)
                name = string.Join("", foreignKey.Columns.Select(x => table.FindColumn(x).NetName).ToArray());

            return NameCollection(name);
        }
コード例 #30
0
ファイル: Firebird.cs プロジェクト: Petran15/dbschemareader
 private static void AssertEmployeeTableValid(DatabaseTable employees)
 {
     Assert.AreEqual(11, employees.Columns.Count, "The employee table contains 11 columns.");
     Assert.AreEqual(2, employees.ForeignKeys.Count, "The employee table contains 2 foreign keys.");
     var integ28 = employees.ForeignKeys.First(f => f.Name == "INTEG_28");
     Assert.AreEqual(1, integ28.Columns.Count, "The INTEG_28 fk on employee table references with 1 key.");
     var integ29 = employees.ForeignKeys.First(f => f.Name == "INTEG_29");
     Assert.AreEqual(3, integ29.Columns.Count, "The INTEG_28 fk on employee table references with 3 key.");
 }