diff options
-rw-r--r-- | project2/tablepatch.cpp | 455 |
1 files changed, 313 insertions, 142 deletions
diff --git a/project2/tablepatch.cpp b/project2/tablepatch.cpp index 540da5e..3533b65 100644 --- a/project2/tablepatch.cpp +++ b/project2/tablepatch.cpp @@ -44,59 +44,104 @@ TablePatch::patch(const char * where, const char * order) void TablePatch::doDeletes(const char * where, const char * order) { - // ----------------------------------------------------------------- - // Build SQL to delete keys ---------------------------------------- - // ----------------------------------------------------------------- - Buffer toDelSql; - toDelSql.appendf("DELETE FROM %s d WHERE (", - dest.c_str()); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(", "); - } - toDelSql.appendf("d.%s", - pki->c_str()); - } - // ----------------------------------------------------------------- - // Build SQL to select keys to delete ------------------------------ - // ----------------------------------------------------------------- - toDelSql.append(") IN (SELECT "); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(", "); - } - toDelSql.appendf("a.%s", - pki->c_str()); - } - toDelSql.appendf(" FROM %s a LEFT OUTER JOIN %s b ON ", - dest.c_str(), src.c_str()); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(" AND "); - } - toDelSql.appendf(" a.%s = b.%s", - pki->c_str(), pki->c_str()); - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toDelSql.append(" WHERE "); - } - else { - toDelSql.append(" AND "); - } - toDelSql.appendf(" b.%s IS NULL", - pki->c_str()); - } - if (where && *where) { - toDelSql.appendf(" AND %s", where); - } - if (order && *order) { - toDelSql.appendf(" ORDER BY %s", order); - } - toDelSql.append(")"); - ModifyCommand * del = db.newModifyCommand(toDelSql); - del->execute(); - delete del; + switch (db.bulkDeleteStyle()) { + case BulkDeleteUsingSubSelect: + { + // ----------------------------------------------------------------- + // Build SQL to delete keys ---------------------------------------- + // ----------------------------------------------------------------- + Buffer toDelSql; + toDelSql.appendf("DELETE FROM %s WHERE (", + dest.c_str()); + foreach (PKI, pk, pki) { + if (pki != pk.begin()) { + toDelSql.append(", "); + } + toDelSql.appendf("%s.%s", + dest.c_str(), + pki->c_str()); + } + // ----------------------------------------------------------------- + // Build SQL to select keys to delete ------------------------------ + // ----------------------------------------------------------------- + toDelSql.append(") IN (SELECT "); + foreach (PKI, pk, pki) { + if (pki != pk.begin()) { + toDelSql.append(", "); + } + toDelSql.appendf("a.%s", + pki->c_str()); + } + toDelSql.appendf(" FROM %s a LEFT OUTER JOIN %s b ON ", + dest.c_str(), src.c_str()); + foreach (PKI, pk, pki) { + if (pki != pk.begin()) { + toDelSql.append(" AND "); + } + toDelSql.appendf(" a.%s = b.%s", + pki->c_str(), pki->c_str()); + } + foreach (PKI, pk, pki) { + if (pki == pk.begin()) { + toDelSql.append(" WHERE "); + } + else { + toDelSql.append(" AND "); + } + toDelSql.appendf(" b.%s IS NULL", + pki->c_str()); + } + if (where && *where) { + toDelSql.appendf(" AND %s", where); + } + if (order && *order) { + toDelSql.appendf(" ORDER BY %s", order); + } + toDelSql.append(")"); + ModifyCommand * del = db.newModifyCommand(toDelSql); + del->execute(); + delete del; + break; + } + case BulkDeleteUsingUsingAlias: + case BulkDeleteUsingUsing: + { + Buffer toDelSql; + toDelSql.appendf("DELETE FROM %s USING %s a LEFT OUTER JOIN %s b ", + (db.bulkDeleteStyle() == BulkDeleteUsingUsingAlias ? "a" : dest.c_str()), + dest.c_str(), src.c_str()); + foreach (PKI, pk, pki) { + if (pki != pk.begin()) { + toDelSql.append(" AND "); + } + else { + toDelSql.append(" ON "); + } + toDelSql.appendf(" a.%s = b.%s", + pki->c_str(), pki->c_str()); + } + foreach (PKI, pk, pki) { + if (pki != pk.begin()) { + toDelSql.append(" AND "); + } + else { + toDelSql.append(" WHERE "); + } + toDelSql.appendf(" b.%s IS NULL", + pki->c_str()); + } + if (where && *where) { + toDelSql.appendf(" AND %s", where); + } + if (order && *order) { + toDelSql.appendf(" ORDER BY %s", order); + } + ModifyCommand * del = db.newModifyCommand(toDelSql); + del->execute(); + delete del; + break; + } + } } void @@ -106,98 +151,224 @@ TablePatch::doUpdates(const char * where, const char * order) // Can't "change" anything... it's all part of the key return; } - // ----------------------------------------------------------------- - // Build SQL for list of updates to perform ------------------------ - // ----------------------------------------------------------------- - Buffer toUpdSel; - toUpdSel.append("SELECT "); - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - toUpdSel.appendf("b.%s, ", - col->c_str()); - } - } - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) != pk.end()) { - toUpdSel.appendf("b.%s, ", - col->c_str()); - } - } - toUpdSel.appendf("0 FROM %s a, %s b", - dest.c_str(), src.c_str()); - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toUpdSel.append(" WHERE "); - } - else { - toUpdSel.append(" AND "); - } - toUpdSel.appendf(" a.%s = b.%s", - pki->c_str(), pki->c_str()); - } - if (where && *where) { - toUpdSel.appendf(" AND %s", where); - } - toUpdSel.append(" AND ("); - bool first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - toUpdSel.append(" OR "); + switch (db.bulkUpdateStyle()) { + case BulkUpdateByIteration: + { + // ----------------------------------------------------------------- + // Build SQL for list of updates to perform ------------------------ + // ----------------------------------------------------------------- + Buffer toUpdSel; + toUpdSel.append("SELECT "); + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + toUpdSel.appendf("b.%s, ", + col->c_str()); + } + } + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) != pk.end()) { + toUpdSel.appendf("b.%s, ", + col->c_str()); + } + } + toUpdSel.appendf("0 FROM %s a, %s b", + dest.c_str(), src.c_str()); + foreach (PKI, pk, pki) { + if (pki == pk.begin()) { + toUpdSel.append(" WHERE "); + } + else { + toUpdSel.append(" AND "); + } + toUpdSel.appendf(" a.%s = b.%s", + pki->c_str(), pki->c_str()); + } + if (where && *where) { + toUpdSel.appendf(" AND %s", where); + } + toUpdSel.append(" AND ("); + bool first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + toUpdSel.append(" OR "); + } + first = false; + toUpdSel.appendf( + " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ + + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", + col->c_str(), col->c_str(), col->c_str(), col->c_str()); + } + } + toUpdSel.append(")"); + if (order && *order) { + toUpdSel.appendf(" ORDER BY %s", order); + } + // ----------------------------------------------------------------- + // Build SQL to perform updates ------------------------------------ + // ----------------------------------------------------------------- + Buffer updSql; + updSql.appendf("UPDATE %s SET ", + dest.c_str()); + first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + updSql.append(", "); + } + first = false; + updSql.appendf(" %s = ?", + col->c_str()); + } + } + foreach (PKI, pk, pki) { + if (pki == pk.begin()) { + updSql.append(" WHERE "); + } + else { + updSql.append(" AND "); + } + updSql.appendf(" %s = ?", + pki->c_str()); + } + // ----------------------------------------------------------------- + // Iterator over update list make changes -------------------------- + // ----------------------------------------------------------------- + SelectCommand * toUpd = db.newSelectCommand(toUpdSel); + ModifyCommand * upd = db.newModifyCommand(updSql); + int cs = cols.size(); + toUpd->execute(); + for (int c = 0; c < cs; c += 1) { + (*toUpd)[c].rebind(upd, c); + } + while (toUpd->fetch()) { + upd->execute(false); + } + delete toUpd; + delete upd; } - first = false; - toUpdSel.appendf( - " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ - + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", - col->c_str(), col->c_str(), col->c_str(), col->c_str()); - } - } - toUpdSel.append(")"); - if (order && *order) { - toUpdSel.appendf(" ORDER BY %s", order); - } - // ----------------------------------------------------------------- - // Build SQL to perform updates ------------------------------------ - // ----------------------------------------------------------------- - Buffer updSql; - updSql.appendf("UPDATE %s SET ", - dest.c_str()); - first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(", "); + break; + case BulkUpdateUsingFromSrc: + { + // ----------------------------------------------------------------- + // Build SQL for list of updates to perform ------------------------ + // ----------------------------------------------------------------- + Buffer updSql; + updSql.appendf("UPDATE %s SET ", + dest.c_str()); + bool first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + updSql.append(", "); + } + first = false; + updSql.appendf(" %s = b.%s ", + col->c_str(), col->c_str()); + } + } + updSql.appendf(" FROM %s b ", + src.c_str()); + foreach (PKI, pk, pki) { + if (pki == pk.begin()) { + updSql.append(" WHERE "); + } + else { + updSql.append(" AND "); + } + updSql.appendf(" %s.%s = b.%s ", + dest.c_str(), pki->c_str(), pki->c_str()); + } + updSql.append(" AND ("); + first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + updSql.append(" OR "); + } + first = false; + updSql.appendf( + " (((CASE WHEN (%s.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ + + (CASE WHEN(%s.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", + dest.c_str(), col->c_str(), col->c_str(), + dest.c_str(), col->c_str(), col->c_str()); + } + } + updSql.append(")"); + if (where && *where) { + updSql.appendf(" AND %s ", where); + } + if (order && *order) { + updSql.appendf(" ORDER BY %s", order); + } + // ----------------------------------------------------------------- + // Execute the bulk update command --------------------------------- + // ----------------------------------------------------------------- + ModifyCommand * upd = db.newModifyCommand(updSql); + upd->execute(true); + delete upd; + break; + } + case BulkUpdateUsingJoin: + { + // ----------------------------------------------------------------- + // Build SQL for list of updates to perform ------------------------ + // ----------------------------------------------------------------- + Buffer updSql; + updSql.appendf("UPDATE %s a, %s b SET ", + dest.c_str(), src.c_str()); + bool first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + updSql.append(", "); + } + first = false; + updSql.appendf(" a.%s = b.%s ", + col->c_str(), col->c_str()); + } + } + foreach (PKI, pk, pki) { + if (pki == pk.begin()) { + updSql.append(" WHERE "); + } + else { + updSql.append(" AND "); + } + updSql.appendf(" a.%s = b.%s ", + pki->c_str(), pki->c_str()); + } + updSql.append(" AND ("); + first = true; + foreach (Columns::const_iterator, cols, col) { + if (pk.find(*col) == pk.end()) { + if (!first) { + updSql.append(" OR "); + } + first = false; + updSql.appendf( + " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ + + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", + col->c_str(), col->c_str(), + col->c_str(), col->c_str()); + } + } + updSql.append(")"); + if (where && *where) { + updSql.appendf(" AND %s ", where); + } + if (order && *order) { + updSql.appendf(" ORDER BY %s", order); + } + // ----------------------------------------------------------------- + // Execute the bulk update command --------------------------------- + // ----------------------------------------------------------------- + ModifyCommand * upd = db.newModifyCommand(updSql); + upd->execute(true); + delete upd; + break; } - first = false; - updSql.appendf(" %s = ?", - col->c_str()); - } - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - updSql.append(" WHERE "); - } - else { - updSql.append(" AND "); - } - updSql.appendf(" %s = ?", - pki->c_str()); - } - // ----------------------------------------------------------------- - // Iterator over update list make changes -------------------------- - // ----------------------------------------------------------------- - SelectCommand * toUpd = db.newSelectCommand(toUpdSel); - ModifyCommand * upd = db.newModifyCommand(updSql); - int cs = cols.size(); - toUpd->execute(); - for (int c = 0; c < cs; c += 1) { - (*toUpd)[c].rebind(upd, c); - } - while (toUpd->fetch()) { - upd->execute(false); } - delete toUpd; - delete upd; } void |