/** * Verify that the given {@link SourceRecord} is a {@link Operation#DELETE DELETE} record without PK. * matches the expected value. * * @param record the source record; may not be null * @param pkField the single field defining the primary key of the struct; may not be null * @param pk the expected integer value of the primary key in the struct */ public static void isValidDelete(SourceRecord record) { isValidDelete(record, false); }
protected void assertDelete(SourceRecord record, String pkField, int pk) { VerifyRecord.isValidDelete(record, pkField, pk); }
/** * Verify that the given {@link SourceRecord} is a {@link Operation#DELETE DELETE} record, and that the integer key * matches the expected value. * * @param record the source record; may not be null * @param pkField the single field defining the primary key of the struct; may not be null * @param pk the expected integer value of the primary key in the struct */ public static void isValidDelete(SourceRecord record, String pkField, int pk) { hasValidKey(record, pkField, pk); isValidDelete(record, true); }
@Test public void shouldReceiveChangesForDeletes() throws Exception { // add a new entry and remove both String statements = "INSERT INTO test_table (text) VALUES ('insert2');" + "DELETE FROM test_table WHERE pk > 0;"; consumer = testConsumer(5); recordsProducer.start(consumer, blackHole); executeAndWait(statements); String topicPrefix = "public.test_table"; String topicName = topicName(topicPrefix); assertRecordInserted(topicPrefix, PK_FIELD, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, PK_FIELD, 1); // second entry removed record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, PK_FIELD, 2); }
@Test public void shouldReceiveChangesForUpdatesWithPKChanges() throws Exception { consumer = testConsumer(3); recordsProducer.start(consumer, blackHole); executeAndWait("UPDATE test_table SET text = 'update', pk = 2"); String topicName = topicName("public.test_table"); // first should be a delete of the old pk SourceRecord deleteRecord = consumer.remove(); assertEquals(topicName, deleteRecord.topic()); VerifyRecord.isValidDelete(deleteRecord, PK_FIELD, 1); // followed by a tombstone of the old pk SourceRecord tombstoneRecord = consumer.remove(); assertEquals(topicName, tombstoneRecord.topic()); VerifyRecord.isValidTombstone(tombstoneRecord, PK_FIELD, 1); // and finally insert of the new value SourceRecord insertRecord = consumer.remove(); assertEquals(topicName, insertRecord.topic()); VerifyRecord.isValidInsert(insertRecord, PK_FIELD, 2); }
@Test @FixFor("DBZ-582") public void shouldReceiveChangesForDeletesWithoutTombstone() throws Exception { PostgresConnectorConfig config = new PostgresConnectorConfig(TestHelper.defaultConfig() .with(PostgresConnectorConfig.INCLUDE_UNKNOWN_DATATYPES, true) .with(CommonConnectorConfig.TOMBSTONES_ON_DELETE, false) .build() ); setupRecordsProducer(config); // add a new entry and remove both String statements = "INSERT INTO test_table (text) VALUES ('insert2');" + "DELETE FROM test_table WHERE pk > 0;"; consumer = testConsumer(3); recordsProducer.start(consumer, blackHole); executeAndWait(statements); String topicPrefix = "public.test_table"; String topicName = topicName(topicPrefix); assertRecordInserted(topicPrefix, PK_FIELD, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); // second entry removed record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2); }
@Test @FixFor("DBZ-259") public void shouldProcessIntervalDelete() throws Exception { final String statements = "INSERT INTO table_with_interval VALUES (default, 'Foo', default);" + "INSERT INTO table_with_interval VALUES (default, 'Bar', default);" + "DELETE FROM table_with_interval WHERE id = 1;"; consumer = testConsumer(4); recordsProducer.start(consumer, blackHole); executeAndWait(statements); final String topicPrefix = "public.table_with_interval"; final String topicName = topicName(topicPrefix); final String pk = "id"; assertRecordInserted(topicPrefix, pk, 1); assertRecordInserted(topicPrefix, pk, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, pk, 1); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, pk, 1); }
@Test @FixFor("DBZ-582") public void shouldReceiveChangesForUpdatesWithPKChangesWithoutTombstone() throws Exception { PostgresConnectorConfig config = new PostgresConnectorConfig(TestHelper.defaultConfig() .with(PostgresConnectorConfig.INCLUDE_UNKNOWN_DATATYPES, true) .with(CommonConnectorConfig.TOMBSTONES_ON_DELETE, false) .build() ); setupRecordsProducer(config); consumer = testConsumer(2); recordsProducer.start(consumer, blackHole); executeAndWait("UPDATE test_table SET text = 'update', pk = 2"); String topicName = topicName("public.test_table"); // first should be a delete of the old pk SourceRecord deleteRecord = consumer.remove(); assertEquals(topicName, deleteRecord.topic()); VerifyRecord.isValidDelete(deleteRecord, PK_FIELD, 1); // followed by insert of the new value SourceRecord insertRecord = consumer.remove(); assertEquals(topicName, insertRecord.topic()); VerifyRecord.isValidInsert(insertRecord, PK_FIELD, 2); }
SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2);
executeAndWait("DELETE FROM test_table WHERE id=1"); SourceRecord deletedRecord = consumer.remove(); VerifyRecord.isValidDelete(deletedRecord);
protected void assertDelete(SourceRecord record, String pkField, int pk) { VerifyRecord.isValidDelete(record, pkField, pk); }
@Test public void shouldReceiveChangesForDeletes() throws Exception { // add a new entry and remove both String statements = "INSERT INTO test_table (text) VALUES ('insert2');" + "DELETE FROM test_table WHERE pk > 0;"; consumer = testConsumer(5); recordsProducer.start(consumer, blackHole); executeAndWait(statements); String topicPrefix = "public.test_table"; String topicName = topicName(topicPrefix); assertRecordInserted(topicPrefix, PK_FIELD, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, PK_FIELD, 1); // second entry removed record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, PK_FIELD, 2); }
@Test public void shouldReceiveChangesForUpdatesWithPKChanges() throws Exception { consumer = testConsumer(3); recordsProducer.start(consumer, blackHole); executeAndWait("UPDATE test_table SET text = 'update', pk = 2"); String topicName = topicName("public.test_table"); // first should be a delete of the old pk SourceRecord deleteRecord = consumer.remove(); assertEquals(topicName, deleteRecord.topic()); VerifyRecord.isValidDelete(deleteRecord, PK_FIELD, 1); // followed by a tombstone of the old pk SourceRecord tombstoneRecord = consumer.remove(); assertEquals(topicName, tombstoneRecord.topic()); VerifyRecord.isValidTombstone(tombstoneRecord, PK_FIELD, 1); // and finally insert of the new value SourceRecord insertRecord = consumer.remove(); assertEquals(topicName, insertRecord.topic()); VerifyRecord.isValidInsert(insertRecord, PK_FIELD, 2); }
@Test @FixFor("DBZ-582") public void shouldReceiveChangesForDeletesWithoutTombstone() throws Exception { PostgresConnectorConfig config = new PostgresConnectorConfig(TestHelper.defaultConfig() .with(PostgresConnectorConfig.INCLUDE_UNKNOWN_DATATYPES, true) .with(CommonConnectorConfig.TOMBSTONES_ON_DELETE, false) .build() ); setupRecordsProducer(config); // add a new entry and remove both String statements = "INSERT INTO test_table (text) VALUES ('insert2');" + "DELETE FROM test_table WHERE pk > 0;"; consumer = testConsumer(3); recordsProducer.start(consumer, blackHole); executeAndWait(statements); String topicPrefix = "public.test_table"; String topicName = topicName(topicPrefix); assertRecordInserted(topicPrefix, PK_FIELD, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); // second entry removed record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2); }
@Test @FixFor("DBZ-259") public void shouldProcessIntervalDelete() throws Exception { final String statements = "INSERT INTO table_with_interval VALUES (default, 'Foo', default);" + "INSERT INTO table_with_interval VALUES (default, 'Bar', default);" + "DELETE FROM table_with_interval WHERE id = 1;"; consumer = testConsumer(4); recordsProducer.start(consumer, blackHole); executeAndWait(statements); final String topicPrefix = "public.table_with_interval"; final String topicName = topicName(topicPrefix); final String pk = "id"; assertRecordInserted(topicPrefix, pk, 1); assertRecordInserted(topicPrefix, pk, 2); // first entry removed SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, pk, 1); // followed by a tombstone record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidTombstone(record, pk, 1); }
@Test @FixFor("DBZ-582") public void shouldReceiveChangesForUpdatesWithPKChangesWithoutTombstone() throws Exception { PostgresConnectorConfig config = new PostgresConnectorConfig(TestHelper.defaultConfig() .with(PostgresConnectorConfig.INCLUDE_UNKNOWN_DATATYPES, true) .with(CommonConnectorConfig.TOMBSTONES_ON_DELETE, false) .build() ); setupRecordsProducer(config); consumer = testConsumer(2); recordsProducer.start(consumer, blackHole); executeAndWait("UPDATE test_table SET text = 'update', pk = 2"); String topicName = topicName("public.test_table"); // first should be a delete of the old pk SourceRecord deleteRecord = consumer.remove(); assertEquals(topicName, deleteRecord.topic()); VerifyRecord.isValidDelete(deleteRecord, PK_FIELD, 1); // followed by insert of the new value SourceRecord insertRecord = consumer.remove(); assertEquals(topicName, insertRecord.topic()); VerifyRecord.isValidInsert(insertRecord, PK_FIELD, 2); }
SourceRecord record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 1); record = consumer.remove(); assertEquals(topicName, record.topic()); VerifyRecord.isValidDelete(record, PK_FIELD, 2);
VerifyRecord.isValidDelete(testTableRecords.get(2), "ID", 1); before = (Struct) ((Struct)testTableRecords.get(2).value()).get("before"); assertThat(before.get("ID")).isEqualTo(1); VerifyRecord.isValidDelete(testTableRecords.get(5), "ID", 2); before = (Struct) ((Struct)testTableRecords.get(5).value()).get("before"); assertThat(before.get("ID")).isEqualTo(2);
executeAndWait("DELETE FROM test_table WHERE id=1"); SourceRecord deletedRecord = consumer.remove(); VerifyRecord.isValidDelete(deletedRecord);