system/src/sc/lang/sql/SchemaManager.java
public void initFromDB(Layer buildLayer, boolean changeReadyState) {
      if (!needsInitFromDB)
         return;
      ISchemaUpdater schemaUpdater = provider.getSchemaUpdater();
      int numOutOfSync = 0;
      int numChanged = 0;
      if (schemaUpdater != null) {
         if (dataSourceName != null) {
            dbSchemaTypes = schemaUpdater.getDBSchemas(dataSourceName);
            initFromDBFailed = dbSchemaTypes == null;

            dbMetadata = schemaUpdater.getDBMetadata(dataSourceName);
            dbMetadataFailed = dbMetadata == null;
            dbMissingMetadata = null;
         }

         if (!initFromDBFailed) {
            needsInitFromDB = false;

            // Compare the db_schema_ table contents to the new+changed types as computed from the most recent deployed build.
            // We'll recompute the new+alter scripts accordingly
            for (DBSchemaType dbTypeSchema: dbSchemaTypes) {
               String typeName = dbTypeSchema.getTypeName();
               SQLFileModel newSchema = schemasByType.get(typeName);
               // There's a schema in the database for a type not defined in this layer - it might be that we are sharing
               // a database with other programs but at least make this info available to the schemaManager
               if (newSchema == null) {
                  notUsedTypeSchemas.add(dbTypeSchema);
               }
               else {
                  String sqlStr = dbTypeSchema.getCurrentVersion().getSchemaSQL();
                  Object parseRes = SQLLanguage.getSQLLanguage().parseString(sqlStr);
                  if (parseRes instanceof ParseError) {
                     DBUtil.error("Parse error - unable to parse schema from current database for type:" + typeName + " :" + sqlStr);
                     continue;
                  }
                  SQLFileModel dbModel = (SQLFileModel) ParseUtil.nodeToSemanticValue(parseRes);
                  dbModel.srcType = newSchema.srcType;

                  // Check the current database schema against what we have in the db_schema_ tables
                  DBMetadata missingTableInfo = dbModel.getMissingTableInfo(dbMetadata);
                  if (missingTableInfo != null) {
                     DBUtil.error("Current db_schema_type table for: " + typeName + " - out of sync. It has this info: " + missingTableInfo + " missing in current DB");
                     schemaUpdater.removeDBSchemaForType(dataSourceName, typeName);
                     numOutOfSync++;
                     continue;
                  }

                  // This model already matches what's in the database schema so it's not actually a new model
                  if (DynUtil.equalObjects(dbModel.sqlCommands, newSchema.sqlCommands)) {
                     newModels.remove(newSchema);
                     alterSchema.remove(newSchema);
                     removeChangedType(typeName);
                     recordDeployedSchema(typeName, newSchema, buildLayer);
                  }
                  else {
                     SchemaTypeChange curChange = getChangedType(typeName);
                     if (curChange != null) {
                        if (!curChange.fromModel.equals(dbModel)) {
                           DBUtil.warn("Model stored in database does not match last build");
                           // This will be more reliable since it's stored next to the data
                           curChange.fromModel = dbModel;
                        }
                        else if (curChange.toModel.equals(dbModel)) {
                           // we already have this change from the file system cache
                           removeChangedType(typeName);
                        }
                     }
                     else {
                        newModels.remove(newSchema);
                        alterSchema.remove(newSchema);
                        DBUtil.info("Schema for type: " + typeName + " discovered from database schema");
                        SchemaTypeChange change = new SchemaTypeChange(typeName, dbModel, newSchema);
                        updateAlterModel(change);
                        changedTypes.add(change);
                        numChanged++;
                     }
                  }
               }
            }

            if (dbMetadata != null) {
               ArrayList<SQLFileModel> toRemove = new ArrayList<SQLFileModel>();
               for (TableInfo tableInfo:dbMetadata.tableInfos) {
                  for (SQLFileModel newSchema:newModels) {
                     CreateTable table = newSchema.findCreateTable(tableInfo.tableName);
                     if (table != null) {
                        TableInfo missingInfo = table.getMissingTableInfo(tableInfo);
                        toRemove.add(newSchema);
                        if (missingInfo == null) {
                           DBUtil.warn("Matching table: " + tableInfo.tableName + " exists in: " + dbMetadata.dataSourceName);
                           // TODO: We're removing all changes for this type rather than just the 'create table' that might not be fully accurate
                        }
                        else {
                           DBUtil.warn("Table: " + tableInfo.tableName + " exists in: " + dbMetadata.dataSourceName + " but is missing: " + missingInfo);
                           conflictModels.add(newSchema);
                        }
                     }
                  }
               }
               if (toRemove.size() > 0) {
                  newModels.removeAll(toRemove);
                  alterSchema.removeAll(toRemove);
               }
            }

            schemaChanged = newModels.size() > 0 || changedTypes.size() > 0;

            if (!schemaChanged) {
               DBUtil.info("Schema manager - init from DB found all tables/columns in schema");
            }
            else {
               DBUtil.info("Schema manager - init from DB found:  " + numChanged + " types changed and " + numOutOfSync + " out of sync ");
            }
         }

         // There's no db_schema_type metadata, but there is metadata provided by the DB. We'll check it against the
         // current schema for differences:
         if (!dbMetadataFailed) {
            if (currentSchema != null) {
               for (SQLFileModel typeSchema:currentSchema) {
                  DBMetadata missingData = typeSchema.getMissingTableInfo(dbMetadata);
                  if (missingData != null) {
                     if (dbMissingMetadata == null)
                        dbMissingMetadata = missingData;
                     else
                        dbMissingMetadata.addMetadata(missingData);
                  }
               }

               dbExtraMetadata = null;
               for (TableInfo tableInfo:dbMetadata.tableInfos) {
                  String tableName = tableInfo.tableName;

                  if (isMetadataTable(tableName))
                     continue;

                  CreateTable createTable = null;
                  for (SQLFileModel typeSchema:currentSchema) {
                     createTable = typeSchema.findCreateTable(tableName);
                     if (createTable != null)
                        break;
                  }
                  if (createTable == null) {
                     if (dbExtraMetadata == null)
                        dbExtraMetadata = new DBMetadata();
                     dbExtraMetadata.tableInfos.add(tableInfo);
                  }
                  else {
                     ArrayList<ColumnInfo> extraCols = null;
                     for (ColumnInfo colInfo:tableInfo.colInfos) {
                        ColumnDef colDef = createTable.findColumn(colInfo.colName);
                        if (colDef == null) {
                           if (extraCols == null)
                              extraCols = new ArrayList<ColumnInfo>();
                           extraCols.add(colInfo);
                        }
                     }
                     if (extraCols != null) {
                        TableInfo ti = new TableInfo(tableName);
                        ti.colInfos = extraCols;
                        if (dbExtraMetadata == null)
                           dbExtraMetadata = new DBMetadata();
                        dbExtraMetadata.tableInfos.add(ti);
                     }
                  }
               }
            }
         }

         if (changeReadyState) {
            // The deployed schema does not match and we are running interactively so tell apps to wait till we fix
            // the DB schema before running
            if ((initFromDBFailed || schemaChanged || dbMissingMetadata != null) && system.options.startInterpreter) {
               markSchemaNotReady();
            }
            // After initializing from the database, we find that the DB is setup properly - because we turned off
            // the default schema though, need to tell the apps to go ahead and run
            else if (!schemaChanged && schemaNotReady) {
               markSchemaReady();
            }
         }
      }
   }
/**
    * Connect to the database and populate the schema manager with two types of metadata about the schema. Use the db_schema_
    * tables to retrieve our record of the schema along with (optionally) the database table/column metadata to see what's actually there.
    */
Connect to the database and populate the schema manager with two types of metadata about the schema. Use the db_schema_
tables to retrieve our record of the schema along with (optionally) the database table/column metadata to see what's actually there.
Connect to the database and populate the schema manager with two types of metadata about the schema . Use the db_schema_ tables to retrieve our record of the schema along with ( optionally ) the database table / column metadata to see what ' s actually there .
public void initFromDB(Layer buildLayer, boolean changeReadyState) {
      if (!needsInitFromDB)
         return;
      ISchemaUpdater schemaUpdater = provider.getSchemaUpdater();
      int numOutOfSync = 0;
      int numChanged = 0;
      if (schemaUpdater != null) {
         if (dataSourceName != null) {
            dbSchemaTypes = schemaUpdater.getDBSchemas(dataSourceName);
            initFromDBFailed = dbSchemaTypes == null;
            dbMetadata = schemaUpdater.getDBMetadata(dataSourceName);
            dbMetadataFailed = dbMetadata == null;
            dbMissingMetadata = null;
         }
         if (!initFromDBFailed) {
            needsInitFromDB = false;
            for (DBSchemaType dbTypeSchema: dbSchemaTypes) {
               String typeName = dbTypeSchema.getTypeName();
               SQLFileModel newSchema = schemasByType.get(typeName);
               if (newSchema == null) {
                  notUsedTypeSchemas.add(dbTypeSchema);
               }
               else {
                  String sqlStr = dbTypeSchema.getCurrentVersion().getSchemaSQL();
                  Object parseRes = SQLLanguage.getSQLLanguage().parseString(sqlStr);
                  if (parseRes instanceof ParseError) {
                     DBUtil.error("Parse error - unable to parse schema from current database for type:" + typeName + " :" + sqlStr);
                     continue;
                  }
                  SQLFileModel dbModel = (SQLFileModel) ParseUtil.nodeToSemanticValue(parseRes);
                  dbModel.srcType = newSchema.srcType;
                  DBMetadata missingTableInfo = dbModel.getMissingTableInfo(dbMetadata);
                  if (missingTableInfo != null) {
                     DBUtil.error("Current db_schema_type table for: " + typeName + " - out of sync. It has this info: " + missingTableInfo + " missing in current DB");
                     schemaUpdater.removeDBSchemaForType(dataSourceName, typeName);
                     numOutOfSync++;
                     continue;
                  }
                  if (DynUtil.equalObjects(dbModel.sqlCommands, newSchema.sqlCommands)) {
                     newModels.remove(newSchema);
                     alterSchema.remove(newSchema);
                     removeChangedType(typeName);
                     recordDeployedSchema(typeName, newSchema, buildLayer);
                  }
                  else {
                     SchemaTypeChange curChange = getChangedType(typeName);
                     if (curChange != null) {
                        if (!curChange.fromModel.equals(dbModel)) {
                           DBUtil.warn("Model stored in database does not match last build");
                           curChange.fromModel = dbModel;
                        }
                        else if (curChange.toModel.equals(dbModel)) {
                           removeChangedType(typeName);
                        }
                     }
                     else {
                        newModels.remove(newSchema);
                        alterSchema.remove(newSchema);
                        DBUtil.info("Schema for type: " + typeName + " discovered from database schema");
                        SchemaTypeChange change = new SchemaTypeChange(typeName, dbModel, newSchema);
                        updateAlterModel(change);
                        changedTypes.add(change);
                        numChanged++;
                     }
                  }
               }
            }
            if (dbMetadata != null) {
               ArrayList<SQLFileModel> toRemove = new ArrayList<SQLFileModel>();
               for (TableInfo tableInfo:dbMetadata.tableInfos) {
                  for (SQLFileModel newSchema:newModels) {
                     CreateTable table = newSchema.findCreateTable(tableInfo.tableName);
                     if (table != null) {
                        TableInfo missingInfo = table.getMissingTableInfo(tableInfo);
                        toRemove.add(newSchema);
                        if (missingInfo == null) {
                           DBUtil.warn("Matching table: " + tableInfo.tableName + " exists in: " + dbMetadata.dataSourceName);
                        }
                        else {
                           DBUtil.warn("Table: " + tableInfo.tableName + " exists in: " + dbMetadata.dataSourceName + " but is missing: " + missingInfo);
                           conflictModels.add(newSchema);
                        }
                     }
                  }
               }
               if (toRemove.size() > 0) {
                  newModels.removeAll(toRemove);
                  alterSchema.removeAll(toRemove);
               }
            }
            schemaChanged = newModels.size() > 0 || changedTypes.size() > 0;
            if (!schemaChanged) {
               DBUtil.info("Schema manager - init from DB found all tables/columns in schema");
            }
            else {
               DBUtil.info("Schema manager - init from DB found:  " + numChanged + " types changed and " + numOutOfSync + " out of sync ");
            }
         }
         if (!dbMetadataFailed) {
            if (currentSchema != null) {
               for (SQLFileModel typeSchema:currentSchema) {
                  DBMetadata missingData = typeSchema.getMissingTableInfo(dbMetadata);
                  if (missingData != null) {
                     if (dbMissingMetadata == null)
                        dbMissingMetadata = missingData;
                     else
                        dbMissingMetadata.addMetadata(missingData);
                  }
               }
               dbExtraMetadata = null;
               for (TableInfo tableInfo:dbMetadata.tableInfos) {
                  String tableName = tableInfo.tableName;
                  if (isMetadataTable(tableName))
                     continue;
                  CreateTable createTable = null;
                  for (SQLFileModel typeSchema:currentSchema) {
                     createTable = typeSchema.findCreateTable(tableName);
                     if (createTable != null)
                        break;
                  }
                  if (createTable == null) {
                     if (dbExtraMetadata == null)
                        dbExtraMetadata = new DBMetadata();
                     dbExtraMetadata.tableInfos.add(tableInfo);
                  }
                  else {
                     ArrayList<ColumnInfo> extraCols = null;
                     for (ColumnInfo colInfo:tableInfo.colInfos) {
                        ColumnDef colDef = createTable.findColumn(colInfo.colName);
                        if (colDef == null) {
                           if (extraCols == null)
                              extraCols = new ArrayList<ColumnInfo>();
                           extraCols.add(colInfo);
                        }
                     }
                     if (extraCols != null) {
                        TableInfo ti = new TableInfo(tableName);
                        ti.colInfos = extraCols;
                        if (dbExtraMetadata == null)
                           dbExtraMetadata = new DBMetadata();
                        dbExtraMetadata.tableInfos.add(ti);
                     }
                  }
               }
            }
         }
         if (changeReadyState) {
            if ((initFromDBFailed || schemaChanged || dbMissingMetadata != null) && system.options.startInterpreter) {
               markSchemaNotReady();
            }
            else if (!schemaChanged && schemaNotReady) {
               markSchemaReady();
            }
         }
      }
   }
public void initFromDB ( Layer buildLayer , boolean changeReadyState ) { if ( ! needsInitFromDB ) return ; ISchemaUpdater schemaUpdater = provider . getSchemaUpdater ( ) ; int numOutOfSync = 0 ; int numChanged = 0 ; if ( schemaUpdater != null ) { if ( dataSourceName != null ) { dbSchemaTypes = schemaUpdater . getDBSchemas ( dataSourceName ) ; initFromDBFailed = dbSchemaTypes == null ; dbMetadata = schemaUpdater . getDBMetadata ( dataSourceName ) ; dbMetadataFailed = dbMetadata == null ; dbMissingMetadata = null ; } if ( ! initFromDBFailed ) { needsInitFromDB = false ; for ( DBSchemaType dbTypeSchema : dbSchemaTypes ) { String typeName = dbTypeSchema . getTypeName ( ) ; SQLFileModel newSchema = schemasByType . get ( typeName ) ; if ( newSchema == null ) { notUsedTypeSchemas . add ( dbTypeSchema ) ; } else { String sqlStr = dbTypeSchema . getCurrentVersion ( ) . getSchemaSQL ( ) ; Object parseRes = SQLLanguage . getSQLLanguage ( ) . parseString ( sqlStr ) ; if ( parseRes instanceof ParseError ) { DBUtil . error ( "Parse error - unable to parse schema from current database for type:" + typeName + " :" + sqlStr ) ; continue ; } SQLFileModel dbModel = ( SQLFileModel ) ParseUtil . nodeToSemanticValue ( parseRes ) ; dbModel . srcType = newSchema . srcType ; DBMetadata missingTableInfo = dbModel . getMissingTableInfo ( dbMetadata ) ; if ( missingTableInfo != null ) { DBUtil . error ( "Current db_schema_type table for: " + typeName + " - out of sync. It has this info: " + missingTableInfo + " missing in current DB" ) ; schemaUpdater . removeDBSchemaForType ( dataSourceName , typeName ) ; numOutOfSync ++ ; continue ; } if ( DynUtil . equalObjects ( dbModel . sqlCommands , newSchema . sqlCommands ) ) { newModels . remove ( newSchema ) ; alterSchema . remove ( newSchema ) ; removeChangedType ( typeName ) ; recordDeployedSchema ( typeName , newSchema , buildLayer ) ; } else { SchemaTypeChange curChange = getChangedType ( typeName ) ; if ( curChange != null ) { if ( ! curChange . fromModel . equals ( dbModel ) ) { DBUtil . warn ( "Model stored in database does not match last build" ) ; curChange . fromModel = dbModel ; } else if ( curChange . toModel . equals ( dbModel ) ) { removeChangedType ( typeName ) ; } } else { newModels . remove ( newSchema ) ; alterSchema . remove ( newSchema ) ; DBUtil . info ( "Schema for type: " + typeName + " discovered from database schema" ) ; SchemaTypeChange change = new SchemaTypeChange ( typeName , dbModel , newSchema ) ; updateAlterModel ( change ) ; changedTypes . add ( change ) ; numChanged ++ ; } } } } if ( dbMetadata != null ) { ArrayList < SQLFileModel > toRemove = new ArrayList < SQLFileModel > ( ) ; for ( TableInfo tableInfo : dbMetadata . tableInfos ) { for ( SQLFileModel newSchema : newModels ) { CreateTable table = newSchema . findCreateTable ( tableInfo . tableName ) ; if ( table != null ) { TableInfo missingInfo = table . getMissingTableInfo ( tableInfo ) ; toRemove . add ( newSchema ) ; if ( missingInfo == null ) { DBUtil . warn ( "Matching table: " + tableInfo . tableName + " exists in: " + dbMetadata . dataSourceName ) ; } else { DBUtil . warn ( "Table: " + tableInfo . tableName + " exists in: " + dbMetadata . dataSourceName + " but is missing: " + missingInfo ) ; conflictModels . add ( newSchema ) ; } } } } if ( toRemove . size ( ) > 0 ) { newModels . removeAll ( toRemove ) ; alterSchema . removeAll ( toRemove ) ; } } schemaChanged = newModels . size ( ) > 0 || changedTypes . size ( ) > 0 ; if ( ! schemaChanged ) { DBUtil . info ( "Schema manager - init from DB found all tables/columns in schema" ) ; } else { DBUtil . info ( "Schema manager - init from DB found:  " + numChanged + " types changed and " + numOutOfSync + " out of sync " ) ; } } if ( ! dbMetadataFailed ) { if ( currentSchema != null ) { for ( SQLFileModel typeSchema : currentSchema ) { DBMetadata missingData = typeSchema . getMissingTableInfo ( dbMetadata ) ; if ( missingData != null ) { if ( dbMissingMetadata == null ) dbMissingMetadata = missingData ; else dbMissingMetadata . addMetadata ( missingData ) ; } } dbExtraMetadata = null ; for ( TableInfo tableInfo : dbMetadata . tableInfos ) { String tableName = tableInfo . tableName ; if ( isMetadataTable ( tableName ) ) continue ; CreateTable createTable = null ; for ( SQLFileModel typeSchema : currentSchema ) { createTable = typeSchema . findCreateTable ( tableName ) ; if ( createTable != null ) break ; } if ( createTable == null ) { if ( dbExtraMetadata == null ) dbExtraMetadata = new DBMetadata ( ) ; dbExtraMetadata . tableInfos . add ( tableInfo ) ; } else { ArrayList < ColumnInfo > extraCols = null ; for ( ColumnInfo colInfo : tableInfo . colInfos ) { ColumnDef colDef = createTable . findColumn ( colInfo . colName ) ; if ( colDef == null ) { if ( extraCols == null ) extraCols = new ArrayList < ColumnInfo > ( ) ; extraCols . add ( colInfo ) ; } } if ( extraCols != null ) { TableInfo ti = new TableInfo ( tableName ) ; ti . colInfos = extraCols ; if ( dbExtraMetadata == null ) dbExtraMetadata = new DBMetadata ( ) ; dbExtraMetadata . tableInfos . add ( ti ) ; } } } } } if ( changeReadyState ) { if ( ( initFromDBFailed || schemaChanged || dbMissingMetadata != null ) && system . options . startInterpreter ) { markSchemaNotReady ( ) ; } else if ( ! schemaChanged && schemaNotReady ) { markSchemaReady ( ) ; } } } }
Connect to the database and populate the schema manager with two types of metadata about the schema.
Connect to the database and populate the schema manager with two types of metadata about the schema .
// Compare the db_schema_ table contents to the new+changed types as computed from the most recent deployed build. // We'll recompute the new+alter scripts accordingly // There's a schema in the database for a type not defined in this layer - it might be that we are sharing // a database with other programs but at least make this info available to the schemaManager // Check the current database schema against what we have in the db_schema_ tables // This model already matches what's in the database schema so it's not actually a new model // This will be more reliable since it's stored next to the data // we already have this change from the file system cache // TODO: We're removing all changes for this type rather than just the 'create table' that might not be fully accurate // There's no db_schema_type metadata, but there is metadata provided by the DB. We'll check it against the // current schema for differences: // The deployed schema does not match and we are running interactively so tell apps to wait till we fix // the DB schema before running // After initializing from the database, we find that the DB is setup properly - because we turned off // the default schema though, need to tell the apps to go ahead and run