/** * Add one columns to this table, regardless of the {@link Column#position() position} of the supplied * columns. However, if an existing column definition matches a supplied column, the new column definition will replace * the existing column definition. * * @param column the definition for the column to be added * @return this editor so callers can chain methods together */ default TableEditor addColumn(Column column) { return addColumns(column); }
public Table getTableSchemaFromChangeTable(ChangeTable changeTable) throws SQLException { final DatabaseMetaData metadata = connection().getMetaData(); final TableId changeTableId = changeTable.getChangeTableId(); List<ColumnEditor> columnEditors = new ArrayList<>(); try (ResultSet rs = metadata.getColumns(realDatabaseName, changeTableId.schema(), changeTableId.table(), null)) { while (rs.next()) { readTableColumn(rs, changeTableId, null).ifPresent(columnEditors::add); } } // The first 5 columns and the last column of the change table are CDC metadata final List<Column> columns = columnEditors.subList(CHANGE_TABLE_DATA_COLUMN_OFFSET, columnEditors.size() - 1).stream() .map(c -> c.position(c.position() - CHANGE_TABLE_DATA_COLUMN_OFFSET).create()) .collect(Collectors.toList()); final List<String> pkColumnNames = new ArrayList<>(); prepareQuery(GET_LIST_OF_KEY_COLUMNS, ps -> ps.setInt(1, changeTable.getChangeTableObjectId()), rs -> { while (rs.next()) { pkColumnNames.add(rs.getString(2)); } }); Collections.sort(columns); return Table.editor() .tableId(changeTable.getSourceTableId()) .addColumns(columns) .setPrimaryKeyNames(pkColumnNames) .create(); }
public Table getTableSchemaFromTable(ChangeTable changeTable) throws SQLException { final DatabaseMetaData metadata = connection().getMetaData(); List<Column> columns = new ArrayList<>(); try (ResultSet rs = metadata.getColumns( realDatabaseName, changeTable.getSourceTableId().schema(), changeTable.getSourceTableId().table(), null) ) { while (rs.next()) { readTableColumn(rs, changeTable.getSourceTableId(), null).ifPresent(ce -> columns.add(ce.create())); } } final List<String> pkColumnNames = readPrimaryKeyNames(metadata, changeTable.getSourceTableId()); Collections.sort(columns); return Table.editor() .tableId(changeTable.getSourceTableId()) .addColumns(columns) .setPrimaryKeyNames(pkColumnNames) .create(); }
if (ctx.star != null) { tableByAlias.keySet().forEach(tableId -> { table.addColumns(tableByAlias.get(tableId).columns()); }); TableId tableId = parser.parseQualifiedTableId(((MySqlParser.SelectStarElementContext) selectElementContext).fullId()); Table selectedTable = tableByAlias.get(tableId); table.addColumns(selectedTable.columns());
@Override public void exitCreateView(MySqlParser.CreateViewContext ctx) { parser.runIfNotNull(() -> { tableEditor.addColumns(selectColumnsListener.getSelectedColumns()); // Make sure that the table's character set has been set ... if (!tableEditor.hasDefaultCharsetName()) { tableEditor.setDefaultCharsetName(parser.currentDatabaseCharset()); } parser.databaseTables().overwriteTable(tableEditor.create()); listeners.remove(selectColumnsListener); }, tableEditor); // signal view even if it was skipped parser.signalCreateView(parser.parseQualifiedTableId(ctx.fullId()), ctx); super.exitCreateView(ctx); } }
@Override public void exitAlterView(MySqlParser.AlterViewContext ctx) { parser.runIfNotNull(() -> { tableEditor.addColumns(selectColumnsListener.getSelectedColumns()); // Make sure that the table's character set has been set ... if (!tableEditor.hasDefaultCharsetName()) { tableEditor.setDefaultCharsetName(parser.currentDatabaseCharset()); } parser.databaseTables().overwriteTable(tableEditor.create()); listeners.remove(selectColumnsListener); }, tableEditor); // signal view even if it was skipped parser.signalAlterView(parser.parseQualifiedTableId(ctx.fullId()), null, ctx); super.exitAlterView(ctx); } }
protected Column parseCreateColumn(Marker start, TableEditor table, String columnName, String newColumnName) { // Obtain the column editor ... Column existingColumn = table.columnWithName(columnName); ColumnEditor column = existingColumn != null ? existingColumn.edit() : Column.editor().name(columnName); AtomicBoolean isPrimaryKey = new AtomicBoolean(false); parseColumnDefinition(start, columnName, tokens, table, column, isPrimaryKey); convertDefaultValueToSchemaType(column); // Update the table ... Column newColumnDefn = column.create(); table.addColumns(newColumnDefn); if (isPrimaryKey.get()) { table.setPrimaryKeyNames(newColumnDefn.name()); } if (newColumnName != null && !newColumnName.equalsIgnoreCase(columnName)) { table.renameColumn(columnName, newColumnName); columnName = newColumnName; } // ALTER TABLE allows reordering the columns after the definition ... if (tokens.canConsume("FIRST")) { table.reorderColumn(columnName, null); } else if (tokens.canConsume("AFTER")) { table.reorderColumn(columnName, tokens.consume()); } return table.columnWithName(newColumnDefn.name()); }
protected void parseTableElement(Marker start, TableEditor table) { if (tokens.matchesAnyOf("CONSTRAINT", "UNIQUE", "PRIMARY", "FOREIGN", "CHECK")) { parseTableConstraintDefinition(start, table); } else if (tokens.matches("LIKE")) { parseTableLikeClause(start, table); } else if (tokens.matches("REF", "IS")) { parseSelfReferencingColumnSpec(start, table); } else { // Obtain the column editor ... String columnName = tokens.consume(); Column existingColumn = table.columnWithName(columnName); ColumnEditor column = existingColumn != null ? existingColumn.edit() : Column.editor().name(columnName); AtomicBoolean isPrimaryKey = new AtomicBoolean(false); if (tokens.matches("WITH", "OPTIONS")) { parseColumnOptions(start, columnName, tokens, column); } else { parseColumnDefinition(start, columnName, tokens, table, column, isPrimaryKey); } // Update the table ... Column newColumnDefn = column.create(); table.addColumns(newColumnDefn); if (isPrimaryKey.get()) { table.setPrimaryKeyNames(newColumnDefn.name()); } } }
@Test public void shouldFindNonExistingColumnByNameIndependentOfCase() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).position(1).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).position(1).create(); editor.addColumns(c1, c2, c3); editor.columns().forEach(col -> { assertThat(editor.columnWithName(col.name())).isNotNull(); assertThat(editor.columnWithName(col.name().toUpperCase())).isNotNull(); assertThat(editor.columnWithName(col.name().toLowerCase())).isNotNull(); }); assertThat(editor.columnWithName("WOOPS")).isNull(); }
@Test(expected = IllegalArgumentException.class) public void shouldNotAllowAddingPrimaryKeyColumnWhenNotFound() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).position(1).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).position(1).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1", "WOOPS"); }
@Test(expected = IllegalArgumentException.class) public void shouldNotReorderColumnIfNameDoesNotMatch() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.reorderColumn("WOOPS", "C2"); assertValidPositions(editor); }
@Test public void shouldFindGeneratedColumns() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).generated(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).generated(true).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1"); table = editor.create(); assertThat(table.retrieveColumnNames()).containsExactly("C1", "C2", "C3"); table.columns().forEach(col -> { assertThat(table.isGenerated(col.name())).isEqualTo(col.isGenerated()); }); assertValidPositions(editor); }
@Test public void shouldFindAutoIncrementedColumns() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1"); table = editor.create(); assertThat(table.retrieveColumnNames()).containsExactly("C1", "C2", "C3"); table.columns().forEach(col -> { assertThat(table.isAutoIncremented(col.name())).isEqualTo(col.isAutoIncremented()); }); assertValidPositions(editor); }
@Test public void shouldRemoveColumnByName() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.removeColumn("C2"); assertThat(editor.columns()).containsExactly(editor.columnWithName("C1"), editor.columnWithName("C3")); assertValidPositions(editor); }
/** * Add one columns to this table, regardless of the {@link Column#position() position} of the supplied * columns. However, if an existing column definition matches a supplied column, the new column definition will replace * the existing column definition. * * @param column the definition for the column to be added * @return this editor so callers can chain methods together */ default TableEditor addColumn(Column column) { return addColumns(column); }
@Before public void beforeEach() { table = Table.editor() .tableId(id) .addColumns(Column.editor().name("C1") .type("VARCHAR").jdbcType(Types.VARCHAR).length(10) .generated(true) .optional(false) .create(), Column.editor().name("C2") .type("NUMBER").jdbcType(Types.NUMERIC).length(5) .optional(false) .create(), Column.editor().name("C3") .type("DATE").jdbcType(Types.DATE).length(4) .optional(true) .create(), Column.editor().name("C4") .type("COUNTER").jdbcType(Types.INTEGER) .autoIncremented(true) .optional(true) .create()) .setPrimaryKeyNames("C1", "C2") .create(); c1 = table.columnWithName("C1"); c2 = table.columnWithName("C2"); c3 = table.columnWithName("C3"); c4 = table.columnWithName("C4"); }
@Test public void shouldAllowAddingPrimaryKeyColumnWhenFound() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).position(1).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).position(1).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1"); c1 = editor.columnWithName(c1.name()); c2 = editor.columnWithName(c2.name()); c3 = editor.columnWithName(c3.name()); assertThat(c1.position()).isEqualTo(1); assertThat(c2.position()).isEqualTo(2); assertThat(c3.position()).isEqualTo(3); table = editor.create(); assertThat(table.retrieveColumnNames()).containsExactly("C1", "C2", "C3"); assertThat(table.columns()).containsExactly(c1, c2, c3); assertThat(table.primaryKeyColumnNames()).containsOnly("C1"); assertValidPositions(editor); }
table = Table.editor() .tableId(id) .addColumns(Column.editor().name("C1") .type("VARCHAR").jdbcType(Types.VARCHAR).length(10) .optional(false)
Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); assertValidPositions(editor); editor.reorderColumn("C1", null);
protected void parseTableElement(Marker start, TableEditor table) { if (tokens.matchesAnyOf("CONSTRAINT", "UNIQUE", "PRIMARY", "FOREIGN", "CHECK")) { parseTableConstraintDefinition(start, table); } else if (tokens.matches("LIKE")) { parseTableLikeClause(start, table); } else if (tokens.matches("REF", "IS")) { parseSelfReferencingColumnSpec(start, table); } else { // Obtain the column editor ... String columnName = tokens.consume(); Column existingColumn = table.columnWithName(columnName); ColumnEditor column = existingColumn != null ? existingColumn.edit() : Column.editor().name(columnName); AtomicBoolean isPrimaryKey = new AtomicBoolean(false); if (tokens.matches("WITH", "OPTIONS")) { parseColumnOptions(start, columnName, tokens, column); } else { parseColumnDefinition(start, columnName, tokens, table, column, isPrimaryKey); } // Update the table ... Column newColumnDefn = column.create(); table.addColumns(newColumnDefn); if (isPrimaryKey.get()) { table.setPrimaryKeyNames(newColumnDefn.name()); } } }