/// <summary> /// Parses DISABLE statements. /// </summary> private static void ParseDisable(Parser parser, bool outputIgnoredStatements, string tableName, PgDatabase database) { if (parser.ExpectOptional("TRIGGER")) { if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + tableName + " DISABLE TRIGGER " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else if (parser.ExpectOptional("RULE")) { if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + tableName + " DISABLE RULE " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } }
/// <summary> /// Parses COMMENT statements. /// </summary> public static void Parse(PgDatabase database, string statement, bool outputIgnoredStatements) { var parser = new Parser(statement); parser.Expect("COMMENT", "ON"); if (parser.ExpectOptional("TABLE")) { ParseTable(parser, database); } else if (parser.ExpectOptional("COLUMN")) { ParseColumn(parser, database); } else if (parser.ExpectOptional("CONSTRAINT")) { ParseConstraint(parser, database); } else if (parser.ExpectOptional("DATABASE")) { ParseDatabase(parser, database); } else if (parser.ExpectOptional("FUNCTION")) { ParseFunction(parser, database); } else if (parser.ExpectOptional("INDEX")) { ParseIndex(parser, database); } else if (parser.ExpectOptional("SCHEMA")) { ParseSchema(parser, database); } else if (parser.ExpectOptional("SEQUENCE")) { ParseSequence(parser, database); } else if (parser.ExpectOptional("TRIGGER")) { ParseTrigger(parser, database); } else if (parser.ExpectOptional("VIEW")) { ParseView(parser, database); } else if (outputIgnoredStatements) { database.AddIgnoredStatement(statement); } }
/// <summary> /// Parses ALTER TABLE view. /// </summary> private static void ParseView(Parser parser, PgView view, bool outputIgnoredStatements, string viewName, PgDatabase database) { while (!parser.ExpectOptional(";")) { if (parser.ExpectOptional("ALTER")) { parser.ExpectOptional("COLUMN"); var columnName = ParserUtils.GetObjectName(parser.ParseIdentifier()); if (parser.ExpectOptional("SET", "DEFAULT")) { var expression = parser.Expression(); view.AddColumnDefaultValue(columnName, expression); } else if (parser.ExpectOptional("DROP", "DEFAULT")) { view.RemoveColumnDefaultValue(columnName); } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } else if (parser.ExpectOptional("OWNER", "TO")) { // we do not parse this one so we just consume the identifier if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + viewName + " OWNER TO " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } }
/// <summary> /// Parses ALTER TABLE sequence. /// </summary> private static void ParseSequence(Parser parser, PgSequence sequence, bool outputIgnoredStatements, string sequenceName, PgDatabase database) { while (!parser.ExpectOptional(";")) { if (parser.ExpectOptional("OWNER", "TO")) { // we do not parse this one so we just consume the identifier if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + sequenceName + " OWNER TO " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } }
/// <summary> /// Parses ALTER TABLE statement. /// </summary> public static void Parse(PgDatabase database, string statement, bool outputIgnoredStatements) { var parser = new Parser(statement); parser.Expect("ALTER", "TABLE"); parser.ExpectOptional("ONLY"); var tableName = parser.ParseIdentifier(); var schemaName = ParserUtils.GetSchemaName(tableName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} from {statement}"); } var objectName = ParserUtils.GetObjectName(tableName); PgTable table = schema.GetTable(objectName); if (table == null) { PgView view = schema.GetView(objectName); if (view != null) { ParseView(parser, view, outputIgnoredStatements, tableName, database); return; } PgSequence sequence = schema.GetSequence(objectName); if (sequence != null) { ParseSequence(parser, sequence, outputIgnoredStatements, tableName, database); return; } throw new TeamworkParserException($"CannotFindObject in {tableName} from {statement}"); } while (!parser.ExpectOptional(";")) { if (parser.ExpectOptional("ALTER")) { ParseAlterColumn(parser, table); } else if (parser.ExpectOptional("CLUSTER", "ON")) { table.ClusterIndexName = ParserUtils.GetObjectName(parser.ParseIdentifier()); } else if (parser.ExpectOptional("OWNER", "TO")) { // we do not parse this one so we just consume the identifier if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + tableName + " OWNER TO " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else if (parser.ExpectOptional("ADD")) { if (parser.ExpectOptional("FOREIGN", "KEY")) { ParseAddForeignKey(parser, table); } else if (parser.ExpectOptional("CONSTRAINT")) { ParseAddConstraint(parser, table, schema); } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } else if (parser.ExpectOptional("ENABLE")) { ParseEnable(parser, outputIgnoredStatements, tableName, database); } else if (parser.ExpectOptional("DISABLE")) { ParseDisable(parser, outputIgnoredStatements, tableName, database); } else if (parser.ExpectOptional("REPLICA IDENTITY")) { parser.Expect("NOTHING"); } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } if (parser.ExpectOptional(";")) { break; } else { parser.Expect(","); } } }
/// <summary> /// Loads database schema from dump file. /// </summary> /// <param name="file">The path to the file which is loaded.</param> /// <param name="database">The database.</param> /// <param name="encodingName">Charset that should be used to read the file.</param> /// <param name="outputIgnoredStatements">Whether ignored statements should be included in the output.</param> /// <param name="ignoreSlonyTriggers">Indicates if slony triggers are ignored.</param> /// <returns>Database schema from dump file.</returns> public static PgDatabase LoadDatabaseSchema(string file, Database database, bool outputIgnoredStatements, bool ignoreSlonyTriggers, string encodingName = DefaultEncoding) { var encoding = Encoding.GetEncoding(encodingName); var pgDatabase = new PgDatabase(database.Name, database.IgnoredSchemas.ToList()); StreamReader reader = null; using (reader = new StreamReader(file, encoding)) { var statement = GetWholeStatement(reader); while (statement != null) { if (PatternCreateSchema.Matches(statement).Count != 0) { CreateSchemaParser.Parse(pgDatabase, statement); } else if (PatternCreateRule.Matches(statement).Count != 0) { CreateRuleParser.Parse(pgDatabase, statement); } else if (PatternDefaultSchema.Matches(statement).Count != 0) { PatternDefaultSchema.Matches(statement); pgDatabase.SetDefaultSchema(PatternDefaultSchema.Matches(statement)[0].Groups[1].ToString()); } else if (PatternCreateTable.Matches(statement).Count != 0) { CreateTableParser.Parse(pgDatabase, statement); } else if (PatternAlterTable.Matches(statement).Count != 0) { AlterTableParser.Parse(pgDatabase, statement, outputIgnoredStatements); } else if (PatternCreateSequence.Matches(statement).Count != 0) { CreateSequenceParser.Parse(pgDatabase, statement); } else if (PatternAlterSequence.Matches(statement).Count != 0) { AlterSequenceParser.Parse(pgDatabase, statement); } else if (PatternCreateIndex.Matches(statement).Count != 0) { CreateIndexParser.Parse(pgDatabase, statement); } else if (PatternCreateView.Matches(statement).Count != 0) { CreateViewParser.Parse(pgDatabase, statement); } else if (PatternAlterView.Matches(statement).Count != 0) { AlterViewParser.Parse(pgDatabase, statement, outputIgnoredStatements); } else if (PatternCreateTrigger.Matches(statement).Count != 0) { CreateTriggerParser.Parse(pgDatabase, statement, ignoreSlonyTriggers); } else if (PatternCreateFunction.Matches(statement).Count != 0) { CreateFunctionParser.Parse(pgDatabase, statement); } else if (PatternPrivilegeGrant.Matches(statement).Count != 0) { PrivilegeParser.Parse(pgDatabase, statement, PgPrivilegeCommand.Grant); } else if (PatternPrivilegeRevoke.Matches(statement).Count != 0) { PrivilegeParser.Parse(pgDatabase, statement, PgPrivilegeCommand.Revoke); } else if (PatternCreateAggregate.Matches(statement).Count != 0) { CreateAggregateParser.Parse(pgDatabase, statement); } else if (PatternComment.Matches(statement).Count != 0) { CommentParser.Parse(pgDatabase, statement, outputIgnoredStatements); } else if (PatternCreateType.Matches(statement).Count != 0) { CreateTypeParser.Parse(pgDatabase, statement); } else if (PatternSelect.Matches(statement).Count != 0 || PatternInsertInto.Matches(statement).Count != 0 || PatternUpdate.Matches(statement).Count != 0 || PatternDeleteFrom.Matches(statement).Count != 0) { // these statements are ignored } else if (outputIgnoredStatements) { pgDatabase.AddIgnoredStatement(statement); } else { // these statements are ignored if outputIgnoredStatements is false } statement = GetWholeStatement(reader); } } return(pgDatabase); }
/// <summary> /// Parses ALTER VIEW statement. /// </summary> public static void Parse(PgDatabase database, string statement, bool outputIgnoredStatements) { var parser = new Parser(statement); parser.Expect("ALTER", "VIEW"); var viewName = parser.ParseIdentifier(); var schemaName = ParserUtils.GetSchemaName(viewName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} from {statement}"); } var objectName = ParserUtils.GetObjectName(viewName); PgView view = schema.GetView(objectName); if (view == null) { throw new TeamworkParserException($"CannotFindView {viewName} from {statement}"); } while (!parser.ExpectOptional(";")) { if (parser.ExpectOptional("ALTER")) { parser.ExpectOptional("COLUMN"); var columnName = ParserUtils.GetObjectName(parser.ParseIdentifier()); if (parser.ExpectOptional("SET", "DEFAULT")) { var expression = parser.Expression(); view.AddColumnDefaultValue(columnName, expression); } else if (parser.ExpectOptional("DROP", "DEFAULT")) { view.RemoveColumnDefaultValue(columnName); } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } else if (parser.ExpectOptional("OWNER", "TO")) { // we do not parse this one so we just consume the identifier if (outputIgnoredStatements) { database.AddIgnoredStatement("ALTER TABLE " + viewName + " OWNER TO " + parser.ParseIdentifier() + ';'); } else { parser.ParseIdentifier(); } } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } }