42546fb9daa04783fd4591527c6c387eaadeb7db
[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 "IDBGetAllRecordsData.h"
35 #include "IDBGetAllResult.h"
36 #include "IDBGetResult.h"
37 #include "IDBIterateCursorData.h"
38 #include "IDBKeyData.h"
39 #include "IDBObjectStoreInfo.h"
40 #include "IDBSerialization.h"
41 #include "IDBTransactionInfo.h"
42 #include "IDBValue.h"
43 #include "IndexKey.h"
44 #include "Logging.h"
45 #include "SQLiteDatabase.h"
46 #include "SQLiteFileSystem.h"
47 #include "SQLiteIDBCursor.h"
48 #include "SQLiteStatement.h"
49 #include "SQLiteTransaction.h"
50 #include "ThreadSafeDataBuffer.h"
51 #include <heap/HeapInlines.h>
52 #include <heap/StrongInlines.h>
53 #include <runtime/AuxiliaryBarrierInlines.h>
54 #include <runtime/JSCJSValueInlines.h>
55 #include <runtime/JSGlobalObject.h>
56 #include <runtime/StructureInlines.h>
57 #include <wtf/NeverDestroyed.h>
58
59 using namespace JSC;
60
61 namespace WebCore {
62 namespace IDBServer {
63
64 // Current version of the metadata schema being used in the metadata database.
65 static const int currentMetadataVersion = 1;
66
67 static int idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
68 {
69     IDBKeyData a, b;
70     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(aBuffer), aLength, a)) {
71         LOG_ERROR("Unable to deserialize key A in collation function.");
72
73         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
74         // We arbitrarily choose "A > B"
75         return 1;
76     }
77     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(bBuffer), bLength, b)) {
78         LOG_ERROR("Unable to deserialize key B in collation function.");
79
80         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
81         // We arbitrarily choose "A > B"
82         return 1;
83     }
84
85     return a.compare(b);
86 }
87
88 static const String v1RecordsTableSchema(const String& tableName)
89 {
90     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)");
91 }
92
93 static const String& v1RecordsTableSchema()
94 {
95     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("Records"));
96     return v1RecordsTableSchemaString;
97 }
98
99 static const String& v1RecordsTableSchemaAlternate()
100 {
101     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("\"Records\""));
102     return v1RecordsTableSchemaString;
103 }
104
105 static const String v2RecordsTableSchema(const String& tableName)
106 {
107     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)");
108 }
109
110 static const String& v2RecordsTableSchema()
111 {
112     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("Records"));
113     return v2RecordsTableSchemaString;
114 }
115
116 static const String& v2RecordsTableSchemaAlternate()
117 {
118     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("\"Records\""));
119     return v2RecordsTableSchemaString;
120 }
121
122 static const String v3RecordsTableSchema(const String& tableName)
123 {
124     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, recordID INTEGER PRIMARY KEY)");
125 }
126
127 static const String& v3RecordsTableSchema()
128 {
129     static NeverDestroyed<WTF::String> v3RecordsTableSchemaString(v3RecordsTableSchema("Records"));
130     return v3RecordsTableSchemaString;
131 }
132
133 static const String& v3RecordsTableSchemaAlternate()
134 {
135     static NeverDestroyed<WTF::String> v3RecordsTableSchemaString(v3RecordsTableSchema("\"Records\""));
136     return v3RecordsTableSchemaString;
137 }
138
139 static const String v1IndexRecordsTableSchema(const String& tableName)
140 {
141     return makeString("CREATE TABLE ", tableName, " (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)");
142 }
143
144 static const String& v1IndexRecordsTableSchema()
145 {
146     static NeverDestroyed<WTF::String> v1IndexRecordsTableSchemaString(v1IndexRecordsTableSchema("IndexRecords"));
147     return v1IndexRecordsTableSchemaString;
148 }
149
150 static const String& v1IndexRecordsTableSchemaAlternate()
151 {
152     static NeverDestroyed<WTF::String> v1IndexRecordsTableSchemaString(v1IndexRecordsTableSchema("\"IndexRecords\""));
153     return v1IndexRecordsTableSchemaString;
154 }
155
156 static const String v2IndexRecordsTableSchema(const String& tableName)
157 {
158     return makeString("CREATE TABLE ", tableName, " (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL)");
159 }
160
161 static const String& v2IndexRecordsTableSchema()
162 {
163     static NeverDestroyed<WTF::String> v2IndexRecordsTableSchemaString(v2IndexRecordsTableSchema("IndexRecords"));
164     return v2IndexRecordsTableSchemaString;
165 }
166
167 static const String& v2IndexRecordsTableSchemaAlternate()
168 {
169     static NeverDestroyed<WTF::String> v2IndexRecordsTableSchemaString(v2IndexRecordsTableSchema("\"IndexRecords\""));
170     return v2IndexRecordsTableSchemaString;
171 }
172
173 static const String blobRecordsTableSchema(const String& tableName)
174 {
175     return makeString("CREATE TABLE ", tableName, " (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)");
176 }
177
178 static const String& blobRecordsTableSchema()
179 {
180     static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("BlobRecords"));
181     return blobRecordsTableSchemaString;
182 }
183
184 static const String& blobRecordsTableSchemaAlternate()
185 {
186     static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("\"BlobRecords\""));
187     return blobRecordsTableSchemaString;
188 }
189
190 static const String blobFilesTableSchema(const String& tableName)
191 {
192     return makeString("CREATE TABLE ", tableName, " (blobURL TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, fileName TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL)");
193 }
194
195 static const String& blobFilesTableSchema()
196 {
197     static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("BlobFiles"));
198     return blobFilesTableSchemaString;
199 }
200
201 static const String& blobFilesTableSchemaAlternate()
202 {
203     static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("\"BlobFiles\""));
204     return blobFilesTableSchemaString;
205 }
206
207 SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory, IDBBackingStoreTemporaryFileHandler& fileHandler)
208     : m_identifier(identifier)
209     , m_temporaryFileHandler(fileHandler)
210 {
211     m_absoluteDatabaseDirectory = identifier.databaseDirectoryRelativeToRoot(databaseRootDirectory);
212 }
213
214 SQLiteIDBBackingStore::~SQLiteIDBBackingStore()
215 {
216     if (m_sqliteDB)
217         m_sqliteDB->close();
218
219     if (m_vm) {
220         JSLockHolder locker(m_vm.get());
221         m_globalObject.clear();
222         m_vm = nullptr;
223     }
224 }
225
226
227 void SQLiteIDBBackingStore::initializeVM()
228 {
229     if (!m_vm) {
230         ASSERT(!m_globalObject);
231         m_vm = VM::create();
232
233         JSLockHolder locker(m_vm.get());
234         m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
235     }
236 }
237
238 VM& SQLiteIDBBackingStore::vm()
239 {
240     initializeVM();
241     return *m_vm;
242 }
243
244 JSGlobalObject& SQLiteIDBBackingStore::globalObject()
245 {
246     initializeVM();
247     return **m_globalObject;
248 }
249
250 static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
251 {
252     String currentSchema;
253     {
254         // Fetch the schema for an existing records table.
255         SQLiteStatement statement(database, "SELECT type, sql FROM sqlite_master WHERE tbl_name='Records'");
256         if (statement.prepare() != SQLITE_OK) {
257             LOG_ERROR("Unable to prepare statement to fetch schema for the Records table.");
258             return false;
259         }
260
261         int sqliteResult = statement.step();
262
263         // If there is no Records table at all, create it and then bail.
264         if (sqliteResult == SQLITE_DONE) {
265             if (!database.executeCommand(v3RecordsTableSchema())) {
266                 LOG_ERROR("Could not create Records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
267                 return false;
268             }
269
270             return true;
271         }
272
273         if (sqliteResult != SQLITE_ROW) {
274             LOG_ERROR("Error executing statement to fetch schema for the Records table.");
275             return false;
276         }
277
278         currentSchema = statement.getColumnText(1);
279     }
280
281     ASSERT(!currentSchema.isEmpty());
282
283     // If the schema in the backing store is the current schema, we're done.
284     if (currentSchema == v3RecordsTableSchema() || currentSchema == v3RecordsTableSchemaAlternate())
285         return true;
286
287     // If the record table is not the current schema then it must be one of the previous schemas.
288     // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
289     if (currentSchema != v1RecordsTableSchema() && currentSchema != v1RecordsTableSchemaAlternate()
290         && currentSchema != v2RecordsTableSchema() && currentSchema != v2RecordsTableSchemaAlternate())
291         RELEASE_ASSERT_NOT_REACHED();
292
293     SQLiteTransaction transaction(database);
294     transaction.begin();
295
296     // Create a temporary table with the correct schema and migrate all existing content over.
297     if (!database.executeCommand(v3RecordsTableSchema("_Temp_Records"))) {
298         LOG_ERROR("Could not create temporary records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
299         return false;
300     }
301
302     if (!database.executeCommand("INSERT INTO _Temp_Records (objectStoreID, key, value) SELECT objectStoreID, CAST(key AS TEXT), value FROM Records")) {
303         LOG_ERROR("Could not migrate existing Records content (%i) - %s", database.lastError(), database.lastErrorMsg());
304         return false;
305     }
306
307     if (!database.executeCommand("DROP TABLE Records")) {
308         LOG_ERROR("Could not drop existing Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
309         return false;
310     }
311
312     if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records")) {
313         LOG_ERROR("Could not rename temporary Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
314         return false;
315     }
316
317     transaction.commit();
318
319     return true;
320 }
321
322 bool SQLiteIDBBackingStore::ensureValidBlobTables()
323 {
324     ASSERT(m_sqliteDB);
325     ASSERT(m_sqliteDB->isOpen());
326
327     String currentSchema;
328     {
329         // Fetch the schema for an existing blob record table.
330         SQLiteStatement statement(*m_sqliteDB, "SELECT type, sql FROM sqlite_master WHERE tbl_name='BlobRecords'");
331         if (statement.prepare() != SQLITE_OK) {
332             LOG_ERROR("Unable to prepare statement to fetch schema for the BlobRecords table.");
333             return false;
334         }
335
336         int sqliteResult = statement.step();
337
338         // If there is no BlobRecords table at all, create it..
339         if (sqliteResult == SQLITE_DONE) {
340             if (!m_sqliteDB->executeCommand(blobRecordsTableSchema())) {
341                 LOG_ERROR("Could not create BlobRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
342                 return false;
343             }
344
345             currentSchema = blobRecordsTableSchema();
346         } else if (sqliteResult != SQLITE_ROW) {
347             LOG_ERROR("Error executing statement to fetch schema for the BlobRecords table.");
348             return false;
349         } else
350             currentSchema = statement.getColumnText(1);
351     }
352
353     if (currentSchema != blobRecordsTableSchema() && currentSchema != blobRecordsTableSchemaAlternate()) {
354         LOG_ERROR("Invalid BlobRecords table schema found");
355         return false;
356     }
357
358     {
359         // Fetch the schema for an existing blob file table.
360         SQLiteStatement statement(*m_sqliteDB, "SELECT type, sql FROM sqlite_master WHERE tbl_name='BlobFiles'");
361         if (statement.prepare() != SQLITE_OK) {
362             LOG_ERROR("Unable to prepare statement to fetch schema for the BlobFiles table.");
363             return false;
364         }
365
366         int sqliteResult = statement.step();
367
368         // If there is no BlobFiles table at all, create it and then bail.
369         if (sqliteResult == SQLITE_DONE) {
370             if (!m_sqliteDB->executeCommand(blobFilesTableSchema())) {
371                 LOG_ERROR("Could not create BlobFiles table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
372                 return false;
373             }
374
375             return true;
376         }
377
378         if (sqliteResult != SQLITE_ROW) {
379             LOG_ERROR("Error executing statement to fetch schema for the BlobFiles table.");
380             return false;
381         }
382
383         currentSchema = statement.getColumnText(1);
384     }
385
386     if (currentSchema != blobFilesTableSchema() && currentSchema != blobFilesTableSchemaAlternate()) {
387         LOG_ERROR("Invalid BlobFiles table schema found");
388         return false;
389     }
390
391     return true;
392 }
393
394 bool SQLiteIDBBackingStore::ensureValidRecordsTable()
395 {
396     ASSERT(m_sqliteDB);
397     ASSERT(m_sqliteDB->isOpen());
398
399     if (!createOrMigrateRecordsTableIfNecessary(*m_sqliteDB))
400         return false;
401
402     // Whether the updated records table already existed or if it was just created and the data migrated over,
403     // make sure the uniqueness index exists.
404     if (!m_sqliteDB->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);")) {
405         LOG_ERROR("Could not create RecordsIndex on Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
406         return false;
407     }
408
409     return true;
410 }
411
412 bool SQLiteIDBBackingStore::ensureValidIndexRecordsTable()
413 {
414     ASSERT(m_sqliteDB);
415     ASSERT(m_sqliteDB->isOpen());
416
417     String currentSchema;
418     {
419         // Fetch the schema for an existing index record table.
420         SQLiteStatement statement(*m_sqliteDB, "SELECT type, sql FROM sqlite_master WHERE tbl_name='IndexRecords'");
421         if (statement.prepare() != SQLITE_OK) {
422             LOG_ERROR("Unable to prepare statement to fetch schema for the IndexRecords table.");
423             return false;
424         }
425
426         int sqliteResult = statement.step();
427
428         // If there is no IndexRecords table at all, create it and then bail.
429         if (sqliteResult == SQLITE_DONE) {
430             if (!m_sqliteDB->executeCommand(v2IndexRecordsTableSchema())) {
431                 LOG_ERROR("Could not create IndexRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
432                 return false;
433             }
434
435             return true;
436         }
437
438         if (sqliteResult != SQLITE_ROW) {
439             LOG_ERROR("Error executing statement to fetch schema for the IndexRecords table.");
440             return false;
441         }
442
443         currentSchema = statement.getColumnText(1);
444     }
445
446     ASSERT(!currentSchema.isEmpty());
447
448     // If the schema in the backing store is the current schema, we're done.
449     if (currentSchema == v2IndexRecordsTableSchema() || currentSchema == v2IndexRecordsTableSchemaAlternate())
450         return true;
451
452     // If the record table is not the current schema then it must be one of the previous schemas.
453     // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
454     if (currentSchema != v1IndexRecordsTableSchema() && currentSchema != v1IndexRecordsTableSchemaAlternate())
455         RELEASE_ASSERT_NOT_REACHED();
456
457     SQLiteTransaction transaction(*m_sqliteDB);
458     transaction.begin();
459
460     // Create a temporary table with the correct schema and migrate all existing content over.
461     if (!m_sqliteDB->executeCommand(v2IndexRecordsTableSchema("_Temp_IndexRecords"))) {
462         LOG_ERROR("Could not create temporary index records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
463         return false;
464     }
465
466     if (!m_sqliteDB->executeCommand("INSERT INTO _Temp_IndexRecords SELECT * FROM IndexRecords")) {
467         LOG_ERROR("Could not migrate existing IndexRecords content (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
468         return false;
469     }
470
471     if (!m_sqliteDB->executeCommand("DROP TABLE IndexRecords")) {
472         LOG_ERROR("Could not drop existing IndexRecords table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
473         return false;
474     }
475
476     if (!m_sqliteDB->executeCommand("ALTER TABLE _Temp_IndexRecords RENAME TO IndexRecords")) {
477         LOG_ERROR("Could not rename temporary IndexRecords table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
478         return false;
479     }
480
481     transaction.commit();
482
483     return true;
484 }
485
486 std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo()
487 {
488     ASSERT(m_sqliteDB);
489     ASSERT(m_sqliteDB->isOpen());
490
491     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);")) {
492         LOG_ERROR("Could not create IDBDatabaseInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
493         m_sqliteDB = nullptr;
494         return nullptr;
495     }
496
497     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);")) {
498         LOG_ERROR("Could not create ObjectStoreInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
499         m_sqliteDB = nullptr;
500         return nullptr;
501     }
502
503     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);")) {
504         LOG_ERROR("Could not create IndexInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
505         m_sqliteDB = nullptr;
506         return nullptr;
507     }
508
509     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);")) {
510         LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
511         m_sqliteDB = nullptr;
512         return nullptr;
513     }
514
515     {
516         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);"));
517         if (sql.prepare() != SQLITE_OK
518             || sql.bindInt(1, currentMetadataVersion) != SQLITE_OK
519             || sql.step() != SQLITE_DONE) {
520             LOG_ERROR("Could not insert database metadata version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
521             m_sqliteDB = nullptr;
522             return nullptr;
523         }
524     }
525     {
526         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseName', ?);"));
527         if (sql.prepare() != SQLITE_OK
528             || sql.bindText(1, m_identifier.databaseName()) != SQLITE_OK
529             || sql.step() != SQLITE_DONE) {
530             LOG_ERROR("Could not insert database name into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
531             m_sqliteDB = nullptr;
532             return nullptr;
533         }
534     }
535     {
536         // Database versions are defined to be a uin64_t in the spec but sqlite3 doesn't support native binding of unsigned integers.
537         // Therefore we'll store the version as a String.
538         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseVersion', ?);"));
539         if (sql.prepare() != SQLITE_OK
540             || sql.bindText(1, String::number(0)) != SQLITE_OK
541             || sql.step() != SQLITE_DONE) {
542             LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
543             m_sqliteDB = nullptr;
544             return nullptr;
545         }
546     }
547
548     if (!m_sqliteDB->executeCommand(ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MaxObjectStoreID', 1);"))) {
549         LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
550         m_sqliteDB = nullptr;
551         return nullptr;
552     }
553
554     // This initial database info matches the default values we just put into the metadata database.
555     return std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
556 }
557
558 std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::extractExistingDatabaseInfo()
559 {
560     ASSERT(m_sqliteDB);
561
562     if (!m_sqliteDB->tableExists(ASCIILiteral("IDBDatabaseInfo")))
563         return nullptr;
564
565     String databaseName;
566     {
567         SQLiteStatement sql(*m_sqliteDB, "SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseName';");
568         if (sql.isColumnNull(0))
569             return nullptr;
570         databaseName = sql.getColumnText(0);
571         if (databaseName != m_identifier.databaseName()) {
572             LOG_ERROR("Database name in the info database ('%s') does not match the expected name ('%s')", databaseName.utf8().data(), m_identifier.databaseName().utf8().data());
573             return nullptr;
574         }
575     }
576     uint64_t databaseVersion;
577     {
578         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseVersion';"));
579         if (sql.isColumnNull(0))
580             return nullptr;
581         String stringVersion = sql.getColumnText(0);
582         bool ok;
583         databaseVersion = stringVersion.toUInt64Strict(&ok);
584         if (!ok) {
585             LOG_ERROR("Database version on disk ('%s') does not cleanly convert to an unsigned 64-bit integer version", stringVersion.utf8().data());
586             return nullptr;
587         }
588     }
589
590     auto databaseInfo = std::make_unique<IDBDatabaseInfo>(databaseName, databaseVersion);
591
592     {
593         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, keyPath, autoInc, maxIndexID FROM ObjectStoreInfo;"));
594         if (sql.prepare() != SQLITE_OK)
595             return nullptr;
596
597         int result = sql.step();
598         while (result == SQLITE_ROW) {
599             uint64_t objectStoreID = sql.getColumnInt64(0);
600             String objectStoreName = sql.getColumnText(1);
601
602             Vector<char> keyPathBuffer;
603             sql.getColumnBlobAsVector(2, keyPathBuffer);
604
605             std::optional<IDBKeyPath> objectStoreKeyPath;
606             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), objectStoreKeyPath)) {
607                 LOG_ERROR("Unable to extract key path from database");
608                 return nullptr;
609             }
610
611             bool autoIncrement = sql.getColumnInt(3);
612
613             databaseInfo->addExistingObjectStore({ objectStoreID, objectStoreName, WTFMove(objectStoreKeyPath), autoIncrement });
614
615             result = sql.step();
616         }
617
618         if (result != SQLITE_DONE) {
619             LOG_ERROR("Error fetching object store info from database on disk");
620             return nullptr;
621         }
622     }
623
624     {
625         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
626         if (sql.prepare() != SQLITE_OK)
627             return nullptr;
628
629         int result = sql.step();
630         while (result == SQLITE_ROW) {
631             uint64_t indexID = sql.getColumnInt64(0);
632             String indexName = sql.getColumnText(1);
633             uint64_t objectStoreID = sql.getColumnInt64(2);
634
635             Vector<char> keyPathBuffer;
636             sql.getColumnBlobAsVector(3, keyPathBuffer);
637
638             std::optional<IDBKeyPath> indexKeyPath;
639             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexKeyPath)) {
640                 LOG_ERROR("Unable to extract key path from database");
641                 return nullptr;
642             }
643             if (!indexKeyPath) {
644                 LOG_ERROR("Unable to extract key path from database");
645                 return nullptr;
646             }
647
648             bool unique = sql.getColumnInt(4);
649             bool multiEntry = sql.getColumnInt(5);
650
651             auto objectStore = databaseInfo->infoForExistingObjectStore(objectStoreID);
652             if (!objectStore) {
653                 LOG_ERROR("Found index referring to a non-existant object store");
654                 return nullptr;
655             }
656
657             objectStore->addExistingIndex({ indexID, objectStoreID, indexName, WTFMove(indexKeyPath.value()), unique, multiEntry });
658
659             result = sql.step();
660         }
661
662         if (result != SQLITE_DONE) {
663             LOG_ERROR("Error fetching index info from database on disk");
664             return nullptr;
665         }
666     }
667
668     return databaseInfo;
669 }
670
671 String SQLiteIDBBackingStore::databaseNameFromEncodedFilename(const String& encodedName)
672 {
673     if (equal(encodedName, ASCIILiteral("%00")))
674         return { };
675
676     String partiallyDecoded = encodedName;
677     partiallyDecoded.replace(ASCIILiteral("%2E"), ASCIILiteral("."));
678
679     return decodeFromFilename(partiallyDecoded);
680 }
681
682 String SQLiteIDBBackingStore::filenameForDatabaseName() const
683 {
684     ASSERT(!m_identifier.databaseName().isNull());
685
686     if (m_identifier.databaseName().isEmpty())
687         return "%00";
688
689     String filename = encodeForFileName(m_identifier.databaseName());
690     filename.replace('.', "%2E");
691
692     return filename;
693 }
694
695 String SQLiteIDBBackingStore::fullDatabaseDirectory() const
696 {
697     ASSERT(!m_identifier.databaseName().isNull());
698
699     return pathByAppendingComponent(m_absoluteDatabaseDirectory, filenameForDatabaseName());
700 }
701
702 String SQLiteIDBBackingStore::fullDatabasePath() const
703 {
704     ASSERT(!m_identifier.databaseName().isNull());
705
706     return pathByAppendingComponent(fullDatabaseDirectory(), "IndexedDB.sqlite3");
707 }
708
709 IDBError SQLiteIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info)
710 {
711     LOG(IndexedDB, "SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s", m_identifier.databaseName().utf8().data());
712
713     if (m_databaseInfo) {
714         info = *m_databaseInfo;
715         return { };
716     }
717
718     makeAllDirectories(fullDatabaseDirectory());
719     String dbFilename = fullDatabasePath();
720
721     m_sqliteDB = std::make_unique<SQLiteDatabase>();
722     if (!m_sqliteDB->open(dbFilename)) {
723         LOG_ERROR("Failed to open SQLite database at path '%s'", dbFilename.utf8().data());
724         m_sqliteDB = nullptr;
725     }
726
727     if (!m_sqliteDB)
728         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open database file on disk") };
729
730     m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
731         return idbKeyCollate(aLength, a, bLength, b);
732     });
733
734     if (!ensureValidRecordsTable()) {
735         LOG_ERROR("Error creating or migrating Records table in database");
736         m_sqliteDB = nullptr;
737         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Records table in database") };
738     }
739
740     if (!ensureValidIndexRecordsTable()) {
741         LOG_ERROR("Error creating or migrating Index Records table in database");
742         m_sqliteDB = nullptr;
743         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Index Records table in database") };
744     }
745
746     if (!ensureValidBlobTables()) {
747         LOG_ERROR("Error creating or confirming Blob Records tables in database");
748         m_sqliteDB = nullptr;
749         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or confirming Blob Records tables in database") };
750     }
751
752     auto databaseInfo = extractExistingDatabaseInfo();
753     if (!databaseInfo)
754         databaseInfo = createAndPopulateInitialDatabaseInfo();
755
756     if (!databaseInfo) {
757         LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data());
758         m_sqliteDB = nullptr;
759         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to establish IDB database file") };
760     }
761
762     m_databaseInfo = WTFMove(databaseInfo);
763     info = *m_databaseInfo;
764     return { };
765 }
766
767 IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo& info)
768 {
769     LOG(IndexedDB, "SQLiteIDBBackingStore::beginTransaction - %s", info.identifier().loggingString().utf8().data());
770
771     ASSERT(m_sqliteDB);
772     ASSERT(m_sqliteDB->isOpen());
773     ASSERT(m_databaseInfo);
774
775     auto addResult = m_transactions.add(info.identifier(), nullptr);
776     if (!addResult.isNewEntry) {
777         LOG_ERROR("Attempt to establish transaction identifier that already exists");
778         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to establish transaction identifier that already exists") };
779     }
780
781     addResult.iterator->value = std::make_unique<SQLiteIDBTransaction>(*this, info);
782
783     auto error = addResult.iterator->value->begin(*m_sqliteDB);
784     if (error.isNull() && info.mode() == IDBTransactionMode::Versionchange) {
785         m_originalDatabaseInfoBeforeVersionChange = std::make_unique<IDBDatabaseInfo>(*m_databaseInfo);
786
787         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE IDBDatabaseInfo SET value = ? where key = 'DatabaseVersion';"));
788         if (sql.prepare() != SQLITE_OK
789             || sql.bindText(1, String::number(info.newVersion())) != SQLITE_OK
790             || sql.step() != SQLITE_DONE)
791             error = { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to store new database version in database") };
792     }
793
794     return error;
795 }
796
797 IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier& identifier)
798 {
799     LOG(IndexedDB, "SQLiteIDBBackingStore::abortTransaction - %s", identifier.loggingString().utf8().data());
800
801     ASSERT(m_sqliteDB);
802     ASSERT(m_sqliteDB->isOpen());
803
804     auto transaction = m_transactions.take(identifier);
805     if (!transaction) {
806         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
807         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to abort a transaction that hasn't been established") };
808     }
809
810     if (transaction->mode() == IDBTransactionMode::Versionchange && m_originalDatabaseInfoBeforeVersionChange)
811         m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
812
813     return transaction->abort();
814 }
815
816 IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier& identifier)
817 {
818     LOG(IndexedDB, "SQLiteIDBBackingStore::commitTransaction - %s", identifier.loggingString().utf8().data());
819
820     ASSERT(m_sqliteDB);
821     ASSERT(m_sqliteDB->isOpen());
822
823     auto transaction = m_transactions.take(identifier);
824     if (!transaction) {
825         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
826         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit a transaction that hasn't been established") };
827     }
828
829     auto error = transaction->commit();
830     if (!error.isNull()) {
831         if (transaction->mode() == IDBTransactionMode::Versionchange) {
832             ASSERT(m_originalDatabaseInfoBeforeVersionChange);
833             m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
834         }
835     } else
836         m_originalDatabaseInfoBeforeVersionChange = nullptr;
837
838     return error;
839 }
840
841 IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
842 {
843     LOG(IndexedDB, "SQLiteIDBBackingStore::createObjectStore - adding OS %s with ID %" PRIu64, info.name().utf8().data(), info.identifier());
844
845     ASSERT(m_sqliteDB);
846     ASSERT(m_sqliteDB->isOpen());
847
848     auto* transaction = m_transactions.get(transactionIdentifier);
849     if (!transaction || !transaction->inProgress()) {
850         LOG_ERROR("Attempt to create an object store without an in-progress transaction");
851         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store without an in-progress transaction") };
852     }
853     if (transaction->mode() != IDBTransactionMode::Versionchange) {
854         LOG_ERROR("Attempt to create an object store in a non-version-change transaction");
855         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store in a non-version-change transaction") };
856     }
857
858     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
859     if (!keyPathBlob) {
860         LOG_ERROR("Unable to serialize IDBKeyPath to save in database for new object store");
861         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to save in database for new object store") };
862     }
863
864     {
865         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
866         if (sql.prepare() != SQLITE_OK
867             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
868             || sql.bindText(2, info.name()) != SQLITE_OK
869             || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
870             || sql.bindInt(4, info.autoIncrement()) != SQLITE_OK
871             || sql.bindInt64(5, info.maxIndexID()) != SQLITE_OK
872             || sql.step() != SQLITE_DONE) {
873             LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
874             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not create object store") };
875         }
876     }
877
878     {
879         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, 0);"));
880         if (sql.prepare() != SQLITE_OK
881             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
882             || sql.step() != SQLITE_DONE) {
883             LOG_ERROR("Could not seed initial key generator value for ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
884             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not seed initial key generator value for object store") };
885         }
886     }
887
888     m_databaseInfo->addExistingObjectStore(info);
889
890     return { };
891 }
892
893 IDBError SQLiteIDBBackingStore::deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
894 {
895     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteObjectStore - object store %" PRIu64, objectStoreIdentifier);
896
897     ASSERT(m_sqliteDB);
898     ASSERT(m_sqliteDB->isOpen());
899
900     auto* transaction = m_transactions.get(transactionIdentifier);
901     if (!transaction || !transaction->inProgress()) {
902         LOG_ERROR("Attempt to delete an object store without an in-progress transaction");
903         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store without an in-progress transaction") };
904     }
905     if (transaction->mode() != IDBTransactionMode::Versionchange) {
906         LOG_ERROR("Attempt to delete an object store in a non-version-change transaction");
907         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store in a non-version-change transaction") };
908     }
909
910     // Delete the ObjectStore record
911     {
912         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
913         if (sql.prepare() != SQLITE_OK
914             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
915             || sql.step() != SQLITE_DONE) {
916             LOG_ERROR("Could not delete object store id %" PRIi64 " from ObjectStoreInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
917             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete object store") };
918         }
919     }
920
921     // Delete the ObjectStore's key generator record if there is one.
922     {
923         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM KeyGenerators WHERE objectStoreID = ?;"));
924         if (sql.prepare() != SQLITE_OK
925             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
926             || sql.step() != SQLITE_DONE) {
927             LOG_ERROR("Could not delete object store from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
928             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete key generator for deleted object store") };
929         }
930     }
931
932     // Delete all associated records
933     {
934         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
935         if (sql.prepare() != SQLITE_OK
936             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
937             || sql.step() != SQLITE_DONE) {
938             LOG_ERROR("Could not delete records for object store %" PRIi64 " (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
939             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete records for deleted object store") };
940         }
941     }
942
943     // Delete all associated Indexes
944     {
945         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
946         if (sql.prepare() != SQLITE_OK
947             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
948             || sql.step() != SQLITE_DONE) {
949             LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
950             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex for deleted object store") };
951         }
952     }
953
954     // Delete all associated Index records
955     {
956         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
957         if (sql.prepare() != SQLITE_OK
958             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
959             || sql.step() != SQLITE_DONE) {
960             LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
961             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex records for deleted object store") };
962         }
963     }
964
965     // Delete all unused Blob URL records.
966     {
967         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobRecords WHERE objectStoreRow NOT IN (SELECT recordID FROM Records)"));
968         if (sql.prepare() != SQLITE_OK
969             || sql.step() != SQLITE_DONE) {
970             LOG_ERROR("Could not delete Blob URL records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
971             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete stored blob records for deleted object store") };
972         }
973     }
974
975     // Delete all unused Blob File records.
976     auto error = deleteUnusedBlobFileRecords(*transaction);
977     if (!error.isNull())
978         return error;
979
980     m_databaseInfo->deleteObjectStore(objectStoreIdentifier);
981
982     return { };
983 }
984
985 IDBError SQLiteIDBBackingStore::renameObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName)
986 {
987     LOG(IndexedDB, "SQLiteIDBBackingStore::renameObjectStore - object store %" PRIu64, objectStoreIdentifier);
988
989     ASSERT(m_sqliteDB);
990     ASSERT(m_sqliteDB->isOpen());
991
992     auto* transaction = m_transactions.get(transactionIdentifier);
993     if (!transaction || !transaction->inProgress()) {
994         LOG_ERROR("Attempt to rename an object store without an in-progress transaction");
995         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an object store without an in-progress transaction") };
996     }
997     if (transaction->mode() != IDBTransactionMode::Versionchange) {
998         LOG_ERROR("Attempt to rename an object store in a non-version-change transaction");
999         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an object store in a non-version-change transaction") };
1000     }
1001
1002     {
1003         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE ObjectStoreInfo SET name = ? WHERE id = ?;"));
1004         if (sql.prepare() != SQLITE_OK
1005             || sql.bindText(1, newName) != SQLITE_OK
1006             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1007             || sql.step() != SQLITE_DONE) {
1008             LOG_ERROR("Could not update name for object store id %" PRIi64 " in ObjectStoreInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1009             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename object store") };
1010         }
1011     }
1012
1013     m_databaseInfo->renameObjectStore(objectStoreIdentifier, newName);
1014
1015     return { };
1016 }
1017
1018 IDBError SQLiteIDBBackingStore::clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID)
1019 {
1020     LOG(IndexedDB, "SQLiteIDBBackingStore::clearObjectStore - object store %" PRIu64, objectStoreID);
1021
1022     ASSERT(m_sqliteDB);
1023     ASSERT(m_sqliteDB->isOpen());
1024
1025     auto* transaction = m_transactions.get(transactionIdentifier);
1026     if (!transaction || !transaction->inProgress()) {
1027         LOG_ERROR("Attempt to clear an object store without an in-progress transaction");
1028         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store without an in-progress transaction") };
1029     }
1030     if (transaction->mode() == IDBTransactionMode::Readonly) {
1031         LOG_ERROR("Attempt to clear an object store in a read-only transaction");
1032         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store in a read-only transaction") };
1033     }
1034
1035     {
1036         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
1037         if (sql.prepare() != SQLITE_OK
1038             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1039             || sql.step() != SQLITE_DONE) {
1040             LOG_ERROR("Could not clear records from object store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1041             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to clear object store") };
1042         }
1043     }
1044
1045     {
1046         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
1047         if (sql.prepare() != SQLITE_OK
1048             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1049             || sql.step() != SQLITE_DONE) {
1050             LOG_ERROR("Could not delete records from index record store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1051             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to delete index records while clearing object store") };
1052         }
1053     }
1054
1055     transaction->notifyCursorsOfChanges(objectStoreID);
1056
1057     return { };
1058 }
1059
1060 IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
1061 {
1062     LOG(IndexedDB, "SQLiteIDBBackingStore::createIndex - ObjectStore %" PRIu64 ", Index %" PRIu64, info.objectStoreIdentifier(), info.identifier());
1063     ASSERT(m_sqliteDB);
1064     ASSERT(m_sqliteDB->isOpen());
1065
1066     auto* transaction = m_transactions.get(transactionIdentifier);
1067     if (!transaction || !transaction->inProgress()) {
1068         LOG_ERROR("Attempt to create an index without an in-progress transaction");
1069         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index without an in-progress transaction") };
1070     }
1071     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1072         LOG_ERROR("Attempt to create an index in a non-version-change transaction");
1073         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index in a non-version-change transaction") };
1074     }
1075
1076     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
1077     if (!keyPathBlob) {
1078         LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
1079         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to create index in database") };
1080     }
1081
1082     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
1083     if (sql.prepare() != SQLITE_OK
1084         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1085         || sql.bindText(2, info.name()) != SQLITE_OK
1086         || sql.bindInt64(3, info.objectStoreIdentifier()) != SQLITE_OK
1087         || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
1088         || sql.bindInt(5, info.unique()) != SQLITE_OK
1089         || sql.bindInt(6, info.multiEntry()) != SQLITE_OK
1090         || sql.step() != SQLITE_DONE) {
1091         LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1092         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to create index in database") };
1093     }
1094
1095     // Write index records for any records that already exist in this object store.
1096
1097     auto cursor = transaction->maybeOpenBackingStoreCursor(info.objectStoreIdentifier(), 0, IDBKeyRangeData::allKeys());
1098
1099     if (!cursor) {
1100         LOG_ERROR("Cannot open cursor to populate indexes in database");
1101         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
1102     }
1103
1104     while (!cursor->currentKey().isNull()) {
1105         auto& key = cursor->currentKey();
1106         auto* value = cursor->currentValue();
1107         ThreadSafeDataBuffer valueBuffer = value ? value->data() : ThreadSafeDataBuffer();
1108
1109         IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
1110         if (!error.isNull()) {
1111             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
1112             if (sql.prepare() != SQLITE_OK
1113                 || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1114                 || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
1115                 || sql.step() != SQLITE_DONE) {
1116                 LOG_ERROR("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database");
1117                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database") };
1118             }
1119
1120             return error;
1121         }
1122
1123         if (!cursor->advance(1)) {
1124             LOG_ERROR("Error advancing cursor while indexing existing records for new index.");
1125             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error advancing cursor while indexing existing records for new index") };
1126         }
1127     }
1128
1129     auto* objectStore = m_databaseInfo->infoForExistingObjectStore(info.objectStoreIdentifier());
1130     ASSERT(objectStore);
1131     objectStore->addExistingIndex(info);
1132
1133     return { };
1134 }
1135
1136 IDBError SQLiteIDBBackingStore::uncheckedHasIndexRecord(const IDBIndexInfo& info, const IDBKeyData& indexKey, bool& hasRecord)
1137 {
1138     hasRecord = false;
1139
1140     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
1141     if (!indexKeyBuffer) {
1142         LOG_ERROR("Unable to serialize index key to be stored in the database");
1143         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for index record in database") };
1144     }
1145
1146     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT rowid FROM IndexRecords WHERE indexID = ? AND objectStoreID = ? AND key = CAST(? AS TEXT);"));
1147     if (sql.prepare() != SQLITE_OK
1148         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1149         || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
1150         || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK) {
1151         LOG_ERROR("Error checking for index record in database");
1152         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for index record in database") };
1153     }
1154
1155     int sqlResult = sql.step();
1156     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
1157         return { };
1158
1159     if (sqlResult != SQLITE_ROW) {
1160         // There was an error fetching the record from the database.
1161         LOG_ERROR("Could not check if key exists in index (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1162         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in index") };
1163     }
1164
1165     hasRecord = true;
1166     return { };
1167 }
1168
1169 IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo& info, const IDBKeyData& key, const IndexKey& indexKey)
1170 {
1171     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexKey - (%" PRIu64 ") %s, %s", info.identifier(), key.loggingString().utf8().data(), indexKey.asOneKey().loggingString().utf8().data());
1172
1173     Vector<IDBKeyData> indexKeys;
1174     if (info.multiEntry())
1175         indexKeys = indexKey.multiEntry();
1176     else
1177         indexKeys.append(indexKey.asOneKey());
1178
1179     if (info.unique()) {
1180         bool hasRecord;
1181         IDBError error;
1182         for (auto& indexKey : indexKeys) {
1183             if (!indexKey.isValid())
1184                 continue;
1185             error = uncheckedHasIndexRecord(info, indexKey, hasRecord);
1186             if (!error.isNull())
1187                 return error;
1188             if (hasRecord)
1189                 return IDBError(IDBDatabaseException::ConstraintError);
1190         }
1191     }
1192
1193     for (auto& indexKey : indexKeys) {
1194         if (!indexKey.isValid())
1195             continue;
1196         auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
1197         if (!error.isNull()) {
1198             LOG_ERROR("Unable to put index record for newly created index");
1199             return error;
1200         }
1201     }
1202
1203     return { };
1204 }
1205
1206 IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
1207 {
1208     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexRecord - %s, %s", keyValue.loggingString().utf8().data(), indexKey.loggingString().utf8().data());
1209
1210     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
1211     if (!indexKeyBuffer) {
1212         LOG_ERROR("Unable to serialize index key to be stored in the database");
1213         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize index key to be stored in the database") };
1214     }
1215
1216     RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
1217     if (!valueBuffer) {
1218         LOG_ERROR("Unable to serialize the value to be stored in the database");
1219         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize value to be stored in the database") };
1220     }
1221
1222     {
1223         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));"));
1224         if (sql.prepare() != SQLITE_OK
1225             || sql.bindInt64(1, indexID) != SQLITE_OK
1226             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
1227             || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK
1228             || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLITE_OK
1229             || sql.step() != SQLITE_DONE) {
1230             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());
1231             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error putting index record into database") };
1232         }
1233     }
1234
1235     return { };
1236 }
1237
1238
1239 IDBError SQLiteIDBBackingStore::deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier)
1240 {
1241     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteIndex - object store %" PRIu64, objectStoreIdentifier);
1242
1243     ASSERT(m_sqliteDB);
1244     ASSERT(m_sqliteDB->isOpen());
1245
1246     auto* transaction = m_transactions.get(transactionIdentifier);
1247     if (!transaction || !transaction->inProgress()) {
1248         LOG_ERROR("Attempt to delete index without an in-progress transaction");
1249         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index without an in-progress transaction") };
1250     }
1251
1252     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1253         LOG_ERROR("Attempt to delete index during a non-version-change transaction");
1254         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index during a non-version-change transaction") };
1255     }
1256
1257     {
1258         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
1259         if (sql.prepare() != SQLITE_OK
1260             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
1261             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1262             || sql.step() != SQLITE_DONE) {
1263             LOG_ERROR("Could not delete index id %" PRIi64 " from IndexInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1264             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index from database") };
1265         }
1266     }
1267
1268     {
1269         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
1270         if (sql.prepare() != SQLITE_OK
1271             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
1272             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1273             || sql.step() != SQLITE_DONE) {
1274             LOG_ERROR("Could not delete index records for index id %" PRIi64 " from IndexRecords table (%i) - %s", indexIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1275             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index records from database") };
1276         }
1277     }
1278
1279     auto* objectStore = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
1280     ASSERT(objectStore);
1281     objectStore->deleteIndex(indexIdentifier);
1282
1283     return { };
1284 }
1285
1286 IDBError SQLiteIDBBackingStore::renameIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
1287 {
1288     LOG(IndexedDB, "SQLiteIDBBackingStore::renameIndex - object store %" PRIu64 ", index %" PRIu64, objectStoreIdentifier, indexIdentifier);
1289
1290     ASSERT(m_sqliteDB);
1291     ASSERT(m_sqliteDB->isOpen());
1292
1293     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
1294     if (!objectStoreInfo)
1295         return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1296
1297     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
1298     if (!indexInfo)
1299         return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1300
1301     auto* transaction = m_transactions.get(transactionIdentifier);
1302     if (!transaction || !transaction->inProgress()) {
1303         LOG_ERROR("Attempt to rename an index without an in-progress transaction");
1304         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an index without an in-progress transaction") };
1305     }
1306
1307     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1308         LOG_ERROR("Attempt to rename an index in a non-version-change transaction");
1309         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an index in a non-version-change transaction") };
1310     }
1311
1312     {
1313         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE IndexInfo SET name = ? WHERE objectStoreID = ? AND id = ?;"));
1314         if (sql.prepare() != SQLITE_OK
1315             || sql.bindText(1, newName) != SQLITE_OK
1316             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1317             || sql.bindInt64(3, indexIdentifier) != SQLITE_OK
1318             || sql.step() != SQLITE_DONE) {
1319             LOG_ERROR("Could not update name for index id (%" PRIi64 ", %" PRIi64 ") in IndexInfo table (%i) - %s", objectStoreIdentifier, indexIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1320             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1321         }
1322     }
1323
1324     indexInfo->rename(newName);
1325
1326     return { };
1327 }
1328
1329 IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
1330 {
1331     LOG(IndexedDB, "SQLiteIDBBackingStore::keyExistsInObjectStore - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
1332
1333     ASSERT(m_sqliteDB);
1334     ASSERT(m_sqliteDB->isOpen());
1335
1336     keyExists = false;
1337
1338     auto* transaction = m_transactions.get(transactionIdentifier);
1339     if (!transaction || !transaction->inProgress()) {
1340         LOG_ERROR("Attempt to see if key exists in objectstore without an in-progress transaction");
1341         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to see if key exists in objectstore without an in-progress transaction") };
1342     }
1343
1344     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1345     if (!keyBuffer) {
1346         LOG_ERROR("Unable to serialize IDBKey to check for existence in object store");
1347         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for existence in object store") };
1348     }
1349     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
1350     if (sql.prepare() != SQLITE_OK
1351         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1352         || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
1353         LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1354         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to check for existence of IDBKey in object store") };
1355     }
1356
1357     int sqlResult = sql.step();
1358     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
1359         return { };
1360
1361     if (sqlResult != SQLITE_ROW) {
1362         // There was an error fetching the record from the database.
1363         LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1364         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in object store") };
1365     }
1366
1367     keyExists = true;
1368     return { };
1369 }
1370
1371 IDBError SQLiteIDBBackingStore::deleteUnusedBlobFileRecords(SQLiteIDBTransaction& transaction)
1372 {
1373     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteUnusedBlobFileRecords");
1374
1375     // Gather the set of blob URLs and filenames that are no longer in use.
1376     HashSet<String> removedBlobFilenames;
1377     {
1378         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL NOT IN (SELECT blobURL FROM BlobRecords)"));
1379
1380         if (sql.prepare() != SQLITE_OK) {
1381             LOG_ERROR("Error deleting stored blobs (%i) (Could not gather unused blobURLs) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1382             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1383         }
1384
1385         int result = sql.step();
1386         while (result == SQLITE_ROW) {
1387             removedBlobFilenames.add(sql.getColumnText(0));
1388             result = sql.step();
1389         }
1390
1391         if (result != SQLITE_DONE) {
1392             LOG_ERROR("Error deleting stored blobs (%i) (Could not gather unused blobURLs) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1393             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1394         }
1395     }
1396
1397     // Remove the blob records that are no longer in use.
1398     if (!removedBlobFilenames.isEmpty()) {
1399         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobFiles WHERE blobURL NOT IN (SELECT blobURL FROM BlobRecords)"));
1400
1401         if (sql.prepare() != SQLITE_OK
1402             || sql.step() != SQLITE_DONE) {
1403             LOG_ERROR("Error deleting stored blobs (%i) (Could not delete blobFile records) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1404             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1405         }
1406     }
1407
1408     for (auto& file : removedBlobFilenames)
1409         transaction.addRemovedBlobFile(file);
1410
1411     return { };
1412 }
1413
1414 IDBError SQLiteIDBBackingStore::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const IDBKeyData& keyData)
1415 {
1416     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
1417
1418     ASSERT(m_sqliteDB);
1419     ASSERT(m_sqliteDB->isOpen());
1420     ASSERT(transaction.inProgress());
1421     ASSERT(transaction.mode() != IDBTransactionMode::Readonly);
1422     UNUSED_PARAM(transaction);
1423
1424     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1425     if (!keyBuffer) {
1426         LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
1427         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyData to be removed from the database") };
1428     }
1429
1430     // Get the record ID
1431     int64_t recordID;
1432     {
1433         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT recordID FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1434
1435         if (sql.prepare() != SQLITE_OK
1436             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1437             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
1438             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1439             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1440         }
1441
1442         int result = sql.step();
1443
1444         // If there's no record ID, there's no record to delete.
1445         if (result == SQLITE_DONE)
1446             return { };
1447
1448         if (result != SQLITE_ROW) {
1449             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (unable to fetch record ID) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1450             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1451         }
1452
1453         recordID = sql.getColumnInt64(0);
1454     }
1455
1456     if (recordID < 1) {
1457         LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (record ID is invalid) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1458         return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1459     }
1460
1461     // Delete the blob records for this object store record.
1462     {
1463         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobRecords WHERE objectStoreRow = ?;"));
1464
1465         if (sql.prepare() != SQLITE_OK
1466             || sql.bindInt64(1, recordID) != SQLITE_OK
1467             || sql.step() != SQLITE_DONE) {
1468             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (Could not delete BlobRecords records) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1469             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1470         }
1471     }
1472
1473     auto error = deleteUnusedBlobFileRecords(transaction);
1474     if (!error.isNull())
1475         return error;
1476
1477     // Delete record from object store
1478     {
1479         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1480
1481         if (sql.prepare() != SQLITE_OK
1482             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1483             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1484             || sql.step() != SQLITE_DONE) {
1485             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1486             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1487         }
1488     }
1489
1490     // Delete record from indexes store
1491     {
1492         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
1493
1494         if (sql.prepare() != SQLITE_OK
1495             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1496             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1497             || sql.step() != SQLITE_DONE) {
1498             LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1499             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete index entries for object store record") };
1500         }
1501     }
1502
1503     return { };
1504 }
1505
1506 IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange)
1507 {
1508     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRange - range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1509
1510     ASSERT(m_sqliteDB);
1511     ASSERT(m_sqliteDB->isOpen());
1512
1513     auto* transaction = m_transactions.get(transactionIdentifier);
1514     if (!transaction || !transaction->inProgress()) {
1515         LOG_ERROR("Attempt to delete range from database without an in-progress transaction");
1516         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete range from database without an in-progress transaction") };
1517     }
1518     if (transaction->mode() == IDBTransactionMode::Readonly) {
1519         LOG_ERROR("Attempt to delete records from an object store in a read-only transaction");
1520         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete records from an object store in a read-only transaction") };
1521     }
1522
1523     // If the range to delete is exactly one key we can delete it right now.
1524     if (keyRange.isExactlyOneKey()) {
1525         auto error = deleteRecord(*transaction, objectStoreID, keyRange.lowerKey);
1526         if (!error.isNull()) {
1527             LOG_ERROR("Failed to delete record for key '%s'", keyRange.lowerKey.loggingString().utf8().data());
1528             return error;
1529         }
1530
1531         return { };
1532     }
1533
1534     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, 0, keyRange);
1535     if (!cursor) {
1536         LOG_ERROR("Cannot open cursor to delete range of records from the database");
1537         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to delete range of records from the database") };
1538     }
1539
1540     Vector<IDBKeyData> keys;
1541     while (!cursor->didComplete() && !cursor->didError()) {
1542         keys.append(cursor->currentKey());
1543         cursor->advance(1);
1544     }
1545
1546     if (cursor->didError()) {
1547         LOG_ERROR("Cursor failed while accumulating range of records from the database");
1548         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while accumulating range of records from the database") };
1549     }
1550
1551     IDBError error;
1552     for (auto& key : keys) {
1553         error = deleteRecord(*transaction, objectStoreID, key);
1554         if (!error.isNull()) {
1555             LOG_ERROR("deleteRange: Error deleting keys in range");
1556             break;
1557         }
1558     }
1559
1560     transaction->notifyCursorsOfChanges(objectStoreID);
1561
1562     return error;
1563 }
1564
1565 IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1566 {
1567     JSLockHolder locker(vm());
1568
1569     auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
1570     if (jsValue.isUndefinedOrNull())
1571         return { };
1572
1573     IndexKey indexKey;
1574     generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey);
1575
1576     if (indexKey.isNull())
1577         return { };
1578
1579     return uncheckedPutIndexKey(info, key, indexKey);
1580 }
1581
1582 IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1583 {
1584     JSLockHolder locker(vm());
1585
1586     auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
1587     if (jsValue.isUndefinedOrNull())
1588         return { };
1589
1590     IDBError error;
1591     bool anyRecordsSucceeded = false;
1592     for (auto& index : info.indexMap().values()) {
1593         IndexKey indexKey;
1594         generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
1595
1596         if (indexKey.isNull())
1597             continue;
1598
1599         error = uncheckedPutIndexKey(index, key, indexKey);
1600         if (!error.isNull())
1601             break;
1602
1603         anyRecordsSucceeded = true;
1604     }
1605
1606     if (!error.isNull() && anyRecordsSucceeded) {
1607         RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(key);
1608
1609         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
1610
1611         if (sql.prepare() != SQLITE_OK
1612             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1613             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1614             || sql.step() != SQLITE_DONE) {
1615             LOG_ERROR("Adding one Index record failed, but failed to remove all others that previously succeeded");
1616             return { IDBDatabaseException::UnknownError, ASCIILiteral("Adding one Index record failed, but failed to remove all others that previously succeeded") };
1617         }
1618     }
1619
1620     return error;
1621 }
1622
1623 IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const IDBValue& value)
1624 {
1625     LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreInfo.identifier());
1626
1627     ASSERT(m_sqliteDB);
1628     ASSERT(m_sqliteDB->isOpen());
1629     ASSERT(value.data().data());
1630     ASSERT(value.blobURLs().size() == value.blobFilePaths().size());
1631
1632     auto* transaction = m_transactions.get(transactionIdentifier);
1633     if (!transaction || !transaction->inProgress()) {
1634         LOG_ERROR("Attempt to store a record in an object store without an in-progress transaction");
1635         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store without an in-progress transaction") };
1636     }
1637     if (transaction->mode() == IDBTransactionMode::Readonly) {
1638         LOG_ERROR("Attempt to store a record in an object store in a read-only transaction");
1639         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store in a read-only transaction") };
1640     }
1641
1642     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1643     if (!keyBuffer) {
1644         LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
1645         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
1646     }
1647
1648     int64_t recordID = 0;
1649     {
1650         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?, NULL);"));
1651         if (sql.prepare() != SQLITE_OK
1652             || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
1653             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1654             || sql.bindBlob(3, value.data().data()->data(), value.data().data()->size()) != SQLITE_OK
1655             || sql.step() != SQLITE_DONE) {
1656             LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreInfo.identifier(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1657             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
1658         }
1659
1660         recordID = m_sqliteDB->lastInsertRowID();
1661     }
1662
1663     auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value.data());
1664
1665     if (!error.isNull()) {
1666         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1667         if (sql.prepare() != SQLITE_OK
1668             || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
1669             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1670             || sql.step() != SQLITE_DONE) {
1671             LOG_ERROR("Indexing new object store record failed, but unable to remove the object store record itself");
1672             return { IDBDatabaseException::UnknownError, ASCIILiteral("Indexing new object store record failed, but unable to remove the object store record itself") };
1673         }
1674
1675         return error;
1676     }
1677
1678     const Vector<String>& blobURLs = value.blobURLs();
1679     const Vector<String>& blobFiles = value.blobFilePaths();
1680     for (size_t i = 0; i < blobURLs.size(); ++i) {
1681         auto& url = blobURLs[i];
1682         {
1683             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobRecords VALUES (?, ?);"));
1684             if (sql.prepare() != SQLITE_OK
1685                 || sql.bindInt64(1, recordID) != SQLITE_OK
1686                 || sql.bindText(2, url) != SQLITE_OK
1687                 || sql.step() != SQLITE_DONE) {
1688                 LOG_ERROR("Unable to record Blob record in database");
1689                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob record in database") };
1690             }
1691         }
1692         int64_t potentialFileNameInteger = m_sqliteDB->lastInsertRowID();
1693
1694         // If we already have a file for this blobURL, nothing left to do.
1695         {
1696             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?;"));
1697             if (sql.prepare() != SQLITE_OK
1698                 || sql.bindText(1, url) != SQLITE_OK) {
1699                 LOG_ERROR("Unable to examine Blob filenames in database");
1700                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
1701             }
1702
1703             int result = sql.step();
1704             if (result != SQLITE_ROW && result != SQLITE_DONE) {
1705                 LOG_ERROR("Unable to examine Blob filenames in database");
1706                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
1707             }
1708
1709             if (result == SQLITE_ROW)
1710                 continue;
1711         }
1712
1713         // We don't already have a file for this blobURL, so commit our file as a unique filename
1714         String storedFilename = String::format("%" PRId64 ".blob", potentialFileNameInteger);
1715         {
1716             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobFiles VALUES (?, ?);"));
1717             if (sql.prepare() != SQLITE_OK
1718                 || sql.bindText(1, url) != SQLITE_OK
1719                 || sql.bindText(2, storedFilename) != SQLITE_OK
1720                 || sql.step() != SQLITE_DONE) {
1721                 LOG_ERROR("Unable to record Blob file record in database");
1722                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob file record in database") };
1723             }
1724         }
1725
1726         transaction->addBlobFile(blobFiles[i], storedFilename);
1727     }
1728
1729     transaction->notifyCursorsOfChanges(objectStoreInfo.identifier());
1730
1731     return error;
1732 }
1733
1734 IDBError SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, Vector<String>& blobFilePaths)
1735 {
1736     ASSERT(objectStoreRecord);
1737
1738     HashSet<String> blobURLSet;
1739     {
1740         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT blobURL FROM BlobRecords WHERE objectStoreRow = ?"));
1741         if (sql.prepare() != SQLITE_OK
1742             || sql.bindInt64(1, objectStoreRecord) != SQLITE_OK) {
1743             LOG_ERROR("Could not prepare statement to fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1744             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1745         }
1746
1747         int sqlResult = sql.step();
1748         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1749             // There are no blobURLs in the database for this object store record.
1750             return { };
1751         }
1752
1753         while (sqlResult == SQLITE_ROW) {
1754             blobURLSet.add(sql.getColumnText(0));
1755             sqlResult = sql.step();
1756         }
1757
1758         if (sqlResult != SQLITE_DONE) {
1759             LOG_ERROR("Could not fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1760             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1761         }
1762     }
1763
1764     ASSERT(!blobURLSet.isEmpty());
1765     String databaseDirectory = fullDatabaseDirectory();
1766     for (auto& blobURL : blobURLSet) {
1767         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?"));
1768         if (sql.prepare() != SQLITE_OK
1769             || sql.bindText(1, blobURL) != SQLITE_OK) {
1770             LOG_ERROR("Could not prepare statement to fetch blob filename for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1771             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1772         }
1773
1774         if (sql.step() != SQLITE_ROW) {
1775             LOG_ERROR("Entry for blob filename for blob url %s does not exist (%i) - %s", blobURL.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1776             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1777         }
1778
1779         blobURLs.append(blobURL);
1780
1781         String fileName = sql.getColumnText(0);
1782         blobFilePaths.append(pathByAppendingComponent(databaseDirectory, fileName));
1783     }
1784
1785     return { };
1786 }
1787
1788 IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, IDBGetResult& resultValue)
1789 {
1790     LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1791
1792     ASSERT(m_sqliteDB);
1793     ASSERT(m_sqliteDB->isOpen());
1794
1795     auto* transaction = m_transactions.get(transactionIdentifier);
1796     if (!transaction || !transaction->inProgress()) {
1797         LOG_ERROR("Attempt to get a record from database without an in-progress transaction");
1798         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get a record from database without an in-progress transaction") };
1799     }
1800
1801     auto key = keyRange.lowerKey;
1802     if (key.isNull())
1803         key = IDBKeyData::minimum();
1804     RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(key);
1805     if (!lowerBuffer) {
1806         LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
1807         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
1808     }
1809
1810     key = keyRange.upperKey;
1811     if (key.isNull())
1812         key = IDBKeyData::maximum();
1813     RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(key);
1814     if (!upperBuffer) {
1815         LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
1816         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
1817     }
1818
1819     int64_t recordID = 0;
1820     ThreadSafeDataBuffer resultBuffer;
1821     {
1822         static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1823         static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1824         static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1825         static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1826
1827         const ASCIILiteral* query = nullptr;
1828
1829         if (keyRange.lowerOpen) {
1830             if (keyRange.upperOpen)
1831                 query = &lowerOpenUpperOpen.get();
1832             else
1833                 query = &lowerOpenUpperClosed.get();
1834         } else {
1835             if (keyRange.upperOpen)
1836                 query = &lowerClosedUpperOpen.get();
1837             else
1838                 query = &lowerClosedUpperClosed.get();
1839         }
1840
1841         ASSERT(query);
1842
1843         SQLiteStatement sql(*m_sqliteDB, *query);
1844         if (sql.prepare() != SQLITE_OK
1845             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1846             || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1847             || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1848             LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1849             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
1850         }
1851
1852         int sqlResult = sql.step();
1853
1854         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1855             // There was no record for the key in the database.
1856             return { };
1857         }
1858         if (sqlResult != SQLITE_ROW) {
1859             // There was an error fetching the record from the database.
1860             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1861             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
1862         }
1863
1864         Vector<uint8_t> buffer;
1865         sql.getColumnBlobAsVector(0, buffer);
1866         resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);
1867
1868         recordID = sql.getColumnInt64(1);
1869     }
1870
1871     ASSERT(recordID);
1872     Vector<String> blobURLs, blobFilePaths;
1873     auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
1874     ASSERT(blobURLs.size() == blobFilePaths.size());
1875
1876     if (!error.isNull())
1877         return error;
1878
1879     resultValue = { { resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) } };
1880     return { };
1881 }
1882
1883 IDBError SQLiteIDBBackingStore::getAllRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
1884 {
1885     return getAllRecordsData.indexIdentifier ? getAllIndexRecords(transactionIdentifier, getAllRecordsData, result) : getAllObjectStoreRecords(transactionIdentifier, getAllRecordsData, result);
1886 }
1887
1888 static const ASCIILiteral& queryForGetAllObjectStoreRecords(const IDBGetAllRecordsData& getAllRecordsData)
1889 {
1890     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpenKey("SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1891     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosedKey("SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1892     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpenKey("SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1893     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosedKey("SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1894     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpenValue("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1895     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosedValue("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1896     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpenValue("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1897     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosedValue("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1898
1899     if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
1900         if (getAllRecordsData.keyRangeData.lowerOpen) {
1901             if (getAllRecordsData.keyRangeData.upperOpen)
1902                 return lowerOpenUpperOpenKey.get();
1903             return lowerOpenUpperClosedKey.get();
1904         }
1905
1906         if (getAllRecordsData.keyRangeData.upperOpen)
1907             return lowerClosedUpperOpenKey.get();
1908         return lowerClosedUpperClosedKey.get();
1909     }
1910
1911     if (getAllRecordsData.keyRangeData.lowerOpen) {
1912         if (getAllRecordsData.keyRangeData.upperOpen)
1913             return lowerOpenUpperOpenValue.get();
1914         return lowerOpenUpperClosedValue.get();
1915     }
1916
1917     if (getAllRecordsData.keyRangeData.upperOpen)
1918         return lowerClosedUpperOpenValue.get();
1919     return lowerClosedUpperClosedValue.get();
1920 }
1921
1922 IDBError SQLiteIDBBackingStore::getAllObjectStoreRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
1923 {
1924     LOG(IndexedDB, "SQLiteIDBBackingStore::getAllObjectStoreRecords");
1925
1926     ASSERT(m_sqliteDB);
1927     ASSERT(m_sqliteDB->isOpen());
1928
1929     auto* transaction = m_transactions.get(transactionIdentifier);
1930     if (!transaction || !transaction->inProgress()) {
1931         LOG_ERROR("Attempt to get records from database without an in-progress transaction");
1932         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get records from database without an in-progress transaction") };
1933     }
1934
1935     auto key = getAllRecordsData.keyRangeData.lowerKey;
1936     if (key.isNull())
1937         key = IDBKeyData::minimum();
1938     auto lowerBuffer = serializeIDBKeyData(key);
1939     if (!lowerBuffer) {
1940         LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
1941         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
1942     }
1943
1944     key = getAllRecordsData.keyRangeData.upperKey;
1945     if (key.isNull())
1946         key = IDBKeyData::maximum();
1947     auto upperBuffer = serializeIDBKeyData(key);
1948     if (!upperBuffer) {
1949         LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
1950         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
1951     }
1952
1953     SQLiteStatement sql(*m_sqliteDB, queryForGetAllObjectStoreRecords(getAllRecordsData));
1954     if (sql.prepare() != SQLITE_OK
1955         || sql.bindInt64(1, getAllRecordsData.objectStoreIdentifier) != SQLITE_OK
1956         || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1957         || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1958         LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", getAllRecordsData.objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1959         return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
1960     }
1961
1962     result = { getAllRecordsData.getAllType };
1963
1964     uint32_t targetResults;
1965     if (getAllRecordsData.count && getAllRecordsData.count.value())
1966         targetResults = getAllRecordsData.count.value();
1967     else
1968         targetResults = std::numeric_limits<uint32_t>::max();
1969
1970     int sqlResult = sql.step();
1971     uint32_t returnedResults = 0;
1972
1973     while (sqlResult == SQLITE_ROW && returnedResults < targetResults) {
1974         if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values) {
1975             Vector<uint8_t> buffer;
1976             sql.getColumnBlobAsVector(0, buffer);
1977             ThreadSafeDataBuffer resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);
1978
1979             auto recordID = sql.getColumnInt64(1);
1980
1981             ASSERT(recordID);
1982             Vector<String> blobURLs, blobFilePaths;
1983             auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
1984             ASSERT(blobURLs.size() == blobFilePaths.size());
1985
1986             if (!error.isNull())
1987                 return error;
1988
1989             result.addValue({ resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) });
1990         } else {
1991             Vector<uint8_t> keyData;
1992             IDBKeyData key;
1993             sql.getColumnBlobAsVector(0, keyData);
1994
1995             if (!deserializeIDBKeyData(keyData.data(), keyData.size(), key)) {
1996                 LOG_ERROR("Unable to deserialize key data from database while getting all key records");
1997                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to deserialize key data while getting all key records") };
1998             }
1999
2000             result.addKey(WTFMove(key));
2001         }
2002
2003         ++returnedResults;
2004         sqlResult = sql.step();
2005     }
2006
2007     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE || sqlResult == SQLITE_ROW) {
2008         // Finished getting results
2009         return { };
2010     }
2011
2012     // There was an error fetching records from the database.
2013     LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", getAllRecordsData.objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2014     return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
2015 }
2016
2017 IDBError SQLiteIDBBackingStore::getAllIndexRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
2018 {
2019     LOG(IndexedDB, "SQLiteIDBBackingStore::getAllIndexRecords - %s", getAllRecordsData.keyRangeData.loggingString().utf8().data());
2020
2021     ASSERT(m_sqliteDB);
2022     ASSERT(m_sqliteDB->isOpen());
2023
2024     auto* transaction = m_transactions.get(transactionIdentifier);
2025     if (!transaction || !transaction->inProgress()) {
2026         LOG_ERROR("Attempt to get all index records from database without an in-progress transaction");
2027         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get all index records from database without an in-progress transaction") };
2028     }
2029
2030     auto cursor = transaction->maybeOpenBackingStoreCursor(getAllRecordsData.objectStoreIdentifier, getAllRecordsData.indexIdentifier, getAllRecordsData.keyRangeData);
2031     if (!cursor) {
2032         LOG_ERROR("Cannot open cursor to perform index gets in database");
2033         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to perform index gets in database") };
2034     }
2035
2036     if (cursor->didError()) {
2037         LOG_ERROR("Cursor failed while looking up index records in database");
2038         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index records in database") };
2039     }
2040
2041     result = { getAllRecordsData.getAllType };
2042     uint32_t currentCount = 0;
2043     uint32_t targetCount = getAllRecordsData.count ? getAllRecordsData.count.value() : 0;
2044     if (!targetCount)
2045         targetCount = std::numeric_limits<uint32_t>::max();
2046     while (!cursor->didComplete() && !cursor->didError() && currentCount < targetCount) {
2047         if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
2048             IDBKeyData keyCopy = cursor->currentPrimaryKey();
2049             result.addKey(WTFMove(keyCopy));
2050         } else
2051             result.addValue(cursor->currentValue() ? *cursor->currentValue() : IDBValue());
2052
2053         ++currentCount;
2054         cursor->advance(1);
2055     }
2056
2057     if (cursor->didError()) {
2058         LOG_ERROR("Cursor failed while looking up index records in database");
2059         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index records in database") };
2060     }
2061
2062     return { };
2063 }
2064
2065 IDBError SQLiteIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t indexID, IndexedDB::IndexRecordType type, const IDBKeyRangeData& range, IDBGetResult& getResult)
2066 {
2067     LOG(IndexedDB, "SQLiteIDBBackingStore::getIndexRecord - %s", range.loggingString().utf8().data());
2068
2069     ASSERT(m_sqliteDB);
2070     ASSERT(m_sqliteDB->isOpen());
2071
2072     auto* transaction = m_transactions.get(transactionIdentifier);
2073     if (!transaction || !transaction->inProgress()) {
2074         LOG_ERROR("Attempt to get an index record from database without an in-progress transaction");
2075         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get an index record from database without an in-progress transaction") };
2076     }
2077
2078     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, indexID, range);
2079     if (!cursor) {
2080         LOG_ERROR("Cannot open cursor to perform index get in database");
2081         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to perform index get in database") };
2082     }
2083
2084     if (cursor->didError()) {
2085         LOG_ERROR("Cursor failed while looking up index record in database");
2086         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index record in database") };
2087     }
2088
2089     if (cursor->didComplete())
2090         getResult = { };
2091     else {
2092         if (type == IndexedDB::IndexRecordType::Key)
2093             getResult = { cursor->currentPrimaryKey() };
2094         else
2095             getResult = { cursor->currentValue() ? *cursor->currentValue() : IDBValue(), cursor->currentPrimaryKey() };
2096     }
2097
2098     return { };
2099 }
2100
2101 IDBError SQLiteIDBBackingStore::getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& range, uint64_t& outCount)
2102 {
2103     LOG(IndexedDB, "SQLiteIDBBackingStore::getCount - object store %" PRIu64, objectStoreIdentifier);
2104     ASSERT(m_sqliteDB);
2105     ASSERT(m_sqliteDB->isOpen());
2106
2107     outCount = 0;
2108
2109     auto* transaction = m_transactions.get(transactionIdentifier);
2110     if (!transaction || !transaction->inProgress()) {
2111         LOG_ERROR("Attempt to get count from database without an in-progress transaction");
2112         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get count from database without an in-progress transaction") };
2113     }
2114
2115     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreIdentifier, indexIdentifier, range);
2116     if (!cursor) {
2117         LOG_ERROR("Cannot open cursor to populate indexes in database");
2118         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
2119     }
2120
2121     while (cursor->advance(1))
2122         ++outCount;
2123
2124     return { };
2125 }
2126
2127 IDBError SQLiteIDBBackingStore::uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t& outValue)
2128 {
2129     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT currentKey FROM KeyGenerators WHERE objectStoreID = ?;"));
2130     if (sql.prepare() != SQLITE_OK
2131         || sql.bindInt64(1, objectStoreID) != SQLITE_OK) {
2132         LOG_ERROR("Could not retrieve currentKey from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2133         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error getting current key generator value from database") };
2134     }
2135     int result = sql.step();
2136     if (result != SQLITE_ROW) {
2137         LOG_ERROR("Could not retreive key generator value for object store, but it should be there.");
2138         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error finding current key generator value in database") };
2139     }
2140
2141     int64_t value = sql.getColumnInt64(0);
2142     if (value < 0)
2143         return { IDBDatabaseException::ConstraintError, "Current key generator value from database is invalid" };
2144
2145     outValue = value;
2146     return { };
2147 }
2148
2149 IDBError SQLiteIDBBackingStore::uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value)
2150 {
2151     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, ?);"));
2152     if (sql.prepare() != SQLITE_OK
2153         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
2154         || sql.bindInt64(2, value) != SQLITE_OK
2155         || sql.step() != SQLITE_DONE) {
2156         LOG_ERROR("Could not update key generator value (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2157         return { IDBDatabaseException::ConstraintError, "Error storing new key generator value in database" };
2158     }
2159
2160     return { };
2161 }
2162
2163 IDBError SQLiteIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t& generatedKey)
2164 {
2165     LOG(IndexedDB, "SQLiteIDBBackingStore::generateKeyNumber");
2166
2167     ASSERT(m_sqliteDB);
2168     ASSERT(m_sqliteDB->isOpen());
2169
2170     // The IndexedDatabase spec defines the max key generator value as 2^53;
2171     static uint64_t maxGeneratorValue = 0x20000000000000;
2172
2173     auto* transaction = m_transactions.get(transactionIdentifier);
2174     if (!transaction || !transaction->inProgress()) {
2175         LOG_ERROR("Attempt to generate key in database without an in-progress transaction");
2176         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in database without an in-progress transaction") };
2177     }
2178     if (transaction->mode() == IDBTransactionMode::Readonly) {
2179         LOG_ERROR("Attempt to generate key in a read-only transaction");
2180         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in a read-only transaction") };
2181     }
2182
2183     uint64_t currentValue;
2184     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
2185     if (!error.isNull())
2186         return error;
2187
2188     if (currentValue + 1 > maxGeneratorValue)
2189         return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
2190
2191     generatedKey = currentValue + 1;
2192     return uncheckedSetKeyGeneratorValue(objectStoreID, generatedKey);
2193 }
2194
2195 IDBError SQLiteIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t newKeyNumber)
2196 {
2197     LOG(IndexedDB, "SQLiteIDBBackingStore::revertGeneratedKeyNumber - object store %" PRIu64 ", reverted number %" PRIu64, objectStoreID, newKeyNumber);
2198
2199     ASSERT(m_sqliteDB);
2200     ASSERT(m_sqliteDB->isOpen());
2201
2202     auto* transaction = m_transactions.get(transactionIdentifier);
2203     if (!transaction || !transaction->inProgress()) {
2204         LOG_ERROR("Attempt to revert key generator value in database without an in-progress transaction");
2205         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in database without an in-progress transaction") };
2206     }
2207     if (transaction->mode() == IDBTransactionMode::Readonly) {
2208         LOG_ERROR("Attempt to revert key generator value in a read-only transaction");
2209         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in a read-only transaction") };
2210     }
2211
2212     ASSERT(newKeyNumber);
2213     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyNumber - 1);
2214 }
2215
2216 IDBError SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, double newKeyNumber)
2217 {
2218     LOG(IndexedDB, "SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber");
2219
2220     ASSERT(m_sqliteDB);
2221     ASSERT(m_sqliteDB->isOpen());
2222
2223     auto* transaction = m_transactions.get(transactionIdentifier);
2224     if (!transaction || !transaction->inProgress()) {
2225         LOG_ERROR("Attempt to update key generator value in database without an in-progress transaction");
2226         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in database without an in-progress transaction") };
2227     }
2228     if (transaction->mode() == IDBTransactionMode::Readonly) {
2229         LOG_ERROR("Attempt to update key generator value in a read-only transaction");
2230         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in a read-only transaction") };
2231     }
2232
2233     uint64_t currentValue;
2234     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
2235     if (!error.isNull())
2236         return error;
2237
2238     if (newKeyNumber <= currentValue)
2239         return { };
2240
2241     uint64_t newKeyInteger(newKeyNumber);
2242     if (newKeyInteger <= uint64_t(newKeyNumber))
2243         ++newKeyInteger;
2244
2245     ASSERT(newKeyInteger > uint64_t(newKeyNumber));
2246
2247     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyInteger - 1);
2248 }
2249
2250 IDBError SQLiteIDBBackingStore::openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info, IDBGetResult& result)
2251 {
2252     ASSERT(m_sqliteDB);
2253     ASSERT(m_sqliteDB->isOpen());
2254
2255     auto* transaction = m_transactions.get(transactionIdentifier);
2256     if (!transaction || !transaction->inProgress()) {
2257         LOG_ERROR("Attempt to open a cursor in database without an in-progress transaction");
2258         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to open a cursor in database without an in-progress transaction") };
2259     }
2260
2261     auto* cursor = transaction->maybeOpenCursor(info);
2262     if (!cursor) {
2263         LOG_ERROR("Unable to open cursor");
2264         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open cursor") };
2265     }
2266
2267     m_cursors.set(cursor->identifier(), cursor);
2268
2269     cursor->currentData(result);
2270     return { };
2271 }
2272
2273 IDBError SQLiteIDBBackingStore::iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBIterateCursorData& data, IDBGetResult& result)
2274 {
2275     LOG(IndexedDB, "SQLiteIDBBackingStore::iterateCursor");
2276
2277     ASSERT(m_sqliteDB);
2278     ASSERT(m_sqliteDB->isOpen());
2279
2280     auto* cursor = m_cursors.get(cursorIdentifier);
2281     if (!cursor) {
2282         LOG_ERROR("Attempt to iterate a cursor that doesn't exist");
2283         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor that doesn't exist") };
2284     }
2285
2286     ASSERT_UNUSED(transactionIdentifier, cursor->transaction()->transactionIdentifier() == transactionIdentifier);
2287
2288     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
2289         LOG_ERROR("Attempt to iterate a cursor without an in-progress transaction");
2290         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor without an in-progress transaction") };
2291     }
2292
2293     auto key = data.keyData;
2294     auto primaryKey = data.primaryKeyData;
2295     auto count = data.count;
2296
2297     if (key.isValid()) {
2298         if (!cursor->iterate(key, primaryKey)) {
2299             LOG_ERROR("Attempt to iterate cursor failed");
2300             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate cursor failed") };
2301         }
2302     } else {
2303         ASSERT(!primaryKey.isValid());
2304         if (!count)
2305             count = 1;
2306         if (!cursor->advance(count)) {
2307             LOG_ERROR("Attempt to advance cursor failed");
2308             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to advance cursor failed") };
2309         }
2310     }
2311
2312     cursor->currentData(result);
2313     return { };
2314 }
2315
2316 IDBObjectStoreInfo* SQLiteIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
2317 {
2318     ASSERT(m_databaseInfo);
2319     return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
2320 }
2321
2322 void SQLiteIDBBackingStore::deleteBackingStore()
2323 {
2324     String dbFilename = fullDatabasePath();
2325
2326     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteBackingStore deleting file '%s' on disk", dbFilename.utf8().data());
2327
2328     Vector<String> blobFiles;
2329     {
2330         bool errored = true;
2331
2332         if (m_sqliteDB) {
2333             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles;"));
2334             if (sql.prepare() == SQLITE_OK) {
2335                 int result = sql.step();
2336                 while (result == SQLITE_ROW) {
2337                     blobFiles.append(sql.getColumnText(0));
2338                     result = sql.step();
2339                 }
2340
2341                 if (result == SQLITE_DONE)
2342                     errored = false;
2343             }
2344         }
2345
2346         if (errored)
2347             LOG_ERROR("Error getting all blob filenames to be deleted");
2348     }
2349
2350     String databaseDirectory = fullDatabaseDirectory();
2351     for (auto& file : blobFiles) {
2352         String fullPath = pathByAppendingComponent(databaseDirectory, file);
2353         if (!deleteFile(fullPath))
2354             LOG_ERROR("Error deleting blob file %s", fullPath.utf8().data());
2355     }
2356
2357     if (m_sqliteDB) {
2358         m_sqliteDB->close();
2359         m_sqliteDB = nullptr;
2360     }
2361
2362     SQLiteFileSystem::deleteDatabaseFile(dbFilename);
2363     SQLiteFileSystem::deleteEmptyDatabaseDirectory(fullDatabaseDirectory());
2364     SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_absoluteDatabaseDirectory);
2365 }
2366
2367 void SQLiteIDBBackingStore::unregisterCursor(SQLiteIDBCursor& cursor)
2368 {
2369     ASSERT(m_cursors.contains(cursor.identifier()));
2370     m_cursors.remove(cursor.identifier());
2371 }
2372
2373 } // namespace IDBServer
2374 } // namespace WebCore
2375
2376 #endif // ENABLE(INDEXED_DATABASE)