/** * Utility method to validate that two given {@link SourceRecord} values are identical. * @param actual actual value stored on the source record * @param expected expected value stored on the source record */ public static void assertSameValue(Object actual, Object expected) { if(expected instanceof Double || expected instanceof Float || expected instanceof BigDecimal) { // Value should be within 1% double expectedNumericValue = ((Number)expected).doubleValue(); double actualNumericValue = ((Number)actual).doubleValue(); assertThat(actualNumericValue).isEqualTo(expectedNumericValue, Delta.delta(0.01d*expectedNumericValue)); } else if (expected instanceof Integer || expected instanceof Long || expected instanceof Short) { long expectedNumericValue = ((Number)expected).longValue(); long actualNumericValue = ((Number)actual).longValue(); assertThat(actualNumericValue).isEqualTo(expectedNumericValue); } else if (expected instanceof Boolean) { boolean expectedValue = (Boolean) expected; boolean actualValue = (Boolean) actual; assertThat(actualValue).isEqualTo(expectedValue); } else { assertThat(actual).isEqualTo(expected); } }
protected void assertColumn(Table table, String name, String typeName, int jdbcType, int length, int scale, boolean optional, boolean generated, boolean autoIncremented ) { Column column = table.columnWithName(name); assertThat(column.name()).isEqualTo(name); assertThat(column.typeName()).isEqualTo(typeName); assertThat(column.jdbcType()).isEqualTo(jdbcType); assertThat(column.length()).isEqualTo(length); if (scale == Column.UNSET_INT_VALUE) { assertFalse(column.scale().isPresent()); } else { assertThat(column.scale().get()).isEqualTo(scale); } assertThat(column.isOptional()).isEqualTo(optional); assertThat(column.isGenerated()).isEqualTo(generated); assertThat(column.isAutoIncremented()).isEqualTo(autoIncremented); }
@Test @FixFor("DBZ-860") public void shouldTreatPrimaryKeyColumnsImplicitlyAsNonNull() { String ddl = "CREATE TABLE data(id INT, PRIMARY KEY (id))" + "CREATE TABLE datadef(id INT DEFAULT 0, PRIMARY KEY (id))"; parser.parse(ddl, tables); Table table = tables.forTable(new TableId(null, null, "data")); assertThat(table.columnWithName("id").isOptional()).isEqualTo(false); assertThat(table.columnWithName("id").hasDefaultValue()).isEqualTo(false); Table tableDef = tables.forTable(new TableId(null, null, "datadef")); assertThat(tableDef.columnWithName("id").isOptional()).isEqualTo(false); assertThat(tableDef.columnWithName("id").hasDefaultValue()).isEqualTo(true); assertThat(tableDef.columnWithName("id").defaultValue()).isEqualTo(0); ddl = "CREATE TABLE data(id INT DEFAULT 1, PRIMARY KEY (id))"; parser.parse(ddl, tables); table = tables.forTable(new TableId(null, null, "data")); assertThat(table.columnWithName("id").isOptional()).isEqualTo(false); assertThat(table.columnWithName("id").hasDefaultValue()).isEqualTo(true); assertThat(table.columnWithName("id").defaultValue()).isEqualTo(1); }
protected void assertColumn(Table table, String name, String typeName, int jdbcType, int length, int scale, boolean optional, boolean generated, boolean autoIncremented) { Column column = table.columnWithName(name); assertThat(column.name()).isEqualTo(name); assertThat(column.typeName()).isEqualTo(typeName); assertThat(column.jdbcType()).isEqualTo(jdbcType); assertThat(column.length()).isEqualTo(length); if (scale == Column.UNSET_INT_VALUE) { assertFalse(column.scale().isPresent()); } else { assertThat(column.scale().get()).isEqualTo(scale); } assertThat(column.isOptional()).isEqualTo(optional); assertThat(column.isGenerated()).isEqualTo(generated); assertThat(column.isAutoIncremented()).isEqualTo(autoIncremented); }
@Test public void shouldCreateTaskFromConfigurationWithWhenNeededSnapshotMode() throws Exception { config = simpleConfig().with(MySqlConnectorConfig.SNAPSHOT_MODE, SnapshotMode.WHEN_NEEDED) .build(); context = new MySqlTaskContext(config, new Filters.Builder(config).build(), false, null); context.start(); assertThat("" + context.snapshotMode().getValue()).isEqualTo(SnapshotMode.WHEN_NEEDED.getValue()); assertThat(context.isSnapshotAllowedWhenNeeded()).isEqualTo(true); assertThat(context.isSnapshotNeverAllowed()).isEqualTo(false); }
@Test public void shouldCreateTaskFromConfigurationWithNeverSnapshotMode() throws Exception { config = simpleConfig().with(MySqlConnectorConfig.SNAPSHOT_MODE, SnapshotMode.NEVER) .build(); context = new MySqlTaskContext(config, new Filters.Builder(config).build(), false, null); context.start(); assertThat("" + context.snapshotMode().getValue()).isEqualTo(SnapshotMode.NEVER.getValue()); assertThat(context.isSnapshotAllowedWhenNeeded()).isEqualTo(false); assertThat(context.isSnapshotNeverAllowed()).isEqualTo(true); }
protected void assertFieldSchema(Document doc, String fieldName, Schema.Type type, boolean optional) { assertThat(doc.getString("field")).isEqualTo(fieldName); assertThat(doc.getString("type")).isEqualToIgnoringCase(type.name()); assertThat(doc.getBoolean("optional")).isEqualTo(optional); }
@Test public void shouldReturnRecordedOffsetForUsedReplicaNameDuringInitialSync() { source.startInitialSync(REPLICA_SET_NAME); Document event = new Document().append("ts", new BsonTimestamp(100, 2)) .append("h", Long.valueOf(1987654321)) .append("ns", "dbA.collectA"); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); source.offsetStructForEvent(REPLICA_SET_NAME, event); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(true); Map<String, ?> offset = source.lastOffset(REPLICA_SET_NAME); assertThat(offset.get(SourceInfo.TIMESTAMP)).isEqualTo(100); assertThat(offset.get(SourceInfo.ORDER)).isEqualTo(2); assertThat(offset.get(SourceInfo.OPERATION_ID)).isEqualTo(1987654321L); BsonTimestamp ts = source.lastOffsetTimestamp(REPLICA_SET_NAME); assertThat(ts.getTime()).isEqualTo(100); assertThat(ts.getInc()).isEqualTo(2); Struct struct = source.lastOffsetStruct(REPLICA_SET_NAME,new CollectionId(REPLICA_SET_NAME,"dbA","collectA")); assertThat(struct.getInt32(SourceInfo.TIMESTAMP)).isEqualTo(100); assertThat(struct.getInt32(SourceInfo.ORDER)).isEqualTo(2); assertThat(struct.getInt64(SourceInfo.OPERATION_ID)).isEqualTo(1987654321L); assertThat(struct.getString(SourceInfo.NAMESPACE)).isEqualTo("dbA.collectA"); assertThat(struct.getString(SourceInfo.REPLICA_SET_NAME)).isEqualTo(REPLICA_SET_NAME); assertThat(struct.getString(SourceInfo.SERVER_NAME)).isEqualTo("serverX"); assertThat(struct.getBoolean(SourceInfo.INITIAL_SYNC)).isEqualTo(true); }
@Test public void shouldReturnOffsetForUnusedReplicaNameDuringInitialSync() { source.startInitialSync(REPLICA_SET_NAME); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); Map<String, ?> offset = source.lastOffset(REPLICA_SET_NAME); assertThat(offset.get(SourceInfo.TIMESTAMP)).isEqualTo(0); assertThat(offset.get(SourceInfo.ORDER)).isEqualTo(0); assertThat(offset.get(SourceInfo.OPERATION_ID)).isNull(); BsonTimestamp ts = source.lastOffsetTimestamp(REPLICA_SET_NAME); assertThat(ts.getTime()).isEqualTo(0); assertThat(ts.getInc()).isEqualTo(0); Struct struct = source.lastOffsetStruct(REPLICA_SET_NAME,new CollectionId(REPLICA_SET_NAME,"dbA","collectA")); assertThat(struct.getInt32(SourceInfo.TIMESTAMP)).isEqualTo(0); assertThat(struct.getInt32(SourceInfo.ORDER)).isEqualTo(0); assertThat(struct.getInt64(SourceInfo.OPERATION_ID)).isNull(); assertThat(struct.getString(SourceInfo.NAMESPACE)).isEqualTo("dbA.collectA"); assertThat(struct.getString(SourceInfo.REPLICA_SET_NAME)).isEqualTo(REPLICA_SET_NAME); assertThat(struct.getString(SourceInfo.SERVER_NAME)).isEqualTo("serverX"); assertThat(struct.getBoolean(SourceInfo.INITIAL_SYNC)).isEqualTo(true); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); }
@Test public void shouldReturnRecordedOffsetForUsedReplicaName() { Document event = new Document().append("ts", new BsonTimestamp(100, 2)) .append("h", Long.valueOf(1987654321)) .append("ns", "dbA.collectA"); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); source.offsetStructForEvent(REPLICA_SET_NAME, event); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(true); Map<String, ?> offset = source.lastOffset(REPLICA_SET_NAME); assertThat(offset.get(SourceInfo.TIMESTAMP)).isEqualTo(100); assertThat(offset.get(SourceInfo.ORDER)).isEqualTo(2); assertThat(offset.get(SourceInfo.OPERATION_ID)).isEqualTo(1987654321L); BsonTimestamp ts = source.lastOffsetTimestamp(REPLICA_SET_NAME); assertThat(ts.getTime()).isEqualTo(100); assertThat(ts.getInc()).isEqualTo(2); Struct struct = source.lastOffsetStruct(REPLICA_SET_NAME,new CollectionId(REPLICA_SET_NAME,"dbA","collectA")); assertThat(struct.getInt32(SourceInfo.TIMESTAMP)).isEqualTo(100); assertThat(struct.getInt32(SourceInfo.ORDER)).isEqualTo(2); assertThat(struct.getInt64(SourceInfo.OPERATION_ID)).isEqualTo(1987654321L); assertThat(struct.getString(SourceInfo.NAMESPACE)).isEqualTo("dbA.collectA"); assertThat(struct.getString(SourceInfo.REPLICA_SET_NAME)).isEqualTo(REPLICA_SET_NAME); assertThat(struct.getString(SourceInfo.SERVER_NAME)).isEqualTo("serverX"); assertThat(struct.getBoolean(SourceInfo.INITIAL_SYNC)).isNull(); }
@Test public void shouldReturnOffsetForUnusedReplicaName() { assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); Map<String, ?> offset = source.lastOffset(REPLICA_SET_NAME); assertThat(offset.get(SourceInfo.TIMESTAMP)).isEqualTo(0); assertThat(offset.get(SourceInfo.ORDER)).isEqualTo(0); assertThat(offset.get(SourceInfo.OPERATION_ID)).isNull(); BsonTimestamp ts = source.lastOffsetTimestamp(REPLICA_SET_NAME); assertThat(ts.getTime()).isEqualTo(0); assertThat(ts.getInc()).isEqualTo(0); Struct struct = source.lastOffsetStruct(REPLICA_SET_NAME,new CollectionId(REPLICA_SET_NAME,"dbA","collectA")); assertThat(struct.getInt32(SourceInfo.TIMESTAMP)).isEqualTo(0); assertThat(struct.getInt32(SourceInfo.ORDER)).isEqualTo(0); assertThat(struct.getInt64(SourceInfo.OPERATION_ID)).isNull(); assertThat(struct.getString(SourceInfo.NAMESPACE)).isEqualTo("dbA.collectA"); assertThat(struct.getString(SourceInfo.REPLICA_SET_NAME)).isEqualTo(REPLICA_SET_NAME); assertThat(struct.getString(SourceInfo.SERVER_NAME)).isEqualTo("serverX"); assertThat(struct.getBoolean(SourceInfo.INITIAL_SYNC)).isNull(); assertThat(source.hasOffset(REPLICA_SET_NAME)).isEqualTo(false); }
@Test public void parseUnsignedBigIntDefaultValueToLong() { String sql = "CREATE TABLE UNSIGNED_BIGINT_TABLE (\n" + " A BIGINT UNSIGNED NULL DEFAULT 0,\n" + " B BIGINT UNSIGNED NULL DEFAULT '10',\n" + " C BIGINT UNSIGNED NULL,\n" + " D BIGINT UNSIGNED NOT NULL,\n" + " E BIGINT UNSIGNED NOT NULL DEFAULT 0,\n" + " F BIGINT UNSIGNED NOT NULL DEFAULT '0'\n" + ");"; parser.parse(sql, tables); Table table = tables.forTable(new TableId(null, null, "UNSIGNED_BIGINT_TABLE")); assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L); assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L); assertThat(table.columnWithName("C").isOptional()).isEqualTo(true); assertThat(table.columnWithName("C").hasDefaultValue()).isTrue(); assertThat(table.columnWithName("D").isOptional()).isEqualTo(false); assertThat(table.columnWithName("D").hasDefaultValue()).isFalse(); assertThat(table.columnWithName("E").isOptional()).isEqualTo(false); assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L); assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L); }
@Test public void parseUnsignedIntDefaultValue() { String sql = "CREATE TABLE UNSIGNED_INT_TABLE (\n" + " A INT UNSIGNED NULL DEFAULT 0,\n" + " B INT UNSIGNED NULL DEFAULT '10',\n" + " C INT UNSIGNED NULL,\n" + " D INT UNSIGNED NOT NULL,\n" + " E INT UNSIGNED NOT NULL DEFAULT 0,\n" + " F INT UNSIGNED NOT NULL DEFAULT '0',\n" + " G INT UNSIGNED NOT NULL DEFAULT '4294967295'\n" + ");"; parser.parse(sql, tables); Table table = tables.forTable(new TableId(null, null, "UNSIGNED_INT_TABLE")); assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L); assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L); assertThat(table.columnWithName("C").isOptional()).isEqualTo(true); assertThat(table.columnWithName("C").hasDefaultValue()).isTrue(); assertThat(table.columnWithName("D").isOptional()).isEqualTo(false); assertThat(table.columnWithName("D").hasDefaultValue()).isFalse(); assertThat(table.columnWithName("E").isOptional()).isEqualTo(false); assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L); assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L); assertThat(table.columnWithName("G").defaultValue()).isEqualTo(4294967295L); }
protected void assertColumn(Table table, String name, String typeName, int jdbcType, int length, String charsetName, boolean optional) { Column column = table.columnWithName(name); assertThat(column.name()).isEqualTo(name); assertThat(column.typeName()).isEqualTo(typeName); assertThat(column.jdbcType()).isEqualTo(jdbcType); assertThat(column.length()).isEqualTo(length); assertThat(column.charsetName()).isEqualTo(charsetName); assertFalse(column.scale().isPresent()); assertThat(column.isOptional()).isEqualTo(optional); assertThat(column.isGenerated()).isFalse(); assertThat(column.isAutoIncremented()).isFalse(); }
@Test public void parseUnsignedSmallintDefaultValue() { String sql = "CREATE TABLE UNSIGNED_SMALLINT_TABLE (\n" + " A SMALLINT UNSIGNED NULL DEFAULT 0,\n" + " B SMALLINT UNSIGNED NULL DEFAULT '10',\n" + " C SMALLINT UNSIGNED NULL,\n" + " D SMALLINT UNSIGNED NOT NULL,\n" + " E SMALLINT UNSIGNED NOT NULL DEFAULT 0,\n" + " F SMALLINT UNSIGNED NOT NULL DEFAULT '0',\n" + " G SMALLINT UNSIGNED NOT NULL DEFAULT '65535'\n" + ");"; parser.parse(sql, tables); Table table = tables.forTable(new TableId(null, null, "UNSIGNED_SMALLINT_TABLE")); assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10); assertThat(table.columnWithName("C").isOptional()).isEqualTo(true); assertThat(table.columnWithName("C").hasDefaultValue()).isTrue(); assertThat(table.columnWithName("D").isOptional()).isEqualTo(false); assertThat(table.columnWithName("D").hasDefaultValue()).isFalse(); assertThat(table.columnWithName("E").isOptional()).isEqualTo(false); assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("G").defaultValue()).isEqualTo(65535); }
@Test public void parseUnsignedMediumintDefaultValue() { String sql = "CREATE TABLE UNSIGNED_MEDIUMINT_TABLE (\n" + " A MEDIUMINT UNSIGNED NULL DEFAULT 0,\n" + " B MEDIUMINT UNSIGNED NULL DEFAULT '10',\n" + " C MEDIUMINT UNSIGNED NULL,\n" + " D MEDIUMINT UNSIGNED NOT NULL,\n" + " E MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,\n" + " F MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',\n" + " G MEDIUMINT UNSIGNED NOT NULL DEFAULT '16777215'\n" + ");"; parser.parse(sql, tables); Table table = tables.forTable(new TableId(null, null, "UNSIGNED_MEDIUMINT_TABLE")); assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10); assertThat(table.columnWithName("C").isOptional()).isEqualTo(true); assertThat(table.columnWithName("C").hasDefaultValue()).isTrue(); assertThat(table.columnWithName("D").isOptional()).isEqualTo(false); assertThat(table.columnWithName("D").hasDefaultValue()).isFalse(); assertThat(table.columnWithName("E").isOptional()).isEqualTo(false); assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0); assertThat(table.columnWithName("G").defaultValue()).isEqualTo(16777215); }
@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 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 parseDefaultValue() { String ddl = "CREATE TABLE tmp (id INT NOT NULL, " + "columnA CHAR(60) NOT NULL DEFAULT 'A'," + "columnB INT NOT NULL DEFAULT 1," + "columnC VARCHAR(10) NULL DEFAULT 'C'," + "columnD VARCHAR(10) NULL DEFAULT NULL," + "columnE VARCHAR(10) NOT NULL," + "my_date datetime NOT NULL DEFAULT '2018-04-27 13:28:43');"; parser.parse(ddl, tables); Table table = tables.forTable(new TableId(null, null, "tmp")); assertThat(table.columnWithName("id").isOptional()).isEqualTo(false); assertThat(table.columnWithName("columnA").defaultValue()).isEqualTo("A"); assertThat(table.columnWithName("columnB").defaultValue()).isEqualTo(1); assertThat(table.columnWithName("columnC").defaultValue()).isEqualTo("C"); assertThat(table.columnWithName("columnD").defaultValue()).isEqualTo(null); assertThat(table.columnWithName("columnE").defaultValue()).isEqualTo(null); }
protected void assertField(Field field, String fieldName, Schema expectedSchema, boolean optional) { assertThat(field.name()).isEqualTo(fieldName); Schema schema = field.schema(); assertThat(schema.name()).isEqualTo(expectedSchema.name()); assertThat(schema.doc()).isEqualTo(expectedSchema.doc()); assertThat(schema.parameters()).isEqualTo(expectedSchema.parameters()); assertThat(schema.version()).isEqualTo(expectedSchema.version()); assertThat(schema.isOptional()).isEqualTo(optional); switch (expectedSchema.type()) { case STRUCT: for (Field f : expectedSchema.fields()) { assertField(schema.field(f.name()),f.name(),f.schema(),f.schema().isOptional()); } break; default: } }