Modern IDB: SQLite backend mismanages key generator values.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / SQLiteIDBBackingStore.cpp
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "SQLiteIDBBackingStore.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "FileSystem.h"
32 #include "IDBBindingUtilities.h"
33 #include "IDBDatabaseException.h"
34 #include "IDBGetResult.h"
35 #include "IDBKeyData.h"
36 #include "IDBObjectStoreInfo.h"
37 #include "IDBSerialization.h"
38 #include "IDBTransactionInfo.h"
39 #include "IndexKey.h"
40 #include "Logging.h"
41 #include "SQLiteDatabase.h"
42 #include "SQLiteFileSystem.h"
43 #include "SQLiteIDBCursor.h"
44 #include "SQLiteStatement.h"
45 #include "SQLiteTransaction.h"
46 #include "ThreadSafeDataBuffer.h"
47 #include <wtf/NeverDestroyed.h>
48
49 using namespace JSC;
50
51 namespace WebCore {
52 namespace IDBServer {
53
54 // Current version of the metadata schema being used in the metadata database.
55 static const int currentMetadataVersion = 1;
56
57 static int idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
58 {
59     IDBKeyData a, b;
60     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(aBuffer), aLength, a)) {
61         LOG_ERROR("Unable to deserialize key A in collation function.");
62
63         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
64         // We arbitrarily choose "A > B"
65         return 1;
66     }
67     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(bBuffer), bLength, b)) {
68         LOG_ERROR("Unable to deserialize key B in collation function.");
69
70         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
71         // We arbitrarily choose "A > B"
72         return 1;
73     }
74
75     return a.compare(b);
76 }
77
78 static const String v1RecordsTableSchema(const String& tableName)
79 {
80     return makeString("CREATE TABLE ", tableName, " (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value NOT NULL ON CONFLICT FAIL)");
81 }
82
83 static const String& v1RecordsTableSchema()
84 {
85     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("Records"));
86     return v1RecordsTableSchemaString;
87 }
88
89 static const String& v1RecordsTableSchemaAlternate()
90 {
91     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("\"Records\""));
92     return v1RecordsTableSchemaString;
93 }
94
95 static const String v2RecordsTableSchema(const String& tableName)
96 {
97     return makeString("CREATE TABLE ", tableName, " (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL)");
98 }
99
100 static const String& v2RecordsTableSchema()
101 {
102     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("Records"));
103     return v2RecordsTableSchemaString;
104 }
105
106 static const String& v2RecordsTableSchemaAlternate()
107 {
108     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("\"Records\""));
109     return v2RecordsTableSchemaString;
110 }
111
112 SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory)
113     : m_identifier(identifier)
114 {
115     m_absoluteDatabaseDirectory = identifier.databaseDirectoryRelativeToRoot(databaseRootDirectory);
116 }
117
118 SQLiteIDBBackingStore::~SQLiteIDBBackingStore()
119 {
120     if (m_sqliteDB)
121         m_sqliteDB->close();
122
123     if (m_vm) {
124         JSLockHolder locker(m_vm.get());
125         m_globalObject.clear();
126         m_vm = nullptr;
127     }
128 }
129
130
131 void SQLiteIDBBackingStore::initializeVM()
132 {
133     if (!m_vm) {
134         ASSERT(!m_globalObject);
135         m_vm = VM::create();
136
137         JSLockHolder locker(m_vm.get());
138         m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
139     }
140 }
141
142 VM& SQLiteIDBBackingStore::vm()
143 {
144     initializeVM();
145     return *m_vm;
146 }
147
148 JSGlobalObject& SQLiteIDBBackingStore::globalObject()
149 {
150     initializeVM();
151     return **m_globalObject;
152 }
153
154 static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
155 {
156     String currentSchema;
157     {
158         // Fetch the schema for an existing records table.
159         SQLiteStatement statement(database, "SELECT type, sql FROM sqlite_master WHERE tbl_name='Records'");
160         if (statement.prepare() != SQLITE_OK) {
161             LOG_ERROR("Unable to prepare statement to fetch schema for the Records table.");
162             return false;
163         }
164
165         int sqliteResult = statement.step();
166
167         // If there is no Records table at all, create it and then bail.
168         if (sqliteResult == SQLITE_DONE) {
169             if (!database.executeCommand(v2RecordsTableSchema())) {
170                 LOG_ERROR("Could not create Records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
171                 return false;
172             }
173
174             return true;
175         }
176
177         if (sqliteResult != SQLITE_ROW) {
178             LOG_ERROR("Error executing statement to fetch schema for the Records table.");
179             return false;
180         }
181
182         currentSchema = statement.getColumnText(1);
183     }
184
185     ASSERT(!currentSchema.isEmpty());
186
187     // If the schema in the backing store is the current schema, we're done.
188     if (currentSchema == v2RecordsTableSchema() || currentSchema == v2RecordsTableSchemaAlternate())
189         return true;
190
191     // If the record table is not the current schema then it must be one of the previous schemas.
192     // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
193     if (currentSchema != v1RecordsTableSchema() && currentSchema != v1RecordsTableSchemaAlternate())
194         RELEASE_ASSERT_NOT_REACHED();
195
196     SQLiteTransaction transaction(database);
197     transaction.begin();
198
199     // Create a temporary table with the correct schema and migrate all existing content over.
200     if (!database.executeCommand(v2RecordsTableSchema("_Temp_Records"))) {
201         LOG_ERROR("Could not create temporary records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
202         return false;
203     }
204
205     if (!database.executeCommand("INSERT INTO _Temp_Records SELECT * FROM Records")) {
206         LOG_ERROR("Could not migrate existing Records content (%i) - %s", database.lastError(), database.lastErrorMsg());
207         return false;
208     }
209
210     if (!database.executeCommand("DROP TABLE Records")) {
211         LOG_ERROR("Could not drop existing Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
212         return false;
213     }
214
215     if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records")) {
216         LOG_ERROR("Could not rename temporary Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
217         return false;
218     }
219
220     transaction.commit();
221
222     return true;
223 }
224
225 bool SQLiteIDBBackingStore::ensureValidRecordsTable()
226 {
227     ASSERT(m_sqliteDB);
228     ASSERT(m_sqliteDB->isOpen());
229
230     if (!createOrMigrateRecordsTableIfNecessary(*m_sqliteDB))
231         return false;
232
233     // Whether the updated records table already existed or if it was just created and the data migrated over,
234     // make sure the uniqueness index exists.
235     if (!m_sqliteDB->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);")) {
236         LOG_ERROR("Could not create RecordsIndex on Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
237         return false;
238     }
239
240     return true;
241 }
242
243 std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo()
244 {
245     ASSERT(m_sqliteDB);
246     ASSERT(m_sqliteDB->isOpen());
247
248     if (!m_sqliteDB->executeCommand("CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);")) {
249         LOG_ERROR("Could not create IDBDatabaseInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
250         m_sqliteDB = nullptr;
251         return nullptr;
252     }
253
254     if (!m_sqliteDB->executeCommand("CREATE TABLE ObjectStoreInfo (id INTEGER PRIMARY KEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, autoInc INTEGER NOT NULL ON CONFLICT FAIL, maxIndexID INTEGER NOT NULL ON CONFLICT FAIL);")) {
255         LOG_ERROR("Could not create ObjectStoreInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
256         m_sqliteDB = nullptr;
257         return nullptr;
258     }
259
260     if (!m_sqliteDB->executeCommand("CREATE TABLE IndexInfo (id INTEGER NOT NULL ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, isUnique INTEGER NOT NULL ON CONFLICT FAIL, multiEntry INTEGER NOT NULL ON CONFLICT FAIL);")) {
261         LOG_ERROR("Could not create IndexInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
262         m_sqliteDB = nullptr;
263         return nullptr;
264     }
265
266     if (!m_sqliteDB->executeCommand("CREATE TABLE IndexRecords (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL);")) {
267         LOG_ERROR("Could not create IndexRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
268         m_sqliteDB = nullptr;
269         return nullptr;
270     }
271
272     if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
273         LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
274         m_sqliteDB = nullptr;
275         return nullptr;
276     }
277
278     {
279         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);"));
280         if (sql.prepare() != SQLITE_OK
281             || sql.bindInt(1, currentMetadataVersion) != SQLITE_OK
282             || sql.step() != SQLITE_DONE) {
283             LOG_ERROR("Could not insert database metadata version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
284             m_sqliteDB = nullptr;
285             return nullptr;
286         }
287     }
288     {
289         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseName', ?);"));
290         if (sql.prepare() != SQLITE_OK
291             || sql.bindText(1, m_identifier.databaseName()) != SQLITE_OK
292             || sql.step() != SQLITE_DONE) {
293             LOG_ERROR("Could not insert database name into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
294             m_sqliteDB = nullptr;
295             return nullptr;
296         }
297     }
298     {
299         // Database versions are defined to be a uin64_t in the spec but sqlite3 doesn't support native binding of unsigned integers.
300         // Therefore we'll store the version as a String.
301         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseVersion', ?);"));
302         if (sql.prepare() != SQLITE_OK
303             || sql.bindText(1, String::number(0)) != SQLITE_OK
304             || sql.step() != SQLITE_DONE) {
305             LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
306             m_sqliteDB = nullptr;
307             return nullptr;
308         }
309     }
310
311     if (!m_sqliteDB->executeCommand(ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MaxObjectStoreID', 1);"))) {
312         LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
313         m_sqliteDB = nullptr;
314         return nullptr;
315     }
316
317     // This initial database info matches the default values we just put into the metadata database.
318     return std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
319 }
320
321 std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::extractExistingDatabaseInfo()
322 {
323     ASSERT(m_sqliteDB);
324
325     if (!m_sqliteDB->tableExists(ASCIILiteral("IDBDatabaseInfo")))
326         return nullptr;
327
328     String databaseName;
329     {
330         SQLiteStatement sql(*m_sqliteDB, "SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseName';");
331         if (sql.isColumnNull(0))
332             return nullptr;
333         databaseName = sql.getColumnText(0);
334         if (databaseName != m_identifier.databaseName()) {
335             LOG_ERROR("Database name in the info database ('%s') does not match the expected name ('%s')", databaseName.utf8().data(), m_identifier.databaseName().utf8().data());
336             return nullptr;
337         }
338     }
339     uint64_t databaseVersion;
340     {
341         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseVersion';"));
342         if (sql.isColumnNull(0))
343             return nullptr;
344         String stringVersion = sql.getColumnText(0);
345         bool ok;
346         databaseVersion = stringVersion.toUInt64Strict(&ok);
347         if (!ok) {
348             LOG_ERROR("Database version on disk ('%s') does not cleanly convert to an unsigned 64-bit integer version", stringVersion.utf8().data());
349             return nullptr;
350         }
351     }
352
353     auto databaseInfo = std::make_unique<IDBDatabaseInfo>(databaseName, databaseVersion);
354
355     {
356         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, keyPath, autoInc, maxIndexID FROM ObjectStoreInfo;"));
357         if (sql.prepare() != SQLITE_OK)
358             return nullptr;
359
360         int result = sql.step();
361         while (result == SQLITE_ROW) {
362             uint64_t objectStoreID = sql.getColumnInt64(0);
363             String objectStoreName = sql.getColumnText(1);
364
365             Vector<char> keyPathBuffer;
366             sql.getColumnBlobAsVector(2, keyPathBuffer);
367
368             IDBKeyPath objectStoreKeyPath;
369             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), objectStoreKeyPath)) {
370                 LOG_ERROR("Unable to extract key path from database");
371                 return nullptr;
372             }
373
374             bool autoIncrement = sql.getColumnInt(3);
375
376             databaseInfo->addExistingObjectStore({ objectStoreID, objectStoreName, objectStoreKeyPath, autoIncrement });
377
378             result = sql.step();
379         }
380
381         if (result != SQLITE_DONE) {
382             LOG_ERROR("Error fetching object store info from database on disk");
383             return nullptr;
384         }
385     }
386
387     {
388         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
389         if (sql.prepare() != SQLITE_OK)
390             return nullptr;
391
392         int result = sql.step();
393         while (result == SQLITE_ROW) {
394             uint64_t indexID = sql.getColumnInt64(0);
395             String indexName = sql.getColumnText(1);
396             uint64_t objectStoreID = sql.getColumnInt64(2);
397
398             Vector<char> keyPathBuffer;
399             sql.getColumnBlobAsVector(3, keyPathBuffer);
400
401             IDBKeyPath indexKeyPath;
402             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexKeyPath)) {
403                 LOG_ERROR("Unable to extract key path from database");
404                 return nullptr;
405             }
406
407             bool unique = sql.getColumnInt(4);
408             bool multiEntry = sql.getColumnInt(5);
409
410             auto objectStore = databaseInfo->infoForExistingObjectStore(objectStoreID);
411             if (!objectStore) {
412                 LOG_ERROR("Found index referring to a non-existant object store");
413                 return nullptr;
414             }
415
416             objectStore->addExistingIndex({ indexID, objectStoreID, indexName, indexKeyPath, unique, multiEntry });
417
418             result = sql.step();
419         }
420
421         if (result != SQLITE_DONE) {
422             LOG_ERROR("Error fetching index info from database on disk");
423             return nullptr;
424         }
425     }
426
427     return databaseInfo;
428 }
429
430 String SQLiteIDBBackingStore::filenameForDatabaseName() const
431 {
432     ASSERT(!m_identifier.databaseName().isNull());
433
434     if (m_identifier.databaseName().isEmpty())
435         return "%00";
436
437     String filename = encodeForFileName(m_identifier.databaseName());
438     filename.replace('.', "%2E");
439
440     return filename;
441 }
442
443 String SQLiteIDBBackingStore::fullDatabaseDirectory() const
444 {
445     ASSERT(!m_identifier.databaseName().isNull());
446
447     return pathByAppendingComponent(m_absoluteDatabaseDirectory, filenameForDatabaseName());
448 }
449
450 String SQLiteIDBBackingStore::fullDatabasePath() const
451 {
452     ASSERT(!m_identifier.databaseName().isNull());
453
454     return pathByAppendingComponent(fullDatabaseDirectory(), "IndexedDB.sqlite3");
455 }
456
457 const IDBDatabaseInfo& SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
458 {
459     LOG(IndexedDB, "SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s", m_identifier.databaseName().utf8().data());
460
461     if (m_databaseInfo)
462         return *m_databaseInfo;
463
464     m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
465
466     makeAllDirectories(fullDatabaseDirectory());
467     String dbFilename = fullDatabasePath();
468
469     m_sqliteDB = std::make_unique<SQLiteDatabase>();
470     if (!m_sqliteDB->open(dbFilename)) {
471         LOG_ERROR("Failed to open SQLite database at path '%s'", dbFilename.utf8().data());
472         m_sqliteDB = nullptr;
473     }
474
475     if (!m_sqliteDB)
476         return *m_databaseInfo;
477
478     m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
479         return idbKeyCollate(aLength, a, bLength, b);
480     });
481
482     if (!ensureValidRecordsTable()) {
483         LOG_ERROR("Error creating or migrating Records table in database");
484         m_sqliteDB = nullptr;
485         return *m_databaseInfo;
486     }
487
488     auto databaseInfo = extractExistingDatabaseInfo();
489     if (!databaseInfo)
490         databaseInfo = createAndPopulateInitialDatabaseInfo();
491
492     if (!databaseInfo)
493         LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data());
494     else
495         m_databaseInfo = WTFMove(databaseInfo);
496
497     return *m_databaseInfo;
498 }
499
500 IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo& info)
501 {
502     LOG(IndexedDB, "SQLiteIDBBackingStore::beginTransaction - %s", info.identifier().loggingString().utf8().data());
503
504     ASSERT(m_sqliteDB);
505     ASSERT(m_sqliteDB->isOpen());
506
507     auto addResult = m_transactions.add(info.identifier(), nullptr);
508     if (!addResult.isNewEntry) {
509         LOG_ERROR("Attempt to establish transaction identifier that already exists");
510         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to establish transaction identifier that already exists") };
511     }
512
513     addResult.iterator->value = std::make_unique<SQLiteIDBTransaction>(*this, info);
514     return addResult.iterator->value->begin(*m_sqliteDB);
515 }
516
517 IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier& identifier)
518 {
519     LOG(IndexedDB, "SQLiteIDBBackingStore::abortTransaction - %s", identifier.loggingString().utf8().data());
520
521     ASSERT(m_sqliteDB);
522     ASSERT(m_sqliteDB->isOpen());
523
524     auto transaction = m_transactions.take(identifier);
525     if (!transaction) {
526         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
527         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to abort a transaction that hasn't been established") };
528     }
529
530     return transaction->abort();
531 }
532
533 IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier& identifier)
534 {
535     LOG(IndexedDB, "SQLiteIDBBackingStore::commitTransaction - %s", identifier.loggingString().utf8().data());
536
537     ASSERT(m_sqliteDB);
538     ASSERT(m_sqliteDB->isOpen());
539
540     auto transaction = m_transactions.take(identifier);
541     if (!transaction) {
542         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
543         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit a transaction that hasn't been established") };
544     }
545
546     return transaction->commit();
547 }
548
549 IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
550 {
551     LOG(IndexedDB, "SQLiteIDBBackingStore::createObjectStore - adding OS %s with ID %" PRIu64, info.name().utf8().data(), info.identifier());
552
553     ASSERT(m_sqliteDB);
554     ASSERT(m_sqliteDB->isOpen());
555
556     auto* transaction = m_transactions.get(transactionIdentifier);
557     if (!transaction || !transaction->inProgress()) {
558         LOG_ERROR("Attempt to create an object store without an in-progress transaction");
559         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store without an in-progress transaction") };
560     }
561     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
562         LOG_ERROR("Attempt to create an object store in a non-version-change transaction");
563         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store in a non-version-change transaction") };
564     }
565
566     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
567     if (!keyPathBlob) {
568         LOG_ERROR("Unable to serialize IDBKeyPath to save in database for new object store");
569         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to save in database for new object store") };
570     }
571
572     {
573         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
574         if (sql.prepare() != SQLITE_OK
575             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
576             || sql.bindText(2, info.name()) != SQLITE_OK
577             || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
578             || sql.bindInt(4, info.autoIncrement()) != SQLITE_OK
579             || sql.bindInt64(5, info.maxIndexID()) != SQLITE_OK
580             || sql.step() != SQLITE_DONE) {
581             LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
582             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not create object store") };
583         }
584     }
585
586     {
587         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, 0);"));
588         if (sql.prepare() != SQLITE_OK
589             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
590             || sql.step() != SQLITE_DONE) {
591             LOG_ERROR("Could not seed initial key generator value for ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
592             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not seed initial key generator value for object store") };
593         }
594     }
595
596     return { };
597 }
598
599 IDBError SQLiteIDBBackingStore::deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
600 {
601     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteObjectStore - object store %" PRIu64, objectStoreIdentifier);
602
603     ASSERT(m_sqliteDB);
604     ASSERT(m_sqliteDB->isOpen());
605
606     auto* transaction = m_transactions.get(transactionIdentifier);
607     if (!transaction || !transaction->inProgress()) {
608         LOG_ERROR("Attempt to delete an object store without an in-progress transaction");
609         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store without an in-progress transaction") };
610     }
611     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
612         LOG_ERROR("Attempt to delete an object store in a non-version-change transaction");
613         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store in a non-version-change transaction") };
614     }
615
616     // Delete the ObjectStore record
617     {
618         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
619         if (sql.prepare() != SQLITE_OK
620             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
621             || sql.step() != SQLITE_DONE) {
622             LOG_ERROR("Could not delete object store id %" PRIi64 " from ObjectStoreInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
623             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete object store") };
624         }
625     }
626
627     // Delete the ObjectStore's key generator record if there is one.
628     {
629         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM KeyGenerators WHERE objectStoreID = ?;"));
630         if (sql.prepare() != SQLITE_OK
631             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
632             || sql.step() != SQLITE_DONE) {
633             LOG_ERROR("Could not delete object store from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
634             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete key generator for deleted object store") };
635         }
636     }
637
638     // Delete all associated records
639     {
640         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
641         if (sql.prepare() != SQLITE_OK
642             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
643             || sql.step() != SQLITE_DONE) {
644             LOG_ERROR("Could not delete records for object store %" PRIi64 " (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
645             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete records for deleted object store") };
646         }
647     }
648
649     // Delete all associated Indexes
650     {
651         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
652         if (sql.prepare() != SQLITE_OK
653             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
654             || sql.step() != SQLITE_DONE) {
655             LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
656             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex for deleted object store") };
657         }
658     }
659
660     // Delete all associated Index records
661     {
662         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
663         if (sql.prepare() != SQLITE_OK
664             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
665             || sql.step() != SQLITE_DONE) {
666             LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
667             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex records for deleted object store") };
668         }
669     }
670
671     return true;
672 }
673
674 IDBError SQLiteIDBBackingStore::clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID)
675 {
676     LOG(IndexedDB, "SQLiteIDBBackingStore::clearObjectStore - object store %" PRIu64, objectStoreID);
677
678     ASSERT(m_sqliteDB);
679     ASSERT(m_sqliteDB->isOpen());
680
681     auto* transaction = m_transactions.get(transactionIdentifier);
682     if (!transaction || !transaction->inProgress()) {
683         LOG_ERROR("Attempt to clear an object store without an in-progress transaction");
684         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store without an in-progress transaction") };
685     }
686     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
687         LOG_ERROR("Attempt to clear an object store in a read-only transaction");
688         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store in a read-only transaction") };
689     }
690
691     {
692         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
693         if (sql.prepare() != SQLITE_OK
694             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
695             || sql.step() != SQLITE_DONE) {
696             LOG_ERROR("Could not clear records from object store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
697             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to clear object store") };
698         }
699     }
700
701     {
702         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
703         if (sql.prepare() != SQLITE_OK
704             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
705             || sql.step() != SQLITE_DONE) {
706             LOG_ERROR("Could not delete records from index record store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
707             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to delete index records while clearing object store") };
708         }
709     }
710
711     transaction->notifyCursorsOfChanges(objectStoreID);
712
713     return { };
714 }
715
716 IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
717 {
718     LOG(IndexedDB, "SQLiteIDBBackingStore::createIndex - ObjectStore %" PRIu64 ", Index %" PRIu64, info.objectStoreIdentifier(), info.identifier());
719     ASSERT(m_sqliteDB);
720     ASSERT(m_sqliteDB->isOpen());
721
722     auto* transaction = m_transactions.get(transactionIdentifier);
723     if (!transaction || !transaction->inProgress()) {
724         LOG_ERROR("Attempt to create an index without an in-progress transaction");
725         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index without an in-progress transaction") };
726     }
727     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
728         LOG_ERROR("Attempt to create an index in a non-version-change transaction");
729         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index in a non-version-change transaction") };
730     }
731
732     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
733     if (!keyPathBlob) {
734         LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
735         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to create index in database") };
736     }
737
738     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
739     if (sql.prepare() != SQLITE_OK
740         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
741         || sql.bindText(2, info.name()) != SQLITE_OK
742         || sql.bindInt64(3, info.objectStoreIdentifier()) != SQLITE_OK
743         || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
744         || sql.bindInt(5, info.unique()) != SQLITE_OK
745         || sql.bindInt(6, info.multiEntry()) != SQLITE_OK
746         || sql.step() != SQLITE_DONE) {
747         LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
748         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to create index in database") };
749     }
750
751     // Write index records for any records that already exist in this object store.
752
753     auto cursor = transaction->maybeOpenBackingStoreCursor(info.objectStoreIdentifier(), 0, IDBKeyRangeData::allKeys());
754
755     if (!cursor) {
756         LOG_ERROR("Cannot open cursor to populate indexes in database");
757         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
758     }
759
760     while (!cursor->currentKey().isNull()) {
761         auto& key = cursor->currentKey();
762         auto valueBuffer = ThreadSafeDataBuffer::copyVector(cursor->currentValueBuffer());
763
764         IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
765         if (!error.isNull()) {
766             // FIXME: Remove this newly added index.
767             return error;
768         }
769
770         if (!cursor->advance(1)) {
771             LOG_ERROR("Error advancing cursor while indexing existing records for new index.");
772             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error advancing cursor while indexing existing records for new index") };
773         }
774     }
775
776     return { };
777 }
778
779 IDBError SQLiteIDBBackingStore::uncheckedHasIndexRecord(const IDBIndexInfo& info, const IDBKeyData& indexKey, bool& hasRecord)
780 {
781     hasRecord = false;
782
783     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
784     if (!indexKeyBuffer) {
785         LOG_ERROR("Unable to serialize index key to be stored in the database");
786         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for index record in database") };
787     }
788
789     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT rowid FROM IndexRecords WHERE indexID = ? AND objectStoreID = ? AND key = CAST(? AS TEXT);"));
790     if (sql.prepare() != SQLITE_OK
791         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
792         || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
793         || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK) {
794         LOG_ERROR("Error checking for index record in database");
795         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for index record in database") };
796     }
797
798     int sqlResult = sql.step();
799     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
800         return { };
801
802     if (sqlResult != SQLITE_ROW) {
803         // There was an error fetching the record from the database.
804         LOG_ERROR("Could not check if key exists in index (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
805         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in index") };
806     }
807
808     hasRecord = true;
809     return { };
810 }
811
812 IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo& info, const IDBKeyData& key, const IndexKey& indexKey)
813 {
814     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexKey - (%" PRIu64 ") %s, %s", info.identifier(), key.loggingString().utf8().data(), indexKey.asOneKey().loggingString().utf8().data());
815
816     Vector<IDBKeyData> indexKeys;
817     if (info.multiEntry())
818         indexKeys = indexKey.multiEntry();
819     else
820         indexKeys.append(indexKey.asOneKey());
821
822     if (info.unique()) {
823         bool hasRecord;
824         IDBError error;
825         for (auto& indexKey : indexKeys) {
826             error = uncheckedHasIndexRecord(info, indexKey, hasRecord);
827             if (!error.isNull())
828                 return error;
829             if (hasRecord)
830                 return IDBError(IDBDatabaseException::ConstraintError);
831         }
832     }
833
834     for (auto& indexKey : indexKeys) {
835         auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
836         if (!error.isNull()) {
837             LOG_ERROR("Unable to put index record for newly created index");
838             return error;
839         }
840     }
841
842     return { };
843 }
844
845 IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
846 {
847     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexRecord - %s, %s", keyValue.loggingString().utf8().data(), indexKey.loggingString().utf8().data());
848
849     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
850     if (!indexKeyBuffer) {
851         LOG_ERROR("Unable to serialize index key to be stored in the database");
852         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize index key to be stored in the database") };
853     }
854
855     RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
856     if (!valueBuffer) {
857         LOG_ERROR("Unable to serialize the value to be stored in the database");
858         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize value to be stored in the database") };
859     }
860
861     {
862         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));"));
863         if (sql.prepare() != SQLITE_OK
864             || sql.bindInt64(1, indexID) != SQLITE_OK
865             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
866             || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK
867             || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLITE_OK
868             || sql.step() != SQLITE_DONE) {
869             LOG_ERROR("Could not put index record for index %" PRIi64 " in object store %" PRIi64 " in Records table (%i) - %s", indexID, objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
870             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error putting index record into database") };
871         }
872     }
873
874     return { };
875 }
876
877
878 IDBError SQLiteIDBBackingStore::deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier)
879 {
880     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteIndex - object store %" PRIu64, objectStoreIdentifier);
881
882     ASSERT(m_sqliteDB);
883     ASSERT(m_sqliteDB->isOpen());
884
885     auto* transaction = m_transactions.get(transactionIdentifier);
886     if (!transaction || !transaction->inProgress()) {
887         LOG_ERROR("Attempt to delete index without an in-progress transaction");
888         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index without an in-progress transaction") };
889     }
890
891     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
892         LOG_ERROR("Attempt to delete index during a non-version-change transaction");
893         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index during a non-version-change transaction") };
894     }
895
896     {
897         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
898         if (sql.prepare() != SQLITE_OK
899             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
900             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
901             || sql.step() != SQLITE_DONE) {
902             LOG_ERROR("Could not delete index id %" PRIi64 " from IndexInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
903             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index from database") };
904         }
905     }
906
907     {
908         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
909         if (sql.prepare() != SQLITE_OK
910             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
911             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
912             || sql.step() != SQLITE_DONE) {
913             LOG_ERROR("Could not delete index records for index id %" PRIi64 " from IndexRecords table (%i) - %s", indexIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
914             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index records from database") };
915         }
916     }
917
918     return { };
919 }
920
921 IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
922 {
923     LOG(IndexedDB, "SQLiteIDBBackingStore::keyExistsInObjectStore - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
924
925     ASSERT(m_sqliteDB);
926     ASSERT(m_sqliteDB->isOpen());
927
928     keyExists = false;
929
930     auto* transaction = m_transactions.get(transactionIdentifier);
931     if (!transaction || !transaction->inProgress()) {
932         LOG_ERROR("Attempt to see if key exists in objectstore without an in-progress transaction");
933         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to see if key exists in objectstore without an in-progress transaction") };
934     }
935
936     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
937     if (!keyBuffer) {
938         LOG_ERROR("Unable to serialize IDBKey to check for existence in object store");
939         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for existence in object store") };
940     }
941     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
942     if (sql.prepare() != SQLITE_OK
943         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
944         || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
945         LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
946         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to check for existence of IDBKey in object store") };
947     }
948
949     int sqlResult = sql.step();
950     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
951         return { };
952
953     if (sqlResult != SQLITE_ROW) {
954         // There was an error fetching the record from the database.
955         LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
956         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in object store") };
957     }
958
959     keyExists = true;
960     return { };
961 }
962
963 IDBError SQLiteIDBBackingStore::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const IDBKeyData& keyData)
964 {
965     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
966
967     ASSERT(m_sqliteDB);
968     ASSERT(m_sqliteDB->isOpen());
969     ASSERT(transaction.inProgress());
970     ASSERT(transaction.mode() != IndexedDB::TransactionMode::ReadOnly);
971     UNUSED_PARAM(transaction);
972
973     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
974     if (!keyBuffer) {
975         LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
976         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyData to be removed from the database") };
977     }
978
979     // Delete record from object store
980     {
981         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
982
983         if (sql.prepare() != SQLITE_OK
984             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
985             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
986             || sql.step() != SQLITE_DONE) {
987             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
988             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
989         }
990     }
991
992     // Delete record from indexes store
993     {
994         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
995
996         if (sql.prepare() != SQLITE_OK
997             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
998             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
999             || sql.step() != SQLITE_DONE) {
1000             LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1001             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete index entries for object store record") };
1002         }
1003     }
1004
1005     return { };
1006 }
1007
1008 IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange)
1009 {
1010     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRange - range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1011
1012     ASSERT(m_sqliteDB);
1013     ASSERT(m_sqliteDB->isOpen());
1014
1015     auto* transaction = m_transactions.get(transactionIdentifier);
1016     if (!transaction || !transaction->inProgress()) {
1017         LOG_ERROR("Attempt to delete range from database without an in-progress transaction");
1018         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete range from database without an in-progress transaction") };
1019     }
1020     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1021         LOG_ERROR("Attempt to delete records from an object store in a read-only transaction");
1022         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete records from an object store in a read-only transaction") };
1023     }
1024
1025     // If the range to delete is exactly one key we can delete it right now.
1026     if (keyRange.isExactlyOneKey()) {
1027         auto error = deleteRecord(*transaction, objectStoreID, keyRange.lowerKey);
1028         if (!error.isNull()) {
1029             LOG_ERROR("Failed to delete record for key '%s'", keyRange.lowerKey.loggingString().utf8().data());
1030             return error;
1031         }
1032
1033         return { };
1034     }
1035
1036     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, 0, keyRange);
1037     if (!cursor) {
1038         LOG_ERROR("Cannot open cursor to delete range of records from the database");
1039         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to delete range of records from the database") };
1040     }
1041
1042     Vector<IDBKeyData> keys;
1043     while (!cursor->didComplete() && !cursor->didError()) {
1044         keys.append(cursor->currentKey());
1045         cursor->advance(1);
1046     }
1047
1048     if (cursor->didError()) {
1049         LOG_ERROR("Cursor failed while accumulating range of records from the database");
1050         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while accumulating range of records from the database") };
1051     }
1052
1053     IDBError error;
1054     for (auto& key : keys) {
1055         error = deleteRecord(*transaction, objectStoreID, key);
1056         if (!error.isNull()) {
1057             LOG_ERROR("deleteRange: Error deleting keys in range");
1058             break;
1059         }
1060     }
1061
1062     transaction->notifyCursorsOfChanges(objectStoreID);
1063
1064     return error;
1065 }
1066
1067 IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1068 {
1069     JSLockHolder locker(vm());
1070
1071     auto jsValue = deserializeIDBValueDataToJSValue(*globalObject().globalExec(), value);
1072     if (jsValue.isUndefinedOrNull())
1073         return { };
1074
1075     IndexKey indexKey;
1076     generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey);
1077
1078     if (indexKey.isNull())
1079         return { };
1080
1081     return uncheckedPutIndexKey(info, key, indexKey);
1082 }
1083
1084 IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1085 {
1086     JSLockHolder locker(vm());
1087
1088     auto jsValue = deserializeIDBValueDataToJSValue(*globalObject().globalExec(), value);
1089     if (jsValue.isUndefinedOrNull())
1090         return { };
1091
1092     IDBError error;
1093     Vector<std::pair<uint64_t, IndexKey>> changedIndexRecords;
1094
1095     for (auto& index : info.indexMap().values()) {
1096         IndexKey indexKey;
1097         generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
1098
1099         if (indexKey.isNull())
1100             continue;
1101
1102         error = uncheckedPutIndexKey(index, key, indexKey);
1103         if (!error.isNull())
1104             break;
1105
1106         changedIndexRecords.append(std::make_pair(index.identifier(), indexKey));
1107     }
1108
1109     // FIXME: If any of the index puts failed, revert the ones that went through (changedIndexRecords).
1110
1111     return error;
1112 }
1113
1114 IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
1115 {
1116     LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreInfo.identifier());
1117
1118     ASSERT(m_sqliteDB);
1119     ASSERT(m_sqliteDB->isOpen());
1120     ASSERT(value.data());
1121
1122     auto* transaction = m_transactions.get(transactionIdentifier);
1123     if (!transaction || !transaction->inProgress()) {
1124         LOG_ERROR("Attempt to store a record in an object store without an in-progress transaction");
1125         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store without an in-progress transaction") };
1126     }
1127     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1128         LOG_ERROR("Attempt to store a record in an object store in a read-only transaction");
1129         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store in a read-only transaction") };
1130     }
1131
1132     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1133     if (!keyBuffer) {
1134         LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
1135         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
1136     }
1137     {
1138         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
1139         if (sql.prepare() != SQLITE_OK
1140             || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
1141             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1142             || sql.bindBlob(3, value.data()->data(), value.data()->size()) != SQLITE_OK
1143             || sql.step() != SQLITE_DONE) {
1144             LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreInfo.identifier(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1145             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
1146         }
1147     }
1148
1149     auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value);
1150
1151     // FIXME: If there was an error indexing this record, remove it.
1152
1153     transaction->notifyCursorsOfChanges(objectStoreInfo.identifier());
1154
1155     return error;
1156 }
1157
1158 IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, ThreadSafeDataBuffer& resultValue)
1159 {
1160     LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1161
1162     ASSERT(m_sqliteDB);
1163     ASSERT(m_sqliteDB->isOpen());
1164
1165     auto* transaction = m_transactions.get(transactionIdentifier);
1166     if (!transaction || !transaction->inProgress()) {
1167         LOG_ERROR("Attempt to get a record from database without an in-progress transaction");
1168         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get a record from database without an in-progress transaction") };
1169     }
1170
1171     RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(IDBKeyData(keyRange.lowerKey));
1172     if (!lowerBuffer) {
1173         LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
1174         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
1175     }
1176
1177     RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(IDBKeyData(keyRange.upperKey));
1178     if (!upperBuffer) {
1179         LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
1180         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
1181     }
1182
1183     {
1184         static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1185         static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1186         static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1187         static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1188
1189         const ASCIILiteral* query = nullptr;
1190
1191         if (keyRange.lowerOpen) {
1192             if (keyRange.upperOpen)
1193                 query = &lowerOpenUpperOpen.get();
1194             else
1195                 query = &lowerOpenUpperClosed.get();
1196         } else {
1197             if (keyRange.upperOpen)
1198                 query = &lowerClosedUpperOpen.get();
1199             else
1200                 query = &lowerClosedUpperClosed.get();
1201         }
1202
1203         ASSERT(query);
1204
1205         SQLiteStatement sql(*m_sqliteDB, *query);
1206         if (sql.prepare() != SQLITE_OK
1207             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1208             || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1209             || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1210             LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1211             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
1212         }
1213
1214         int sqlResult = sql.step();
1215
1216         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1217             // There was no record for the key in the database.
1218             return { };
1219         }
1220         if (sqlResult != SQLITE_ROW) {
1221             // There was an error fetching the record from the database.
1222             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1223             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
1224         }
1225
1226         Vector<uint8_t> buffer;
1227         sql.getColumnBlobAsVector(0, buffer);
1228         resultValue = ThreadSafeDataBuffer::adoptVector(buffer);
1229     }
1230
1231     return { };
1232 }
1233
1234 IDBError SQLiteIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t indexID, IndexedDB::IndexRecordType type, const IDBKeyRangeData& range, IDBGetResult& getResult)
1235 {
1236     LOG(IndexedDB, "SQLiteIDBBackingStore::getIndexRecord - %s", range.loggingString().utf8().data());
1237
1238     ASSERT(m_sqliteDB);
1239     ASSERT(m_sqliteDB->isOpen());
1240
1241     auto* transaction = m_transactions.get(transactionIdentifier);
1242     if (!transaction || !transaction->inProgress()) {
1243         LOG_ERROR("Attempt to get an index record from database without an in-progress transaction");
1244         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get an index record from database without an in-progress transaction") };
1245     }
1246
1247     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, indexID, range);
1248     if (!cursor) {
1249         LOG_ERROR("Cannot open cursor to perform index get in database");
1250         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to perform index get in database") };
1251     }
1252
1253     if (cursor->didError()) {
1254         LOG_ERROR("Cursor failed while looking up index record in database");
1255         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index record in database") };
1256     }
1257
1258     if (cursor->didComplete())
1259         getResult = { };
1260     else {
1261         if (type == IndexedDB::IndexRecordType::Key)
1262             getResult = { cursor->currentPrimaryKey() };
1263         else {
1264             getResult = { SharedBuffer::create(cursor->currentValueBuffer().data(), cursor->currentValueBuffer().size()) };
1265             getResult.setKeyData(cursor->currentPrimaryKey());
1266         }
1267     }
1268
1269     return { };
1270 }
1271
1272 IDBError SQLiteIDBBackingStore::getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& range, uint64_t& outCount)
1273 {
1274     LOG(IndexedDB, "SQLiteIDBBackingStore::getCount - object store %" PRIu64, objectStoreIdentifier);
1275     ASSERT(m_sqliteDB);
1276     ASSERT(m_sqliteDB->isOpen());
1277
1278     outCount = 0;
1279
1280     auto* transaction = m_transactions.get(transactionIdentifier);
1281     if (!transaction || !transaction->inProgress()) {
1282         LOG_ERROR("Attempt to get count from database without an in-progress transaction");
1283         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get count from database without an in-progress transaction") };
1284     }
1285
1286     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreIdentifier, indexIdentifier, range);
1287     if (!cursor) {
1288         LOG_ERROR("Cannot open cursor to populate indexes in database");
1289         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
1290     }
1291
1292     while (cursor->advance(1))
1293         ++outCount;
1294
1295     return { };
1296 }
1297
1298 IDBError SQLiteIDBBackingStore::uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t& outValue)
1299 {
1300     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT currentKey FROM KeyGenerators WHERE objectStoreID = ?;"));
1301     if (sql.prepare() != SQLITE_OK
1302         || sql.bindInt64(1, objectStoreID) != SQLITE_OK) {
1303         LOG_ERROR("Could not retrieve currentKey from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1304         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error getting current key generator value from database") };
1305     }
1306     int result = sql.step();
1307     if (result != SQLITE_ROW) {
1308         LOG_ERROR("Could not retreive key generator value for object store, but it should be there.");
1309         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error finding current key generator value in database") };
1310     }
1311
1312     int64_t value = sql.getColumnInt64(0);
1313     if (value < 0)
1314         return { IDBDatabaseException::ConstraintError, "Current key generator value from database is invalid" };
1315
1316     outValue = value;
1317     return { };
1318 }
1319
1320 IDBError SQLiteIDBBackingStore::uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value)
1321 {
1322     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, ?);"));
1323     if (sql.prepare() != SQLITE_OK
1324         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1325         || sql.bindInt64(2, value) != SQLITE_OK
1326         || sql.step() != SQLITE_DONE) {
1327         LOG_ERROR("Could not update key generator value (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1328         return { IDBDatabaseException::ConstraintError, "Error storing new key generator value in database" };
1329     }
1330
1331     return { };
1332 }
1333
1334 IDBError SQLiteIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t& generatedKey)
1335 {
1336     LOG(IndexedDB, "SQLiteIDBBackingStore::generateKeyNumber");
1337
1338     ASSERT(m_sqliteDB);
1339     ASSERT(m_sqliteDB->isOpen());
1340
1341     // The IndexedDatabase spec defines the max key generator value as 2^53;
1342     static uint64_t maxGeneratorValue = 0x20000000000000;
1343
1344     auto* transaction = m_transactions.get(transactionIdentifier);
1345     if (!transaction || !transaction->inProgress()) {
1346         LOG_ERROR("Attempt to generate key in database without an in-progress transaction");
1347         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in database without an in-progress transaction") };
1348     }
1349     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1350         LOG_ERROR("Attempt to generate key in a read-only transaction");
1351         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in a read-only transaction") };
1352     }
1353
1354     uint64_t currentValue;
1355     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
1356     if (!error.isNull())
1357         return error;
1358
1359     if (currentValue + 1 > maxGeneratorValue)
1360         return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
1361
1362     generatedKey = currentValue + 1;
1363     return uncheckedSetKeyGeneratorValue(objectStoreID, generatedKey);
1364 }
1365
1366 IDBError SQLiteIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t newKeyNumber)
1367 {
1368     LOG(IndexedDB, "SQLiteIDBBackingStore::revertGeneratedKeyNumber - object store %" PRIu64 ", reverted number %" PRIu64, objectStoreID, newKeyNumber);
1369
1370     ASSERT(m_sqliteDB);
1371     ASSERT(m_sqliteDB->isOpen());
1372
1373     auto* transaction = m_transactions.get(transactionIdentifier);
1374     if (!transaction || !transaction->inProgress()) {
1375         LOG_ERROR("Attempt to revert key generator value in database without an in-progress transaction");
1376         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in database without an in-progress transaction") };
1377     }
1378     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1379         LOG_ERROR("Attempt to revert key generator value in a read-only transaction");
1380         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in a read-only transaction") };
1381     }
1382
1383     ASSERT(newKeyNumber);
1384     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyNumber - 1);
1385 }
1386
1387 IDBError SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, double newKeyNumber)
1388 {
1389     LOG(IndexedDB, "SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber");
1390
1391     ASSERT(m_sqliteDB);
1392     ASSERT(m_sqliteDB->isOpen());
1393
1394     auto* transaction = m_transactions.get(transactionIdentifier);
1395     if (!transaction || !transaction->inProgress()) {
1396         LOG_ERROR("Attempt to update key generator value in database without an in-progress transaction");
1397         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in database without an in-progress transaction") };
1398     }
1399     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1400         LOG_ERROR("Attempt to update key generator value in a read-only transaction");
1401         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in a read-only transaction") };
1402     }
1403
1404     uint64_t currentValue;
1405     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
1406     if (!error.isNull())
1407         return error;
1408
1409     if (newKeyNumber <= currentValue)
1410         return { };
1411
1412     uint64_t newKeyInteger(newKeyNumber);
1413     if (newKeyInteger <= uint64_t(newKeyNumber))
1414         ++newKeyInteger;
1415
1416     ASSERT(newKeyInteger > uint64_t(newKeyNumber));
1417
1418     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyInteger - 1);
1419 }
1420
1421 IDBError SQLiteIDBBackingStore::openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info, IDBGetResult& result)
1422 {
1423     ASSERT(m_sqliteDB);
1424     ASSERT(m_sqliteDB->isOpen());
1425
1426     auto* transaction = m_transactions.get(transactionIdentifier);
1427     if (!transaction || !transaction->inProgress()) {
1428         LOG_ERROR("Attempt to open a cursor in database without an in-progress transaction");
1429         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to open a cursor in database without an in-progress transaction") };
1430     }
1431
1432     auto* cursor = transaction->maybeOpenCursor(info);
1433     if (!cursor) {
1434         LOG_ERROR("Unable to open cursor");
1435         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open cursor") };
1436     }
1437
1438     m_cursors.set(cursor->identifier(), cursor);
1439
1440     cursor->currentData(result);
1441     return { };
1442 }
1443
1444 IDBError SQLiteIDBBackingStore::iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData& key, uint32_t count, IDBGetResult& result)
1445 {
1446     LOG(IndexedDB, "SQLiteIDBBackingStore::iterateCursor");
1447
1448     ASSERT(m_sqliteDB);
1449     ASSERT(m_sqliteDB->isOpen());
1450
1451     auto* cursor = m_cursors.get(cursorIdentifier);
1452     if (!cursor) {
1453         LOG_ERROR("Attempt to iterate a cursor that doesn't exist");
1454         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor that doesn't exist") };
1455     }
1456
1457     ASSERT_UNUSED(transactionIdentifier, cursor->transaction()->transactionIdentifier() == transactionIdentifier);
1458
1459     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
1460         LOG_ERROR("Attempt to iterate a cursor without an in-progress transaction");
1461         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor without an in-progress transaction") };
1462     }
1463
1464     if (key.isValid()) {
1465         if (!cursor->iterate(key)) {
1466             LOG_ERROR("Attempt to iterate cursor failed");
1467             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate cursor failed") };
1468         }
1469     } else {
1470         if (!count)
1471             count = 1;
1472         if (!cursor->advance(count)) {
1473             LOG_ERROR("Attempt to advance cursor failed");
1474             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to advance cursor failed") };
1475         }
1476     }
1477
1478     cursor->currentData(result);
1479     return { };
1480 }
1481
1482 void SQLiteIDBBackingStore::deleteBackingStore()
1483 {
1484     String dbFilename = fullDatabasePath();
1485
1486     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteBackingStore deleting file '%s' on disk", dbFilename.utf8().data());
1487
1488     if (m_sqliteDB) {
1489         m_sqliteDB->close();
1490         m_sqliteDB = nullptr;
1491     }
1492
1493     SQLiteFileSystem::deleteDatabaseFile(dbFilename);
1494     SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_absoluteDatabaseDirectory);
1495 }
1496
1497 void SQLiteIDBBackingStore::unregisterCursor(SQLiteIDBCursor& cursor)
1498 {
1499     ASSERT(m_cursors.contains(cursor.identifier()));
1500     m_cursors.remove(cursor.identifier());
1501 }
1502
1503 } // namespace IDBServer
1504 } // namespace WebCore
1505
1506 #endif // ENABLE(INDEXED_DATABASE)