Search in sources :

Example 1 with TableId

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;
}
Also used : TableId(io.debezium.relational.TableId) ResultSet(java.sql.ResultSet) DatabaseMetaData(java.sql.DatabaseMetaData) HashSet(java.util.HashSet)

Example 2 with TableId

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);
    }
}
Also used : TableId(io.debezium.relational.TableId) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) ColumnEditor(io.debezium.relational.ColumnEditor) DatabaseMetaData(java.sql.DatabaseMetaData) Column(io.debezium.relational.Column) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashSet(java.util.HashSet)

Example 3 with TableId

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;
}
Also used : TableId(io.debezium.relational.TableId) LinkedList(java.util.LinkedList)

Example 4 with TableId

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);
}
Also used : TableId(io.debezium.relational.TableId) Table(io.debezium.relational.Table) Test(org.junit.Test)

Example 5 with TableId

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);
    }
}
Also used : TableId(io.debezium.relational.TableId)

Aggregations

TableId (io.debezium.relational.TableId)63 Table (io.debezium.relational.Table)39 Test (org.junit.Test)34 FixFor (io.debezium.doc.FixFor)18 Column (io.debezium.relational.Column)7 TableEditor (io.debezium.relational.TableEditor)7 ArrayList (java.util.ArrayList)4 ConnectException (org.apache.kafka.connect.errors.ConnectException)4 TableSchema (io.debezium.relational.TableSchema)3 ParsingException (io.debezium.text.ParsingException)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 HashSet (java.util.HashSet)3 List (java.util.List)3 SourceRecord (org.apache.kafka.connect.source.SourceRecord)3 Predicates (io.debezium.function.Predicates)2 ColumnEditor (io.debezium.relational.ColumnEditor)2 Marker (io.debezium.text.TokenStream.Marker)2 Strings (io.debezium.util.Strings)2 Connection (java.sql.Connection)2