package com.zendesk.maxwell.schema;
import static com.zendesk.maxwell.MaxwellTestSupport.getSQLDir;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import com.zendesk.maxwell.CaseSensitivity;
import com.zendesk.maxwell.MaxwellTestWithIsolatedServer;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import com.google.code.or.common.util.MySQLConstants;
import com.zendesk.maxwell.schema.Database;
import com.zendesk.maxwell.schema.Schema;
import com.zendesk.maxwell.schema.SchemaCapturer;
import com.zendesk.maxwell.schema.Table;
import com.zendesk.maxwell.schema.columndef.*;
import com.zendesk.maxwell.schema.ddl.InvalidSchemaError;
public class SchemaCaptureTest extends MaxwellTestWithIsolatedServer {
private SchemaCapturer capturer;
@Before
public void setUp() throws Exception {
server.getConnection().createStatement().executeUpdate("CREATE DATABASE if not exists test");
this.capturer = new SchemaCapturer(server.getConnection(), CaseSensitivity.CASE_SENSITIVE);
}
@Test
public void testDatabases() throws SQLException, InvalidSchemaError {
Schema s = capturer.capture();
String dbs = StringUtils.join(s.getDatabaseNames().iterator(), ":");
if ( server.getVersion().equals("5.7") )
assertEquals("maxwell:mysql:shard_1:shard_2:sys:test", dbs);
else
assertEquals("maxwell:mysql:shard_1:shard_2:test", dbs);
}
@Test
public void testOneDatabase() throws SQLException, InvalidSchemaError {
SchemaCapturer sc = new SchemaCapturer(server.getConnection(), CaseSensitivity.CASE_SENSITIVE, "shard_1");
Schema s = sc.capture();
String dbs = StringUtils.join(s.getDatabaseNames().iterator(), ":");
assertEquals("shard_1", dbs);
}
@Test
public void testTables() throws SQLException, InvalidSchemaError {
Schema s = capturer.capture();
Database shard1DB = s.findDatabase("shard_1");
assert(shard1DB != null);
List<String> nameList = shard1DB.getTableNames();
assertEquals("ints:mediumints:minimal:sharded", StringUtils.join(nameList.iterator(), ":"));
}
@Test
public void testColumns() throws SQLException, InvalidSchemaError {
Schema s = capturer.capture();
Table sharded = s.findDatabase("shard_1").findTable("sharded");
assert(sharded != null);
ColumnDef columns[];
columns = sharded.getColumnList().toArray(new ColumnDef[0]);
assertThat(columns[0], notNullValue());
assertThat(columns[0], instanceOf(BigIntColumnDef.class));
assertThat(columns[0].getName(), is("id"));
assertEquals(0, columns[0].getPos());
assertTrue(columns[0].matchesMysqlType(MySQLConstants.TYPE_LONGLONG));
assertFalse(columns[0].matchesMysqlType(MySQLConstants.TYPE_DECIMAL));
assertThat(columns[1], allOf(notNullValue(), instanceOf(IntColumnDef.class)));
assertThat(columns[1].getName(), is("account_id"));
assertThat(columns[1], instanceOf(IntColumnDef.class));
assertThat(((IntColumnDef) columns[1]).isSigned(), is(false));
if ( server.getVersion().equals("5.6") ) {
assertThat(columns[10].getName(), is("timestamp2_field"));
assertThat(columns[10], instanceOf(DateTimeColumnDef.class));
assertThat(((DateTimeColumnDef) columns[10]).getColumnLength(), is(3L));
assertThat(columns[11].getName(), is("datetime2_field"));
assertThat(columns[11], instanceOf(DateTimeColumnDef.class));
assertThat(((DateTimeColumnDef) columns[11]).getColumnLength(), is(6L));
assertThat(columns[12].getName(), is("time2_field"));
assertThat(columns[12], instanceOf(TimeColumnDef.class));
assertThat(((TimeColumnDef) columns[12]).getColumnLength(), is(6L));
}
}
@Test
public void testPKs() throws SQLException, InvalidSchemaError {
Schema s = capturer.capture();
Table sharded = s.findDatabase("shard_1").findTable("sharded");
List<String> pk = sharded.getPKList();
assertThat(pk, notNullValue());
assertThat(pk.size(), is(2));
assertThat(pk.get(0), is("id"));
assertThat(pk.get(1), is("account_id"));
}
@Test
public void testEnums() throws SQLException, InvalidSchemaError, IOException {
byte[] sql = Files.readAllBytes(Paths.get(getSQLDir() + "/schema/enum.sql"));
server.executeList(Collections.singletonList(new String(sql)));
Schema s = capturer.capture();
Table enumTest = s.findDatabase("test").findTable("enum_test");
assert(enumTest != null);
ColumnDef[] columns = enumTest.getColumnList().toArray(new ColumnDef[0]);
assertThat(columns[0], notNullValue());
assertThat(columns[0], instanceOf(EnumColumnDef.class));
assertThat(columns[0].getName(), is("language"));
assertArrayEquals(((EnumColumnDef) columns[0]).getEnumValues(), new String[] {"en-US", "de-DE"});
assertThat(columns[1], notNullValue());
assertThat(columns[1], instanceOf(EnumColumnDef.class));
assertThat(columns[1].getName(), is("decimal_separator"));
assertArrayEquals(((EnumColumnDef) columns[1]).getEnumValues(), new String[] {",", "."});
}
}