1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/**
* Cached query for simple queries.
*/
class SimpleCachedQuery extends CachedQuery {
// The query string.
private QueryStr queryStr;
// Create.
init(QueryStr q) {
init { queryStr = q; }
}
// Generate the query.
Statement query(DBConnection db) : override {
db.prepare(queryStr);
}
// To string.
void toS(StrBuf to) {
to << queryStr;
}
}
/**
* A query that wraps multiple actual queries. Used for database compatibility.
*/
class MultiCachedQuery extends CachedQuery {
// The real query string. Only used if the databasse has the appropriate features.
private QueryStr realQuery;
// Features required to use the real query.
private DBFeatures required;
// Fallback queries, used if the database does not have the required capabilities.
private QueryStr[] fallbackQueries;
// Which of the queries in the fallback query to use as the result.
private Nat fallbackResult;
// Create.
init(QueryStr real, DBFeatures features, QueryStr[] fallback, Nat result) {
init {
realQuery = real;
required = features;
fallbackQueries = fallback;
fallbackResult = result;
}
}
// Generate the query.
Statement query(DBConnection db) : override {
var features = db.features;
// Check if we have all features required:
if ((features + required) == features) {
return db.prepare(realQuery);
} else {
return MultiStatement(db, fallbackQueries, fallbackResult);
}
}
// To string.
void toS(StrBuf to) {
to << realQuery << " (with fallback)";
}
}
/**
* Statement that executes multiple queries as a transaction.
*/
class MultiStatement extends Statement {
// Statements to execute.
private Statement[] statements;
// Get the result from this statement.
private Nat result;
// The connection itself.
private DBConnection connection;
// Create.
init(DBConnection db, QueryStr[] queries, Nat result) {
init(db) {
connection = db;
result = result;
}
statements.reserve(queries.count);
for (q in queries)
statements << db.prepare(q);
}
// Finalize everything.
void finalize() : override {
deregister(connection);
for (x in statements)
x.finalize();
}
// Execute the query.
Result execute() : override {
Transaction t(connection);
Nat count = statements.count;
for (Nat i = 0; i < result; i++)
statements[i].execute();
var r = statements[result].execute();
for (Nat i = result + 1; i < count; i++)
statements[i].execute();
t.commit();
return r;
}
// Bind parameters.
void bind(Nat pos, Str v) : override {
for (x in statements)
x.bind(pos, v);
}
void bind(Nat pos, Bool v) : override {
for (x in statements)
x.bind(pos, v);
}
void bind(Nat pos, Int v) : override {
for (x in statements)
x.bind(pos, v);
}
void bind(Nat pos, Long v) : override {
for (x in statements)
x.bind(pos, v);
}
void bind(Nat pos, Float v) : override {
for (x in statements)
x.bind(pos, v);
}
void bind(Nat pos, Double v) : override {
for (x in statements)
x.bind(pos, v);
}
void bindNull(Nat pos) : override {
for (x in statements)
x.bindNull(pos);
}
// Overrides needed.
protected void disposeResult() : override {}
protected Row? nextRow() : override { null; }
protected Int lastRowId() : override { 0; }
protected Nat changes() : override { 0; }
}
|