package com.zendesk.maxwell.schema;
import com.zendesk.maxwell.CaseSensitivity;
import com.zendesk.maxwell.schema.columndef.ColumnDef;
import com.zendesk.maxwell.schema.ddl.InvalidSchemaError;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.List;
public class Schema {
private final ArrayList<Database> databases;
private final String charset;
private final CaseSensitivity sensitivity;
public Schema(List<Database> databases, String charset, CaseSensitivity sensitivity) {
this.sensitivity = sensitivity;
this.charset = charset;
this.databases = new ArrayList<>();
for ( Database d : databases )
addDatabase(d);
}
public List<Database> getDatabases() { return this.databases; }
public List<String> getDatabaseNames () {
ArrayList<String> names = new ArrayList<String>();
for ( Database d : this.databases ) {
names.add(d.getName());
}
return names;
}
public Database findDatabase(String string) {
for ( Database d: this.databases ) {
if ( sensitivity == CaseSensitivity.CASE_SENSITIVE ) {
if ( d.getName().equals(string) ) return d;
} else {
if ( d.getName().toLowerCase().equals(string.toLowerCase()) ) return d;
}
}
return null;
}
public Database findDatabaseOrThrow(String name) throws InvalidSchemaError {
Database d = findDatabase(name);
if ( d == null )
throw new InvalidSchemaError("Couldn't find database '" + name + "'");
return d;
}
public boolean hasDatabase(String string) {
return findDatabase(string) != null;
}
public void addDatabase(Database d) {
d.setSensitivity(sensitivity);
this.databases.add(d);
}
private void diffDBList(List<String> diff, Schema a, Schema b, String nameA, String nameB, boolean recurse) {
for ( Database d : a.databases ) {
Database matchingDB = b.findDatabase(d.getName());
if ( matchingDB == null )
diff.add("-- Database " + d.getName() + " did not exist in " + nameB);
else if ( recurse )
d.diff(diff, matchingDB, nameA, nameB);
}
}
public List<String> diff(Schema that, String thisName, String thatName) {
List<String> diff = new ArrayList<>();
diffDBList(diff, this, that, thisName, thatName, true);
diffDBList(diff, that, this, thatName, thisName, false);
return diff;
}
public boolean equals(Schema that) {
return diff(that, "a", "b").size() == 0;
}
public String getCharset() {
return charset;
}
public CaseSensitivity getCaseSensitivity() {
return sensitivity;
};
public List<Pair<ColumnDef, ColumnDef>> matchColumns(Schema thatSchema) {
ArrayList<Pair<ColumnDef, ColumnDef>> list = new ArrayList<>();
for ( Database thisDatabase : this.getDatabases() ) {
Database thatDatabase = thatSchema.findDatabase(thisDatabase.getName());
if ( thatDatabase == null )
continue;
for ( Table thisTable : thisDatabase.getTableList() ) {
Table thatTable = thatDatabase.findTable(thisTable.getName());
if ( thatTable == null )
continue;
for ( ColumnDef thisColumn : thisTable.getColumnList() ) {
ColumnDef thatColumn = thatTable.findColumn(thisColumn.getName());
if ( thatColumn != null )
list.add(Pair.of(thisColumn, thatColumn));
}
}
}
return list;
}
}