mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 702889 - IndexedDB: Change SQL schema and some cursor queries for faster performance. r=sicking.
--HG-- extra : transplant_source : %14T5%5BR%94%8Dn%95%B5%2CMD%E9%EB%F4%EE9%DB5
This commit is contained in:
parent
7cf0b507f9
commit
9620d104ce
@ -1160,12 +1160,12 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ( value > :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" OR ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(" > :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( value > :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" LIMIT ");
|
||||
break;
|
||||
@ -1178,7 +1178,7 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value > :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
@ -1190,12 +1190,13 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ( value < :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" OR ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(" < :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( value < :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" ) ") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" LIMIT ");
|
||||
break;
|
||||
@ -1208,7 +1209,7 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value < :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
@ -1251,7 +1252,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
if (mIndex->IsAutoIncrement()) {
|
||||
objectTable.AssignLiteral("ai_object_data");
|
||||
objectDataIdColumn.AssignLiteral("ai_object_data_id");
|
||||
keyValueColumn.AssignLiteral("id");
|
||||
keyValueColumn.AssignLiteral("ai_object_data_id");
|
||||
if (mIndex->IsUnique()) {
|
||||
indexTable.AssignLiteral("ai_unique_index_data");
|
||||
}
|
||||
@ -1262,7 +1263,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
else {
|
||||
objectTable.AssignLiteral("object_data");
|
||||
objectDataIdColumn.AssignLiteral("object_data_id");
|
||||
keyValueColumn.AssignLiteral("key_value");
|
||||
keyValueColumn.AssignLiteral("object_data_key");
|
||||
if (mIndex->IsUnique()) {
|
||||
indexTable.AssignLiteral("unique_index_data");
|
||||
}
|
||||
@ -1271,11 +1272,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
|
||||
nsCString value = indexTable + NS_LITERAL_CSTRING(".value");
|
||||
nsCString data = objectTable + NS_LITERAL_CSTRING(".data");
|
||||
nsCString keyValue = objectTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
|
||||
nsCString keyValue = indexTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
|
||||
|
||||
nsCString keyRangeClause;
|
||||
if (mKeyRange) {
|
||||
@ -1304,16 +1302,21 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_NOTREACHED("Unknown direction!");
|
||||
}
|
||||
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + value +
|
||||
NS_LITERAL_CSTRING(", ") + keyValue +
|
||||
NS_LITERAL_CSTRING(", ") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + objectDataIdColumn +
|
||||
NS_LITERAL_CSTRING(" = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :id") +
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
NS_NAMED_LITERAL_CSTRING(dot, ".");
|
||||
NS_NAMED_LITERAL_CSTRING(commaspace, ", ");
|
||||
|
||||
nsCString data = objectTable + NS_LITERAL_CSTRING(".data");
|
||||
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + value + commaspace +
|
||||
keyValue + commaspace + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable + dot +
|
||||
objectDataIdColumn + NS_LITERAL_CSTRING(" = ") +
|
||||
objectTable + dot + id +
|
||||
NS_LITERAL_CSTRING(" WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :") + id +
|
||||
keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
|
||||
@ -1352,20 +1355,29 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
|
||||
// Now we need to make the query to get the next match.
|
||||
nsCAutoString queryStart = NS_LITERAL_CSTRING("SELECT ") + value +
|
||||
NS_LITERAL_CSTRING(", ") + keyValue +
|
||||
NS_LITERAL_CSTRING(", ") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + objectDataIdColumn +
|
||||
NS_LITERAL_CSTRING(" = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :id");
|
||||
commaspace + keyValue + commaspace + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable + dot +
|
||||
objectDataIdColumn + NS_LITERAL_CSTRING(" = ") +
|
||||
objectTable + dot + id +
|
||||
NS_LITERAL_CSTRING(" WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :") + id;
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(currentKey, "current_key");
|
||||
NS_NAMED_LITERAL_CSTRING(rangeKey, "range_key");
|
||||
NS_NAMED_LITERAL_CSTRING(objectKey, "object_key");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(andStr, " AND ");
|
||||
NS_NAMED_LITERAL_CSTRING(orStr, " OR ");
|
||||
NS_NAMED_LITERAL_CSTRING(ge, " >= :");
|
||||
NS_NAMED_LITERAL_CSTRING(gt, " > :");
|
||||
NS_NAMED_LITERAL_CSTRING(le, " <= :");
|
||||
NS_NAMED_LITERAL_CSTRING(lt, " < :");
|
||||
NS_NAMED_LITERAL_CSTRING(openparen, " ( ");
|
||||
NS_NAMED_LITERAL_CSTRING(closeparen, " ) ");
|
||||
NS_NAMED_LITERAL_CSTRING(limit, " LIMIT ");
|
||||
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
@ -1373,18 +1385,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" AND ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" > :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( ") + value +
|
||||
NS_LITERAL_CSTRING(" > :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" >= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + ge + currentKey + andStr +
|
||||
openparen + value + gt + currentKey + orStr + keyValue +
|
||||
gt + objectKey + closeparen + directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + ge + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
@ -1393,12 +1398,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" > :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" >= :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + gt + currentKey +
|
||||
directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + ge + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
@ -1407,18 +1410,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" AND ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" < :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( ") + value +
|
||||
NS_LITERAL_CSTRING(" < :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" <= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + le + currentKey + andStr +
|
||||
openparen + value + lt + currentKey + orStr + keyValue +
|
||||
lt + objectKey + closeparen + directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + le + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
@ -1427,12 +1423,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" < :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" <= :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + lt + currentKey +
|
||||
directionClause +limit;
|
||||
mContinueToQuery = queryStart + andStr + value + le + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1954,7 +1954,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
NS_LITERAL_CSTRING(" WHERE object_store_id = :") +
|
||||
id + keyRangeClause + directionClause;
|
||||
id + keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt =
|
||||
mTransaction->GetCachedStatement(firstQuery);
|
||||
@ -2033,7 +2034,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
NS_LITERAL_CSTRING(" WHERE object_store_id = :") + id +
|
||||
keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
|
||||
mContinueToQuery = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define DB_SCHEMA_VERSION 5
|
||||
#define DB_SCHEMA_VERSION 6
|
||||
|
||||
#define BEGIN_INDEXEDDB_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace indexedDB {
|
||||
|
@ -121,11 +121,10 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `object_store`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_store ("
|
||||
"id INTEGER, "
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"name TEXT NOT NULL, "
|
||||
"key_path TEXT NOT NULL, "
|
||||
"auto_increment INTEGER NOT NULL DEFAULT 0, "
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (name)"
|
||||
");"
|
||||
));
|
||||
@ -134,41 +133,30 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `object_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_data ("
|
||||
"id INTEGER, "
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"key_value DEFAULT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"key_value DEFAULT NULL, " // NONE affinity
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (object_store_id, key_value), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE UNIQUE INDEX key_index "
|
||||
"ON object_data (key_value, object_store_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_object_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_object_data ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, id), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE UNIQUE INDEX ai_key_index "
|
||||
"ON ai_object_data (id, object_store_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `index`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_store_index ("
|
||||
@ -189,12 +177,11 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
@ -203,21 +190,21 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from object_data and object_store fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX value_index "
|
||||
"ON index_data (index_id, value);"
|
||||
"CREATE INDEX index_data_object_data_id_index "
|
||||
"ON index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `unique_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE unique_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE "
|
||||
@ -227,14 +214,20 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from object_data and object_store fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX unique_index_data_object_data_id_index "
|
||||
"ON unique_index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
@ -243,21 +236,22 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from ai_object_data and object_store
|
||||
// fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_value_index "
|
||||
"ON ai_index_data (index_id, value);"
|
||||
"CREATE INDEX ai_index_data_ai_object_data_id_index "
|
||||
"ON ai_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_unique_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_unique_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"UNIQUE (index_id, value), "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
@ -266,6 +260,14 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from ai_object_data and object_store
|
||||
// fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_unique_index_data_ai_object_data_id_index "
|
||||
"ON ai_unique_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -377,7 +379,372 @@ UpgradeSchemaFrom4To5(mozIStorageConnection* aConnection)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = aConnection->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||
rv = aConnection->SetSchemaVersion(5);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UpgradeSchemaFrom5To6(mozIStorageConnection* aConnection)
|
||||
{
|
||||
mozStorageTransaction transaction(aConnection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
// Turn off foreign key constraints before we do anything here.
|
||||
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"PRAGMA foreign_keys = OFF;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// First, drop all the indexes we're no longer going to use.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX key_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX ai_key_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX value_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX ai_value_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now, reorder the columns of object_data to put the blob data last. We do
|
||||
// this by copying into a temporary table, dropping the original, then copying
|
||||
// back into a newly created table.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id, "
|
||||
"key_value, "
|
||||
"data "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT id, object_store_id, key_value, data "
|
||||
"FROM object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_data ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"key_value DEFAULT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, key_value), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO object_data "
|
||||
"SELECT id, object_store_id, key_value, data "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We need to add a unique constraint to our ai_object_data table. Copy all
|
||||
// the data out of it using a temporary table as before.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id, "
|
||||
"data "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT id, object_store_id, data "
|
||||
"FROM ai_object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_object_data ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, id), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO ai_object_data "
|
||||
"SELECT id, object_store_id, data "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"object_data_key, "
|
||||
"object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT OR IGNORE INTO index_data "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX index_data_object_data_id_index "
|
||||
"ON index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the unique_index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"object_data_key, "
|
||||
"object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE unique_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO unique_index_data "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX unique_index_data_object_data_id_index "
|
||||
"ON unique_index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the ai_index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"ai_object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM ai_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT OR IGNORE INTO ai_index_data "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_index_data_ai_object_data_id_index "
|
||||
"ON ai_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the ai_unique_index_data table. We're reordering the columns as well
|
||||
// as changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"ai_object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM ai_unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_unique_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"UNIQUE (index_id, value), "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO ai_unique_index_data "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_unique_index_data_ai_object_data_id_index "
|
||||
"ON ai_unique_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->SetSchemaVersion(6);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
@ -393,14 +760,6 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIFile> dbDirectory;
|
||||
nsresult rv = aDBFile->GetParent(getter_AddRefs(dbDirectory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool exists;
|
||||
rv = aDBFile->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(quotaVFSName, "quota");
|
||||
|
||||
nsCOMPtr<mozIStorageServiceQuotaManagement> ss =
|
||||
@ -408,15 +767,13 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
NS_ENSURE_TRUE(ss, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> connection;
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
nsresult rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
// Nuke the database file. The web services can recreate their data.
|
||||
rv = aDBFile->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
exists = false;
|
||||
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
}
|
||||
@ -427,42 +784,49 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
rv = connection->GetSchemaVersion(&schemaVersion);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
if (!schemaVersion) {
|
||||
// Brand new file, initialize our tables.
|
||||
mozStorageTransaction transaction(connection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
rv = CreateTables(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CreateMetaData(connection, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
||||
schemaVersion == DB_SCHEMA_VERSION,
|
||||
"CreateTables set a bad schema version!");
|
||||
}
|
||||
else if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
// This logic needs to change next time we change the schema!
|
||||
PR_STATIC_ASSERT(DB_SCHEMA_VERSION == 5);
|
||||
if (schemaVersion == 4) {
|
||||
rv = UpgradeSchemaFrom4To5(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
// Nuke it from orbit, it's the only way to be sure.
|
||||
if (exists) {
|
||||
// If the connection is not at the right schema version, nuke it.
|
||||
rv = aDBFile->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PR_STATIC_ASSERT(DB_SCHEMA_VERSION == 6);
|
||||
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mozStorageTransaction transaction(connection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
rv = CreateTables(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CreateMetaData(connection, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
#define UPGRADE_SCHEMA_CASE(_from, _to) \
|
||||
if (schemaVersion == _from) { \
|
||||
rv = UpgradeSchemaFrom##_from##To##_to (connection); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
\
|
||||
rv = connection->GetSchemaVersion(&schemaVersion); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
\
|
||||
NS_ASSERTION(schemaVersion == _to, "Bad upgrade function!"); \
|
||||
}
|
||||
|
||||
// Check to make sure that the database schema is correct again.
|
||||
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
||||
schemaVersion == DB_SCHEMA_VERSION,
|
||||
"CreateTables failed!");
|
||||
UPGRADE_SCHEMA_CASE(4, 5)
|
||||
UPGRADE_SCHEMA_CASE(5, 6)
|
||||
|
||||
#undef UPGRADE_SCHEMA_CASE
|
||||
|
||||
if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
NS_WARNING("Unable to open IndexedDB database, schema doesn't match");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on foreign key constraints.
|
||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
|
Loading…
Reference in New Issue
Block a user