use of org.jumpmind.db.model.Reference in project symmetric-ds by JumpMind.
the class DataService method getForeignTableRows.
protected List<TableRow> getForeignTableRows(List<TableRow> tableRows, Set<TableRow> visited) throws CloneNotSupportedException {
List<TableRow> fkDepList = new ArrayList<TableRow>();
for (TableRow tableRow : tableRows) {
if (!visited.contains(tableRow)) {
visited.add(tableRow);
for (ForeignKey fk : tableRow.getTable().getForeignKeys()) {
Table table = platform.getTableFromCache(fk.getForeignTableName(), false);
if (table == null) {
table = fk.getForeignTable();
if (table == null) {
table = platform.getTableFromCache(tableRow.getTable().getCatalog(), tableRow.getTable().getSchema(), fk.getForeignTableName(), false);
}
}
if (table != null) {
Table foreignTable = (Table) table.clone();
for (Column column : foreignTable.getColumns()) {
column.setPrimaryKey(false);
}
Row whereRow = new Row(fk.getReferenceCount());
String referenceColumnName = null;
boolean[] nullValues = new boolean[fk.getReferenceCount()];
int index = 0;
for (Reference ref : fk.getReferences()) {
Column foreignColumn = foreignTable.findColumn(ref.getForeignColumnName());
Object value = tableRow.getRow().get(ref.getLocalColumnName());
nullValues[index++] = value == null;
referenceColumnName = ref.getLocalColumnName();
whereRow.put(foreignColumn.getName(), value);
foreignColumn.setPrimaryKey(true);
}
boolean allNullValues = true;
for (boolean b : nullValues) {
if (!b) {
allNullValues = false;
break;
}
}
if (!allNullValues) {
DmlStatement whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), foreignTable.getSchema(), foreignTable.getName(), foreignTable.getPrimaryKeyColumns(), foreignTable.getColumns(), nullValues, null);
String whereSql = whereSt.buildDynamicSql(symmetricDialect.getBinaryEncoding(), whereRow, false, true, foreignTable.getPrimaryKeyColumns()).substring(6);
String delimiter = platform.getDatabaseInfo().getSqlCommandDelimiter();
if (delimiter != null && delimiter.length() > 0) {
whereSql = whereSql.substring(0, whereSql.length() - delimiter.length());
}
Row foreignRow = new Row(foreignTable.getColumnCount());
if (foreignTable.getForeignKeyCount() > 0) {
DmlStatement selectSt = platform.createDmlStatement(DmlType.SELECT, foreignTable, null);
Object[] keys = whereRow.toArray(foreignTable.getPrimaryKeyColumnNames());
Map<String, Object> values = sqlTemplate.queryForMap(selectSt.getSql(), keys);
if (values == null) {
log.warn("Unable to reload rows for missing foreign key data for table '{}', parent data not found. Using sql='{}' with keys '{}'", table.getName(), selectSt.getSql(), keys);
} else {
foreignRow.putAll(values);
}
}
TableRow foreignTableRow = new TableRow(foreignTable, foreignRow, whereSql, referenceColumnName, fk.getName());
fkDepList.add(foreignTableRow);
log.debug("Add foreign table reference '{}' whereSql='{}'", foreignTable.getName(), whereSql);
} else {
log.debug("The foreign table reference was null for {}", foreignTable.getName());
}
} else {
log.debug("Foreign table '{}' not found for foreign key '{}'", fk.getForeignTableName(), fk.getName());
}
if (fkDepList.size() > 0) {
fkDepList.addAll(getForeignTableRows(fkDepList, visited));
}
}
}
}
return fkDepList;
}
use of org.jumpmind.db.model.Reference in project symmetric-ds by JumpMind.
the class DbFill method buildDependentColumnValues.
protected void buildDependentColumnValues(List<Table> tables) {
for (Table table : tables) {
Map<String, List<ForeignKeyReference>> columnReferences = new HashMap<String, List<ForeignKeyReference>>();
for (ForeignKey fk : table.getForeignKeys()) {
for (Reference ref : fk.getReferences()) {
List<ForeignKeyReference> references = columnReferences.get(ref.getLocalColumnName());
if (references == null) {
references = new ArrayList<ForeignKeyReference>();
columnReferences.put(ref.getLocalColumnName(), references);
}
references.add(new ForeignKeyReference(fk, ref));
}
}
for (String columnName : columnReferences.keySet()) {
List<ForeignKeyReference> references = columnReferences.get(columnName);
if (references.size() > 1) {
List<Object> commonValue = new ArrayList<Object>();
StringBuilder sb = null;
for (ForeignKeyReference fkr : references) {
String key = fkr.getForeignKey().getForeignTableName() + "." + fkr.getReference().getForeignColumnName();
commonDependencyValues.put(key, commonValue);
commonDependencyTables.add(getDbTable(fkr.getForeignKey().getForeignTableName()));
if (verbose) {
sb = (sb == null) ? new StringBuilder() : sb.append(", ");
sb.append(key);
}
}
if (verbose) {
log.info("Common dependency for table {}: {}", table.getName(), sb.toString());
}
}
}
}
}
use of org.jumpmind.db.model.Reference in project symmetric-ds by JumpMind.
the class DbFill method buildForeignKeyReferences.
protected void buildForeignKeyReferences(List<Table> tables) {
for (Table table : tables) {
for (ForeignKey fk : table.getForeignKeys()) {
for (Reference ref : fk.getReferences()) {
String key = table.getQualifiedTableName() + "." + ref.getLocalColumnName();
foreignKeyReferences.put(key, new ForeignKeyReference(fk, ref));
}
}
}
}
use of org.jumpmind.db.model.Reference in project symmetric-ds by JumpMind.
the class AseDdlReader method readForeignKeys.
@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
// Sybase (or jConnect) does not return the foreign key names, thus we
// have to
// read the foreign keys manually from the system tables
StringBuffer query = new StringBuffer();
query.append("SELECT refobjs.name, localtables.id, remotetables.name, remotetables.id");
for (int idx = 1; idx <= 16; idx++) {
query.append(", refs.fokey");
query.append(idx);
query.append(", refs.refkey");
query.append(idx);
}
query.append(" FROM dbo.sysreferences refs, dbo.sysobjects refobjs, dbo.sysobjects localtables, dbo.sysobjects remotetables");
query.append(" WHERE refobjs.type = 'RI' AND refs.constrid = refobjs.id AND");
query.append(" localtables.type = 'U' AND refs.tableid = localtables.id AND localtables.name = '");
query.append(tableName);
query.append("' AND remotetables.type = 'U' AND refs.reftabid = remotetables.id");
Statement stmt = connection.createStatement();
PreparedStatement prepStmt = connection.prepareStatement("SELECT name FROM dbo.syscolumns WHERE id = ? AND colid = ?");
ArrayList<ForeignKey> result = new ArrayList<ForeignKey>();
try {
ResultSet fkRs = stmt.executeQuery(query.toString());
while (fkRs.next()) {
ForeignKey fk = new ForeignKey(fkRs.getString(1));
int localTableId = fkRs.getInt(2);
int remoteTableId = fkRs.getInt(4);
fk.setForeignTableName(fkRs.getString(3));
for (int idx = 0; idx < 16; idx++) {
short fkColIdx = fkRs.getShort(5 + idx + idx);
short pkColIdx = fkRs.getShort(6 + idx + idx);
Reference ref = new Reference();
if (fkColIdx == 0) {
break;
}
prepStmt.setInt(1, localTableId);
prepStmt.setShort(2, fkColIdx);
ResultSet colRs = prepStmt.executeQuery();
if (colRs.next()) {
ref.setLocalColumnName(colRs.getString(1));
}
colRs.close();
prepStmt.setInt(1, remoteTableId);
prepStmt.setShort(2, pkColIdx);
colRs = prepStmt.executeQuery();
if (colRs.next()) {
ref.setForeignColumnName(colRs.getString(1));
}
colRs.close();
fk.addReference(ref);
}
result.add(fk);
}
fkRs.close();
} finally {
stmt.close();
prepStmt.close();
}
return result;
}
use of org.jumpmind.db.model.Reference in project symmetric-ds by JumpMind.
the class MySqlDdlReader method readForeignKeys.
@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
if (!isMariaDbDriver()) {
return super.readForeignKeys(connection, metaData, tableName);
} else {
Map<String, ForeignKey> fks = new LinkedHashMap<String, ForeignKey>();
ResultSet fkData = null;
try {
fkData = metaData.getForeignKeys(tableName);
while (fkData.next()) {
int count = fkData.getMetaData().getColumnCount();
Map<String, Object> values = new HashMap<String, Object>();
for (int i = 1; i <= count; i++) {
values.put(fkData.getMetaData().getColumnName(i), fkData.getObject(i));
}
String fkName = (String) values.get("CONSTRAINT_NAME");
ForeignKey fk = (ForeignKey) fks.get(fkName);
if (fk == null) {
fk = new ForeignKey(fkName);
fk.setForeignTableName((String) values.get("REFERENCED_TABLE_NAME"));
fks.put(fkName, fk);
}
Reference ref = new Reference();
ref.setForeignColumnName((String) values.get("REFERENCED_COLUMN_NAME"));
ref.setLocalColumnName((String) values.get("COLUMN_NAME"));
if (values.containsKey("POSITION_IN_UNIQUE_CONSTRAINT")) {
ref.setSequenceValue(((Number) values.get("POSITION_IN_UNIQUE_CONSTRAINT")).intValue());
}
fk.addReference(ref);
}
} finally {
close(fkData);
}
return fks.values();
}
}
Aggregations