?? constraintreferential.java
字號:
found = cursor.getSearchRow();
Column[] cols = index.getColumns();
boolean allEqual = true;
for (int i = 0; i < columns.length && i < cols.length; i++) {
int idx = cols[i].getColumnId();
Value c = check.getValue(idx);
Value f = found.getValue(idx);
if (database.compareTypeSave(c, f) != 0) {
allEqual = false;
break;
}
}
if (allEqual) {
return true;
}
}
return false;
}
private boolean isEqual(Row oldRow, Row newRow) throws SQLException {
return refIndex.compareRows(oldRow, newRow) == 0;
}
private void checkRow(Session session, Row oldRow) throws SQLException {
if (refTable == table) {
// special case self referencing constraints: check the deleted row
// first
boolean self = true;
for (int i = 0; i < columns.length; i++) {
Column refCol = refColumns[i].column;
int refIdx = refCol.getColumnId();
Value v = oldRow.getValue(refIdx);
int idx = columns[i].column.getColumnId();
Value r = oldRow.getValue(idx);
if (!database.areEqual(r, v)) {
self = false;
break;
}
}
if (self) {
return;
}
}
SearchRow check = table.getTemplateSimpleRow(false);
for (int i = 0; i < columns.length; i++) {
Column refCol = refColumns[i].column;
int refIdx = refCol.getColumnId();
Column col = columns[i].column;
int idx = col.getColumnId();
Value v = oldRow.getValue(refIdx).convertTo(col.getType());
check.setValue(idx, v);
}
if (found(session, index, check)) {
throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1,
getShortDescription());
}
}
private void checkRowRefTable(Session session, Row oldRow, Row newRow) throws SQLException {
if (oldRow == null) {
// this is an insert
return;
}
if (newRow != null && isEqual(oldRow, newRow)) {
// on an update, if both old and new are the same, don't do anything
return;
}
if (newRow == null) {
// this is a delete
if (deleteAction == RESTRICT) {
checkRow(session, oldRow);
} else {
int i = deleteAction == CASCADE ? 0 : columns.length;
Prepared deleteCommand = getDelete(session);
setWhere(deleteCommand, i, oldRow);
updateWithSkipCheck(deleteCommand);
}
} else {
// this is an update
if (updateAction == RESTRICT) {
checkRow(session, oldRow);
} else {
Prepared updateCommand = getUpdate(session);
if (updateAction == CASCADE) {
ObjectArray params = updateCommand.getParameters();
for (int i = 0; i < columns.length; i++) {
Parameter param = (Parameter) params.get(i);
Column refCol = refColumns[i].column;
param.setValue(newRow.getValue(refCol.getColumnId()));
}
}
setWhere(updateCommand, columns.length, oldRow);
updateWithSkipCheck(updateCommand);
}
}
}
private void updateWithSkipCheck(Prepared prep) throws SQLException {
// TODO constraints: maybe delay the update or support delayed checks
// (until commit)
try {
// TODO multithreaded kernel: this works only if nobody else updates
// this or the ref table at the same time
skipOwnTable = true;
prep.update();
} finally {
skipOwnTable = false;
}
}
void setWhere(Prepared command, int pos, Row row) {
for (int i = 0; i < refColumns.length; i++) {
int idx = refColumns[i].column.getColumnId();
Value v = row.getValue(idx);
ObjectArray params = command.getParameters();
Parameter param = (Parameter) params.get(pos + i);
param.setValue(v);
}
}
public int getDeleteAction() {
return deleteAction;
}
public void setDeleteAction(Session session, int action) throws SQLException {
if (action == deleteAction) {
return;
}
if (deleteAction != RESTRICT) {
throw Message.getSQLException(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, "ON DELETE");
}
this.deleteAction = action;
StringBuffer buff = new StringBuffer();
if (action == CASCADE) {
buff.append("DELETE FROM ");
buff.append(table.getSQL());
} else {
appendUpdate(buff);
}
appendWhere(buff);
deleteSQL = buff.toString();
}
private Prepared getUpdate(Session session) throws SQLException {
return prepare(session, updateSQL, updateAction);
}
private Prepared getDelete(Session session) throws SQLException {
return prepare(session, deleteSQL, deleteAction);
}
public int getUpdateAction() {
return updateAction;
}
public void setUpdateAction(Session session, int action) throws SQLException {
if (action == updateAction) {
return;
}
if (updateAction != RESTRICT) {
throw Message.getSQLException(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, "ON UPDATE");
}
this.updateAction = action;
StringBuffer buff = new StringBuffer();
appendUpdate(buff);
appendWhere(buff);
updateSQL = buff.toString();
}
private Prepared prepare(Session session, String sql, int action) throws SQLException {
Prepared command = session.prepare(sql);
if (action != CASCADE) {
ObjectArray params = command.getParameters();
for (int i = 0; i < columns.length; i++) {
Column column = columns[i].column;
Parameter param = (Parameter) params.get(i);
Value value;
if (action == SET_NULL) {
value = ValueNull.INSTANCE;
} else {
Expression expr = column.getDefaultExpression();
if (expr == null) {
throw Message.getSQLException(ErrorCode.NO_DEFAULT_SET_1, column.getName());
}
value = expr.getValue(session);
}
param.setValue(value);
}
}
return command;
}
private void appendUpdate(StringBuffer buff) {
buff.append("UPDATE ");
buff.append(table.getSQL());
buff.append(" SET ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(" , ");
}
Column column = columns[i].column;
buff.append(Parser.quoteIdentifier(column.getName()));
buff.append("=?");
}
}
private void appendWhere(StringBuffer buff) {
buff.append(" WHERE ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(" AND ");
}
Column column = columns[i].column;
buff.append(Parser.quoteIdentifier(column.getName()));
buff.append("=?");
}
}
public Table getRefTable() {
return refTable;
}
public boolean usesIndex(Index idx) {
return idx == index || idx == refIndex;
}
public void setIndexOwner(Index index) {
if (this.index == index) {
indexOwner = true;
} else if (this.refIndex == index) {
refIndexOwner = true;
} else {
throw Message.getInternalError();
}
}
public boolean containsColumn(Column col) {
for (int i = 0; i < columns.length; i++) {
if (columns[i].column == col) {
return true;
}
}
for (int i = 0; i < refColumns.length; i++) {
if (refColumns[i].column == col) {
return true;
}
}
return false;
}
public boolean isBefore() {
return false;
}
public void checkExistingData(Session session) throws SQLException {
if (session.getDatabase().isStarting()) {
// don't check at startup
return;
}
StringBuffer buff = new StringBuffer();
buff.append("SELECT 1 FROM (SELECT ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(columns[i].getSQL());
}
buff.append(" FROM ");
buff.append(table.getSQL());
buff.append(" WHERE ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(" AND ");
}
buff.append(columns[i].getSQL());
buff.append(" IS NOT NULL ");
}
buff.append(" ORDER BY ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(columns[i].getSQL());
}
buff.append(") C WHERE NOT EXISTS(SELECT 1 FROM ");
buff.append(refTable.getSQL());
buff.append(" P WHERE ");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(" AND ");
}
buff.append("C.");
buff.append(columns[i].getSQL());
buff.append("=");
buff.append("P.");
buff.append(refColumns[i].getSQL());
}
buff.append(")");
String sql = buff.toString();
LocalResult r = session.prepare(sql).query(1);
if (r.next()) {
throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1,
getShortDescription());
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -