package com.zendesk.maxwell.schema;
import java.util.ArrayList;
import java.util.List;
import com.zendesk.maxwell.CaseSensitivity;
import com.zendesk.maxwell.schema.columndef.ColumnDef;
import com.zendesk.maxwell.schema.ddl.InvalidSchemaError;
public class Database {
private final String name;
private final List<Table> tableList;
private String charset;
private CaseSensitivity sensitivity;
public Database(String name, List<Table> tables, String charset) {
this.name = name;
if ( tables == null )
this.tableList = new ArrayList<>();
else
this.tableList = tables;
this.charset = charset;
}
public Database(String name, String charset) {
this(name, null, charset);
}
public List<String> getTableNames() {
ArrayList<String> names = new ArrayList<String>();
for ( Table t : this.tableList ) {
names.add(t.getName());
}
return names;
}
private boolean compareTableNames(String a, String b) {
if ( sensitivity == CaseSensitivity.CASE_SENSITIVE )
return a.equals(b);
else
return a.toLowerCase().equals(b.toLowerCase());
}
public Table findTable(String name) {
for ( Table t: this.tableList ) {
if ( compareTableNames(name, t.getName()))
return t;
}
return null;
}
public Table findTableOrThrow(String table) throws InvalidSchemaError {
Table t = findTable(table);
if ( t == null )
throw new InvalidSchemaError("Couldn't find table '" + table + "'" + " in database " + this.name);
return t;
}
public boolean hasTable(String name) {
return findTable(name) != null;
}
public void removeTable(String name) {
Table t = findTable(name);
if ( t != null )
tableList.remove(t);
}
public Database copy() {
Database d = new Database(this.name, this.charset);
for ( Table t: this.tableList ) {
d.addTable(t.copy());
}
return d;
}
private void diffTableList(List<String> diffs, Database a, Database b, String nameA, String nameB, boolean recurse) {
for ( Table t : a.getTableList() ) {
Table other = b.findTable(t.getName());
if ( other == null )
diffs.add("database " + a.getName() + " did not contain table " + t.getName() + " in " + nameB);
else if ( recurse )
t.diff(diffs, other, nameA, nameB);
}
}
public void diff(List<String> diffs, Database other, String nameA, String nameB) {
if ( !this.charset.toLowerCase().equals(other.getCharset().toLowerCase()) ) {
diffs.add("-- Database " + this.getName() + " had different charset: "
+ this.getCharset() + " in " + nameA + ", "
+ other.getCharset() + " in " + nameB);
}
diffTableList(diffs, this, other, nameA, nameB, true);
diffTableList(diffs, other, this, nameB, nameA, false);
}
public String getCharset() {
if ( charset == null ) {
// TODO: return server-default charset
return "";
} else {
return charset;
}
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getName() {
return name;
}
public List<Table> getTableList() {
return tableList;
}
public void addTable(Table table) {
table.setDatabase(this.name);
this.tableList.add(table);
}
public Table buildTable(String name, String charset, List<ColumnDef> list, List<String> pks) {
if ( charset == null )
charset = getCharset(); // inherit database's default charset
if ( sensitivity == CaseSensitivity.CONVERT_TO_LOWER )
name = name.toLowerCase();
Table t = new Table(this.name, name, charset, list, pks);
this.tableList.add(t);
return t;
}
public Table buildTable(String name, String charset) {
return buildTable(name, charset, new ArrayList<ColumnDef>(), null);
}
public void setSensitivity(CaseSensitivity sensitivity) {
this.sensitivity = sensitivity;
}
}