예제 #1
0
        /// <summary>
        /// Merge the user configuration with the default metadatas from the servers.
        /// </summary>
        /// <param name="metadatas">Metadatas to generate queries for.</param>
        /// <param name="behavior">A behavior for cloning data</param>
        /// <param name="variables">The compiled cascade variables</param>
        private static void MergeForeignKey(this Metadatas metadatas, Behavior behavior, HashSet <SchemaVar> variables)
        {
            if (behavior == null)
            {
                return;
            }

            foreach (var dbSettings in behavior.DbSettings)
            {
                var dbSettingsVar = variables.First(v => v.Id == dbSettings.ForSchemaId);

                if (!metadatas.ContainsKey(dbSettingsVar.Server))
                {
                    continue;
                }
                var server = metadatas[dbSettingsVar.Server];
                if (!server.ContainsKey(dbSettingsVar.Database))
                {
                    continue;
                }
                var database = server[dbSettingsVar.Database];
                if (!database.ContainsKey(dbSettingsVar.Schema))
                {
                    continue;
                }
                var schema = database[dbSettingsVar.Schema];
                MergeFkModifierSchema(schema, dbSettings, variables);
            }
        }
예제 #2
0
        public static Metadatas Deserialize(BinaryReader stream, FastAccessList <object> referenceTracking = null)
        {
            var cTables = new Metadatas();

            var nbServers = stream.ReadInt32();

            for (var n = 0; n < nbServers; n++)
            {
                var serverId = stream.ReadString();
                cTables.Add(serverId, new ServerMetadata());

                var nbDatabases = stream.ReadInt32();
                for (var j = 0; j < nbDatabases; j++)
                {
                    var database = stream.ReadString();
                    cTables[serverId].Add(database, new DatabaseMetadata());

                    var nbSchemas = stream.ReadInt32();
                    for (var k = 0; k < nbSchemas; k++)
                    {
                        var schemaMetadata = new SchemaMetadata();
                        var schema         = stream.ReadString();

                        var nbTablesFrom = stream.ReadInt32();
                        for (var l = 0; l < nbTablesFrom; l++)
                        {
                            TableMetadata table;

                            if (referenceTracking == null)
                            {
                                table = TableMetadata.Deserialize(stream);
                            }
                            else
                            {
                                var id = stream.ReadInt32();
                                table = (TableMetadata)referenceTracking[id];
                            }
                            schemaMetadata.Add(table);
                        }

                        cTables[serverId][database].Add(schema, schemaMetadata);
                    }
                }
            }
            return(cTables);
        }
예제 #3
0
 /// <summary>
 /// Generate derivative tables for the metadatas.
 /// </summary>
 private static void GenerateDerivativeTables(this Metadatas metadatas)
 {
     foreach (var server in metadatas)
     {
         foreach (var database in server.Value)
         {
             foreach (var schema in database.Value)
             {
                 foreach (var table in schema.Value)
                 {
                     //On trouve les dérivées de la table
                     foreach (var databaseDeriv in server.Value)
                     {
                         foreach (var schemaDeriv in databaseDeriv.Value)
                         {
                             foreach (var tableDeriv in schemaDeriv.Value)
                             {
                                 foreach (var fk in tableDeriv.ForeignKeys)
                                 {
                                     //Si correspondance
                                     if (fk.ServerIdTo == server.Key && fk.DatabaseTo == database.Key &&
                                         fk.SchemaTo == schema.Key && fk.TableTo == table.Name)
                                     {
                                         //Si non présente
                                         if (!table.DerivativeTables.Any(t => t.ServerId == fk.ServerIdTo && t.Schema == fk.SchemaTo &&
                                                                         t.Database == fk.DatabaseTo && t.Table == fk.TableTo))
                                         {
                                             table.DerivativeTables.Add(new DerivativeTable
                                             {
                                                 ServerId = server.Key,
                                                 Database = databaseDeriv.Key,
                                                 Schema   = schemaDeriv.Key,
                                                 Table    = tableDeriv.Name
                                             });
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
예제 #4
0
        /// <summary>
        /// Get the metadatas from the databases.
        /// </summary>
        /// <param name="queryProxy">The proxy used to fetch data</param>
        /// <returns>The default metadatas from the databases.</returns>
        private static Metadatas FetchMetadata(List <Connection> connections)
        {
            var metadatas = new Metadatas();

            foreach (var connection in connections)
            {
                var dbConnection = DbProviderFactories.GetFactory(connection.ProviderName).CreateConnection();
                dbConnection.ConnectionString = connection.ConnectionString;

                var provider = MetadataProviderFactory.GetProvider(connection.ProviderName);

                foreach (var database in provider.GetDatabasesName(dbConnection))
                {
                    provider.LoadColumns(dbConnection, metadatas, connection.Id, database);
                    provider.LoadForeignKeys(dbConnection, metadatas, connection.Id, database);
                    provider.LoadUniqueKeys(dbConnection, metadatas, connection.Id, database);
                }
            }
            return(metadatas);
        }
예제 #5
0
        /// <summary>
        /// Generate INSERT and SELECT queries for the tables.
        /// </summary>
        /// <param name="metadatas">Metadatas to generate queries for.</param>
        private static void GenerateCommands(this Metadatas metadatas)
        {
            foreach (var server in metadatas)
            {
                foreach (var database in server.Value)
                {
                    foreach (var schema in database.Value)
                    {
                        foreach (var table in schema.Value)
                        {
                            var sbInsert = new StringBuilder("INSERT INTO ");
                            var sbSelect = new StringBuilder("SELECT ");

                            sbInsert.Append(database.Key);
                            if (!string.IsNullOrEmpty(schema.Key))
                            {
                                sbInsert.Append(".\"").Append(schema.Key).Append('"');
                            }
                            sbInsert.Append(".\"")
                            .Append(table.Name)
                            .Append("\" (");

                            //Nom des colonnes
                            var nbCols = table.ColumnsDefinition.Count;
                            for (var j = 0; j < nbCols; j++)
                            {
                                //Select
                                sbSelect.Append('"').Append(table.ColumnsDefinition[j].Name).Append('"');
                                if (j < nbCols - 1)
                                {
                                    sbSelect.Append(",");
                                }

                                //Insert
                                if (!table.ColumnsDefinition[j].IsAutoIncrement)
                                {
                                    sbInsert.Append('"').Append(table.ColumnsDefinition[j].Name).Append('"');
                                    if (j < nbCols - 1)
                                    {
                                        sbInsert.Append(",");
                                    }
                                }
                            }
                            sbInsert.Append(") VALUES(");

                            //Valeur des colonnes Insert
                            for (var j = 0; j < nbCols; j++)
                            {
                                if (!table.ColumnsDefinition[j].IsAutoIncrement)
                                {
                                    sbInsert.Append("@").Append(table.ColumnsDefinition[j].Name);
                                    if (j < nbCols - 1)
                                    {
                                        sbInsert.Append(",");
                                    }
                                }
                            }
                            sbInsert.Append(");");

                            //Finalisation du select
                            sbSelect.Append(" FROM \"")
                            .Append(database.Key)
                            .Append('"');
                            if (!string.IsNullOrEmpty(schema.Key))
                            {
                                sbSelect.Append(".\"").Append(schema.Key).Append('"');
                            }
                            sbSelect.Append(".\"")
                            .Append(table.Name)
                            .Append("\"");

                            table.InsertCommand = sbInsert.ToString();
                            table.SelectCommand = sbSelect.ToString();
                        }
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Merge a user behavior with the default metadatas.
        /// </summary>
        /// <param name="metadatas">Metadatas to generate queries for.</param>
        /// <param name="behavior">A behavior for cloning data</param>
        /// <param name="variables">The compiled cascade variables</param>
        private static void MergeBehaviour(this Metadatas metadatas, Behavior behavior, HashSet <SchemaVar> variables)
        {
            if (behavior == null)
            {
                return;
            }

            foreach (var dbSettings in behavior.DbSettings)
            {
                var dbSettingsVar = variables.First(v => v.Id == dbSettings.ForSchemaId);

                if (!metadatas.ContainsKey(dbSettingsVar.Server))
                {
                    continue;
                }
                var server = metadatas[dbSettingsVar.Server];
                if (!server.ContainsKey(dbSettingsVar.Database))
                {
                    continue;
                }
                var database = server[dbSettingsVar.Database];
                if (!database.ContainsKey(dbSettingsVar.Schema))
                {
                    continue;
                }
                var schema = database[dbSettingsVar.Schema];

                foreach (var dbSettingsTable in dbSettings.Tables)
                {
                    var table = schema.FirstOrDefault(t => t.Name.Equals(dbSettingsTable.Name, StringComparison.CurrentCultureIgnoreCase));
                    if (table == null)
                    {
                        continue;
                    }

                    //On affecte les changements de la configuration
                    table.IsStatic = dbSettingsTable.IsStatic == NullableBool.True;

                    //Derivative tables
                    var globalAccess  = dbSettingsTable.DerativeTableGlobal.GlobalAccess;
                    var globalCascade = dbSettingsTable.DerativeTableGlobal.GlobalCascade;

                    //Default settings
                    foreach (var derivTbl in table.DerivativeTables)
                    {
                        derivTbl.Access  = globalAccess;
                        derivTbl.Cascade = globalCascade == NullableBool.True;
                    }

                    //Override if modified
                    foreach (var dbSettingsDerivativeTable in dbSettingsTable.DerativeTableGlobal.DerivativeTables)
                    {
                        var destinationVar  = variables.First(v => v.Id == dbSettingsDerivativeTable.DestinationSchema);
                        var derivativeTable = table.DerivativeTables.FirstOrDefault(t => t.ServerId == destinationVar.Server &&
                                                                                    t.Database.Equals(destinationVar.Database,
                                                                                                      StringComparison.OrdinalIgnoreCase) &&
                                                                                    t.Schema.Equals(destinationVar.Schema,
                                                                                                    StringComparison.OrdinalIgnoreCase) &&
                                                                                    t.Table.Equals(dbSettingsDerivativeTable.Name,
                                                                                                   StringComparison.OrdinalIgnoreCase));
                        if (derivativeTable == null)
                        {
                            continue;
                        }
                        derivativeTable.Access  = dbSettingsDerivativeTable.Access;
                        derivativeTable.Cascade = dbSettingsDerivativeTable.Cascade == NullableBool.True;
                    }

                    //Data builder
                    foreach (var builderCol in dbSettingsTable.DataBuilders)
                    {
                        var col = table.ColumnsDefinition.FirstOrDefault(c => c.Name.Equals(builderCol.Name, StringComparison.OrdinalIgnoreCase));
                        if (col != null)
                        {
                            col.BuilderName = builderCol.BuilderName;
                        }
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Load the result of an Sql query into the metadatas object.
        /// </summary>
        /// <param name="reader">Result of an Sql query defined in <see cref="MetadataProvider.SqlGetColumns"/></param>
        /// <param name="metadata">Metadatas container</param>
        /// <param name="serverId">ServerId loaded from</param>
        /// <param name="database">Database loaded from</param>
        /// <param name="typeConverter">Classe performing type conversion between database and .NET.</param>
        internal static void LoadColumns(IDataReader reader, Metadatas metadata, string serverId, string database, ISqlTypeConverter typeConverter)
        {
            var    schemaMetadata  = new SchemaMetadata();
            var    lstSchemaColumn = new List <ColumnDefinition>();
            string currentSchema;

            if (!reader.Read())
            {
                return;
            }

            //Init first row
            var previousSchema = reader.GetString(0);
            var previousTable  = new TableMetadata(reader.GetString(1));

            //Pour chaque ligne
            do
            {
                currentSchema = reader.GetString(0);
                var currentTable = reader.GetString(1);

                //Si on change de table
                if (currentSchema != previousSchema || currentTable != previousTable.Name)
                {
                    previousTable.ColumnsDefinition = lstSchemaColumn;
                    schemaMetadata.Add(previousTable);

                    lstSchemaColumn = new List <ColumnDefinition>();
                    previousTable   = new TableMetadata(currentTable);
                }

                //Si on change de schema
                if (currentSchema != previousSchema)
                {
                    metadata[serverId, database, currentSchema] = schemaMetadata;
                    schemaMetadata = new SchemaMetadata();
                }

                //Ajoute la colonne
                var col = new ColumnDefinition
                {
                    Name    = reader.GetString(2),
                    SqlType = new SqlType
                    {
                        DataType   = reader.GetString(3),
                        Precision  = reader.GetInt32(4),
                        Scale      = reader.GetInt32(5),
                        IsUnsigned = reader.GetBoolean(6)
                    },
                    IsPrimary       = reader.GetBoolean(7),
                    IsAutoIncrement = reader.GetBoolean(8)
                };
                col.DbType = typeConverter.ConvertFromSql(col.SqlType);

                lstSchemaColumn.Add(col);
            } while (reader.Read());

            //Ajoute la dernière table / schema
            if (lstSchemaColumn.Count > 0)
            {
                previousTable.ColumnsDefinition = lstSchemaColumn;
                schemaMetadata.Add(previousTable);
                metadata[serverId, database, currentSchema] = schemaMetadata;
            }
        }
예제 #8
0
        /// <summary>
        /// Load the result of an Sql query into the metadatas object.
        /// </summary>
        /// <param name="reader">Result of an Sql query defined in <see cref="MetadataProvider.SqlGetForeignKeys"/></param>
        /// <param name="metadata">Metadatas container</param>
        /// <param name="serverId">ServerId loaded from</param>
        /// <param name="database">Database loaded from</param>
        internal static void LoadForeignKeys(IDataReader reader, Metadatas metadata, string serverId, string database)
        {
            var lstForeignKeys       = new List <ForeignKey>();
            var lstForeignKeyColumns = new List <ForeignKeyColumn>();

            if (!reader.Read())
            {
                return;
            }

            //Init first row
            var currentSchema          = reader.GetString(0);
            var previousTable          = metadata[serverId][database][currentSchema].First(t => t.Name.Equals(reader.GetString(1), StringComparison.OrdinalIgnoreCase));
            var previousConstraintName = reader.GetString(2);
            var previousConstraint     = new ForeignKey
            {
                ServerIdTo = serverId,
                DatabaseTo = database,
                SchemaTo   = currentSchema,
                TableTo    = reader.GetString(5)
            };

            //Pour chaque ligne
            do
            {
                currentSchema = reader.GetString(0);
                var currentTable      = reader.GetString(1);
                var currentConstraint = reader.GetString(2);

                //Si on change de constraint
                if (currentTable != previousTable.Name || currentConstraint != previousConstraintName)
                {
                    previousConstraint.Columns = lstForeignKeyColumns;
                    lstForeignKeys.Add(previousConstraint);

                    lstForeignKeyColumns = new List <ForeignKeyColumn>();
                    previousConstraint   = new ForeignKey
                    {
                        ServerIdTo = serverId,
                        DatabaseTo = database,
                        SchemaTo   = currentSchema,
                        TableTo    = reader.GetString(5)
                    };
                    previousConstraintName = currentConstraint;
                }

                //Si on change de table
                if (currentTable != previousTable.Name)
                {
                    previousTable.ForeignKeys = lstForeignKeys;

                    //Change de table
                    previousTable  = metadata[serverId][database][currentSchema].First(t => t.Name.Equals(reader.GetString(1), StringComparison.OrdinalIgnoreCase));
                    lstForeignKeys = new List <ForeignKey>();
                }

                //Ajoute la colonne
                var colName = reader.GetString(3);
                lstForeignKeyColumns.Add(new ForeignKeyColumn
                {
                    NameFrom = colName,
                    NameTo   = reader.GetString(6)
                });

                //Affecte l'indicateur dans le schema
                var col = previousTable.ColumnsDefinition.FirstOrDefault(c => c.Name.Equals(colName, StringComparison.OrdinalIgnoreCase));
                if (col == null)
                {
                    throw new Exception($"The column {colName} has not been found in the metadata for the table {previousTable.Name}.");
                }
                col.IsForeignKey = true;
            } while (reader.Read());

            //Ajoute la dernière table / schema
            if (lstForeignKeyColumns.Count > 0)
            {
                previousConstraint.Columns = lstForeignKeyColumns;
                lstForeignKeys.Add(previousConstraint);
                previousTable.ForeignKeys = lstForeignKeys;
            }
        }