use of io.debezium.relational.TableId in project debezium by debezium.
the class JdbcConnection method readTableNames.
/**
* Get the identifiers of the tables.
*
* @param databaseCatalog the name of the catalog, which is typically the database name; may be an empty string for tables
* that have no catalog, or {@code null} if the catalog name should not be used to narrow the list of table
* identifiers
* @param schemaNamePattern the pattern used to match database schema names, which may be "" to match only those tables with
* no schema or {@code null} if the schema name should not be used to narrow the list of table
* identifiers
* @param tableNamePattern the pattern used to match database table names, which may be null to match all table names
* @param tableTypes the set of table types to include in the results, which may be null for all table types
* @return the set of {@link TableId}s; never null but possibly empty
* @throws SQLException if an error occurs while accessing the database metadata
*/
public Set<TableId> readTableNames(String databaseCatalog, String schemaNamePattern, String tableNamePattern, String[] tableTypes) throws SQLException {
if (tableNamePattern == null)
tableNamePattern = "%";
Set<TableId> tableIds = new HashSet<>();
DatabaseMetaData metadata = connection().getMetaData();
try (ResultSet rs = metadata.getTables(databaseCatalog, schemaNamePattern, tableNamePattern, tableTypes)) {
while (rs.next()) {
String catalogName = rs.getString(1);
String schemaName = rs.getString(2);
String tableName = rs.getString(3);
TableId tableId = new TableId(catalogName, schemaName, tableName);
tableIds.add(tableId);
}
}
return tableIds;
}
use of io.debezium.relational.TableId in project debezium by debezium.
the class JdbcConnection method readSchema.
/**
* Create definitions for each tables in the database, given the catalog name, schema pattern, table filter, and
* column filter.
*
* @param tables the set of table definitions to be modified; may not be null
* @param databaseCatalog the name of the catalog, which is typically the database name; may be null if all accessible
* databases are to be processed
* @param schemaNamePattern the pattern used to match database schema names, which may be "" to match only those tables with
* no schema or null to process all accessible tables regardless of database schema name
* @param tableFilter used to determine for which tables are to be processed; may be null if all accessible tables are to be
* processed
* @param columnFilter used to determine which columns should be included as fields in its table's definition; may
* be null if all columns for all tables are to be included
* @param removeTablesNotFoundInJdbc {@code true} if this method should remove from {@code tables} any definitions for tables
* that are not found in the database metadata, or {@code false} if such tables should be left untouched
* @throws SQLException if an error occurs while accessing the database metadata
*/
public void readSchema(Tables tables, String databaseCatalog, String schemaNamePattern, TableNameFilter tableFilter, ColumnNameFilter columnFilter, boolean removeTablesNotFoundInJdbc) throws SQLException {
// Before we make any changes, get the copy of the set of table IDs ...
Set<TableId> tableIdsBefore = new HashSet<>(tables.tableIds());
// Read the metadata for the table columns ...
DatabaseMetaData metadata = connection().getMetaData();
// Find views as they cannot be snapshotted
final Set<TableId> viewIds = new HashSet<>();
try (final ResultSet rs = metadata.getTables(databaseCatalog, schemaNamePattern, null, new String[] { "VIEW" })) {
while (rs.next()) {
final String catalogName = rs.getString(1);
final String schemaName = rs.getString(2);
final String tableName = rs.getString(3);
viewIds.add(new TableId(catalogName, schemaName, tableName));
}
}
ConcurrentMap<TableId, List<Column>> columnsByTable = new ConcurrentHashMap<>();
try (ResultSet rs = metadata.getColumns(databaseCatalog, schemaNamePattern, null, null)) {
while (rs.next()) {
String catalogName = rs.getString(1);
String schemaName = rs.getString(2);
String tableName = rs.getString(3);
TableId tableId = new TableId(catalogName, schemaName, tableName);
if (viewIds.contains(tableId)) {
continue;
}
if (tableFilter == null || tableFilter.matches(catalogName, schemaName, tableName)) {
List<Column> cols = columnsByTable.computeIfAbsent(tableId, name -> new ArrayList<>());
String columnName = rs.getString(4);
if (columnFilter == null || columnFilter.matches(catalogName, schemaName, tableName, columnName)) {
ColumnEditor column = Column.editor().name(columnName);
column.jdbcType(rs.getInt(5));
column.type(rs.getString(6));
column.length(rs.getInt(7));
column.scale(rs.getInt(9));
column.optional(isNullable(rs.getInt(11)));
column.position(rs.getInt(17));
column.autoIncremented("YES".equalsIgnoreCase(rs.getString(23)));
String autogenerated = null;
try {
autogenerated = rs.getString(24);
} catch (SQLException e) {
// ignore, some drivers don't have this index - e.g. Postgres
}
column.generated("YES".equalsIgnoreCase(autogenerated));
column.nativeType(resolveNativeType(column.typeName()));
cols.add(column.create());
}
}
}
}
// Read the metadata for the primary keys ...
for (TableId id : columnsByTable.keySet()) {
// First get the primary key information, which must be done for *each* table ...
List<String> pkColumnNames = null;
try (ResultSet rs = metadata.getPrimaryKeys(id.catalog(), id.schema(), id.table())) {
while (rs.next()) {
if (pkColumnNames == null)
pkColumnNames = new ArrayList<>();
String columnName = rs.getString(4);
int columnIndex = rs.getInt(5);
Collect.set(pkColumnNames, columnIndex - 1, columnName, null);
}
}
// Then define the table ...
List<Column> columns = columnsByTable.get(id);
Collections.sort(columns);
// JDBC does not expose character sets
String defaultCharsetName = null;
tables.overwriteTable(id, columns, pkColumnNames, defaultCharsetName);
}
if (removeTablesNotFoundInJdbc) {
// Remove any definitions for tables that were not found in the database metadata ...
tableIdsBefore.removeAll(columnsByTable.keySet());
tableIdsBefore.forEach(tables::removeTable);
}
}
use of io.debezium.relational.TableId in project debezium by debezium.
the class DdlParser method parseQualifiedTableNames.
/**
* Parse the next tokens for one or more comma-separated qualified table names. This method uses the schema name that appears
* in the
* token stream, or if none is found the {@link #currentSchema()}, and then calls {@link #resolveTableId(String, String)} with
* the values.
*
* @param start the start of the statement
* @return the resolved {@link TableId}
*/
protected List<TableId> parseQualifiedTableNames(Marker start) {
List<TableId> ids = new LinkedList<>();
TableId id = parseQualifiedTableName(start);
if (id != null)
ids.add(id);
while (tokens.canConsume(',')) {
id = parseQualifiedTableName(start);
if (id != null)
ids.add(id);
}
return ids;
}
use of io.debezium.relational.TableId in project debezium by debezium.
the class DdlParserSql2003Test method shouldParseCreateTableStatementWithSingleGeneratedColumnAsPrimaryKey.
@Test
public void shouldParseCreateTableStatementWithSingleGeneratedColumnAsPrimaryKey() {
String ddl = "CREATE TABLE my.foo ( " + System.lineSeparator() + " c1 INTEGER GENERATED ALWAYS AS IDENTITY NOT NULL, " + System.lineSeparator() + " c2 VARCHAR(22), " + System.lineSeparator() + " PRIMARY KEY (c1)" + System.lineSeparator() + "); " + System.lineSeparator();
parser.parse(ddl, tables);
assertThat(tables.size()).isEqualTo(1);
Table foo = tables.forTable(new TableId("my", null, "foo"));
assertThat(foo).isNotNull();
assertThat(foo.columnNames()).containsExactly("c1", "c2");
assertThat(foo.primaryKeyColumnNames()).containsExactly("c1");
assertColumn(foo, "c1", "INTEGER", Types.INTEGER, -1, -1, false, true, true);
assertColumn(foo, "c2", "VARCHAR", Types.VARCHAR, 22, -1, true, false, false);
parser.parse("DROP TABLE my.foo", tables);
assertThat(tables.size()).isEqualTo(0);
}
use of io.debezium.relational.TableId in project debezium by debezium.
the class KeyValueStore method add.
public void add(SourceRecord record) {
TableId tableId = tableIdFromTopic.apply(record.topic());
if (tableId != null) {
this.sourceRecords.add(record);
getOrCreate(tableId).add(record);
}
}
Aggregations