use of com.airbnb.spinaltap.mysql.event.QueryEvent in project SpinalTap by airbnb.
the class MysqlSource method toBinlogEvent.
public static BinlogEvent toBinlogEvent(Event event, BinlogFilePos filePos) {
EventHeaderV4 header = event.getHeader();
EventType eventType = header.getEventType();
long serverId = header.getServerId();
long timestamp = header.getTimestamp();
if (EventType.isWrite(eventType)) {
WriteRowsEventData data = event.getData();
return new WriteEvent(data.getTableId(), serverId, timestamp, filePos, data.getRows());
} else if (EventType.isUpdate(eventType)) {
UpdateRowsEventData data = event.getData();
return new UpdateEvent(data.getTableId(), serverId, timestamp, filePos, data.getRows());
} else if (EventType.isDelete(eventType)) {
DeleteRowsEventData data = event.getData();
return new DeleteEvent(data.getTableId(), serverId, timestamp, filePos, data.getRows());
} else {
switch(eventType) {
case TABLE_MAP:
TableMapEventData tableMapData = event.getData();
return new TableMapEvent(tableMapData.getTableId(), serverId, timestamp, filePos, tableMapData.getDatabase(), tableMapData.getTable(), tableMapData.getColumnTypes());
case XID:
XidEventData xidData = event.getData();
return new XidEvent(serverId, timestamp, filePos, xidData.getXid());
case QUERY:
QueryEventData queryData = event.getData();
return new QueryEvent(serverId, timestamp, filePos, queryData.getDatabase(), queryData.getSql());
case FORMAT_DESCRIPTION:
return new StartEvent(serverId, timestamp, filePos);
default:
return null;
}
}
}
use of com.airbnb.spinaltap.mysql.event.QueryEvent in project SpinalTap by airbnb.
the class MysqlSchemaTrackerTest method testCreateDatabase.
@Test
public void testCreateDatabase() throws Exception {
Table<String, String, TreeMap<Integer, MysqlTableSchema>> allTableSchemaInStore = Tables.newCustomTable(Maps.newHashMap(), Maps::newHashMap);
allTableSchemaInStore.put(DATABASE_NAME, "table1", new TreeMap<Integer, MysqlTableSchema>() {
{
put(1, TABLE1_SCHEMA);
}
});
allTableSchemaInStore.put(DATABASE_NAME, "table2", new TreeMap<Integer, MysqlTableSchema>() {
{
put(1, TABLE2_SCHEMA);
}
});
when(schemaDatabase.listDatabases()).thenReturn(Sets.newHashSet(DATABASE_NAME, DATABASE2_NAME));
when(schemaStore.getAll()).thenReturn(allTableSchemaInStore);
when(schemaDatabase.fetchTableSchema(DATABASE_NAME)).thenReturn(ImmutableMap.of("table1", TABLE1_SCHEMA, "table2", TABLE2_SCHEMA));
when(schemaDatabase.fetchTableSchema(DATABASE2_NAME)).thenReturn(ImmutableMap.of("table1", DATABASE2_TABLE1_SCHEMA));
QueryEvent queryEvent = new QueryEvent(0, 0, binlogFilePos, DATABASE2_NAME, "CREATE DATABASE `database2`");
SchemaTracker schemaTracker = new MysqlSchemaTracker(schemaStore, schemaDatabase);
schemaTracker.processDDLStatement(queryEvent);
verify(schemaDatabase).applyDDLStatement("", queryEvent.getSql());
verify(schemaStore).put(DATABASE2_NAME, "table1", queryEvent.getBinlogFilePos(), queryEvent.getTimestamp(), queryEvent.getSql(), DATABASE2_TABLE1_SCHEMA.getColumnInfo());
}
use of com.airbnb.spinaltap.mysql.event.QueryEvent in project SpinalTap by airbnb.
the class MysqlSchemaTracker method processDDLStatement.
public void processDDLStatement(@NotNull final QueryEvent event) {
BinlogFilePos binlogFilePos = event.getBinlogFilePos();
String ddl = event.getSql();
if (schemaStore.get(binlogFilePos) != null) {
log.info(String.format("DDL Statement (%s) has already been processed. (BinlogFilePos: %s)", ddl, binlogFilePos));
return;
}
// It could be a new database which has not been created in schema store database, so don't
// switch to any database before applying database DDL.
schemaDatabase.applyDDLStatement(DATABASE_DDL_SQL_PATTERN.matcher(ddl).find() ? "" : event.getDatabase(), ddl);
// Get schemas for active tables in schema store
Table<String, String, MysqlTableSchema> activeTableSchemasInStore = Tables.newCustomTable(Maps.newHashMap(), Maps::newHashMap);
schemaStore.getAll().values().stream().map(treeMap -> treeMap.lastEntry().getValue()).filter(schema -> !schema.getColumnInfo().isEmpty()).forEach(schema -> activeTableSchemasInStore.put(schema.getDatabase(), schema.getTable(), schema));
Set<String> activeDatabasesInStore = activeTableSchemasInStore.rowKeySet();
Set<String> databasesInSchemaDatabase = schemaDatabase.listDatabases();
// Handle new databases
Sets.difference(databasesInSchemaDatabase, activeDatabasesInStore).forEach(newDatabase -> updateSchemaStore(newDatabase, event, Maps.newHashMap(), schemaDatabase.fetchTableSchema(newDatabase)));
// Handle existing databases
activeDatabasesInStore.forEach(database -> updateSchemaStore(database, event, activeTableSchemasInStore.row(database), schemaDatabase.fetchTableSchema(database)));
}
use of com.airbnb.spinaltap.mysql.event.QueryEvent in project SpinalTap by airbnb.
the class MysqlEventFilterTest method testEventFilter.
@Test
public void testEventFilter() throws Exception {
TableCache tableCache = mock(TableCache.class);
BinlogEvent lastEvent = new XidEvent(0l, 0l, BINLOG_FILE_POS, 0l);
BinlogFilePos nextPosition = new BinlogFilePos("test.123", 15, 100);
SourceState state = new SourceState(0l, lastEvent.getOffset(), 0l, BINLOG_FILE_POS);
Filter<BinlogEvent> filter = MysqlEventFilter.create(tableCache, TABLE_NAMES, new AtomicReference(state));
when(tableCache.contains(TABLE_ID)).thenReturn(true);
assertTrue(filter.apply(new TableMapEvent(TABLE_ID, 0l, 0l, nextPosition, DATABASE_NAME, TABLE_NAME, new byte[1])));
assertTrue(filter.apply(new WriteEvent(TABLE_ID, 0l, 0l, nextPosition, Collections.emptyList())));
assertTrue(filter.apply(new DeleteEvent(TABLE_ID, 0l, 0l, nextPosition, Collections.emptyList())));
assertTrue(filter.apply(new UpdateEvent(TABLE_ID, 0l, 0l, nextPosition, Collections.emptyList())));
assertTrue(filter.apply(new XidEvent(0l, 0l, BINLOG_FILE_POS, 12l)));
assertTrue(filter.apply(new QueryEvent(0l, 0l, BINLOG_FILE_POS, DATABASE_NAME, "")));
assertTrue(filter.apply(new StartEvent(0l, 0l, BINLOG_FILE_POS)));
assertFalse(filter.apply(new TableMapEvent(TABLE_ID, 0l, 0l, BINLOG_FILE_POS, "", "", new byte[1])));
assertFalse(filter.apply(new WriteEvent(0l, 0l, 0l, BINLOG_FILE_POS, Collections.emptyList())));
assertFalse(filter.apply(new WriteEvent(TABLE_ID, 0l, 0l, BINLOG_FILE_POS, Collections.emptyList())));
assertFalse(filter.apply(mock(BinlogEvent.class)));
}
use of com.airbnb.spinaltap.mysql.event.QueryEvent in project SpinalTap by airbnb.
the class MysqlMutationMapperTest method testQuery.
@Test
public void testQuery() throws Exception {
QueryEvent queryEvent = new QueryEvent(SERVER_ID, 15l, BINLOG_FILE_POS, DATABASE_NAME, "BEGIN");
List<? extends Mutation> mutations = eventMapper.map(queryEvent);
assertTrue(mutations.isEmpty());
assertEquals(15L, beginTransaction.get().getTimestamp());
queryEvent = new QueryEvent(SERVER_ID, 30l, BINLOG_FILE_POS, DATABASE_NAME, "");
mutations = eventMapper.map(queryEvent);
assertTrue(mutations.isEmpty());
assertEquals(15L, beginTransaction.get().getTimestamp());
queryEvent = new QueryEvent(SERVER_ID, 30l, BINLOG_FILE_POS, DATABASE_NAME, "BEGIN");
mutations = eventMapper.map(queryEvent);
assertTrue(mutations.isEmpty());
assertEquals(30L, beginTransaction.get().getTimestamp());
}
Aggregations