IndexedDB 2.0: Encapsulate cursor iteration parameters for easy future expansion.
[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             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             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
811     if (transaction->mode() == IDBTransactionMode::Versionchange) {
812         ASSERT(m_originalDatabaseInfoBeforeVersionChange);
813         m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
814     }
815
816     return transaction->abort();
817 }
818
819 IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier& identifier)
820 {
821     LOG(IndexedDB, "SQLiteIDBBackingStore::commitTransaction - %s", identifier.loggingString().utf8().data());
822
823     ASSERT(m_sqliteDB);
824     ASSERT(m_sqliteDB->isOpen());
825
826     auto transaction = m_transactions.take(identifier);
827     if (!transaction) {
828         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
829         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit a transaction that hasn't been established") };
830     }
831
832     auto error = transaction->commit();
833     if (!error.isNull()) {
834         if (transaction->mode() == IDBTransactionMode::Versionchange) {
835             ASSERT(m_originalDatabaseInfoBeforeVersionChange);
836             m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange);
837         }
838     } else
839         m_originalDatabaseInfoBeforeVersionChange = nullptr;
840
841     return error;
842 }
843
844 IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
845 {
846     LOG(IndexedDB, "SQLiteIDBBackingStore::createObjectStore - adding OS %s with ID %" PRIu64, info.name().utf8().data(), info.identifier());
847
848     ASSERT(m_sqliteDB);
849     ASSERT(m_sqliteDB->isOpen());
850
851     auto* transaction = m_transactions.get(transactionIdentifier);
852     if (!transaction || !transaction->inProgress()) {
853         LOG_ERROR("Attempt to create an object store without an in-progress transaction");
854         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store without an in-progress transaction") };
855     }
856     if (transaction->mode() != IDBTransactionMode::Versionchange) {
857         LOG_ERROR("Attempt to create an object store in a non-version-change transaction");
858         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an object store in a non-version-change transaction") };
859     }
860
861     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
862     if (!keyPathBlob) {
863         LOG_ERROR("Unable to serialize IDBKeyPath to save in database for new object store");
864         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to save in database for new object store") };
865     }
866
867     {
868         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
869         if (sql.prepare() != SQLITE_OK
870             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
871             || sql.bindText(2, info.name()) != SQLITE_OK
872             || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
873             || sql.bindInt(4, info.autoIncrement()) != SQLITE_OK
874             || sql.bindInt64(5, info.maxIndexID()) != SQLITE_OK
875             || sql.step() != SQLITE_DONE) {
876             LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
877             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not create object store") };
878         }
879     }
880
881     {
882         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, 0);"));
883         if (sql.prepare() != SQLITE_OK
884             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
885             || sql.step() != SQLITE_DONE) {
886             LOG_ERROR("Could not seed initial key generator value for ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
887             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not seed initial key generator value for object store") };
888         }
889     }
890
891     m_databaseInfo->addExistingObjectStore(info);
892
893     return { };
894 }
895
896 IDBError SQLiteIDBBackingStore::deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
897 {
898     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteObjectStore - object store %" PRIu64, objectStoreIdentifier);
899
900     ASSERT(m_sqliteDB);
901     ASSERT(m_sqliteDB->isOpen());
902
903     auto* transaction = m_transactions.get(transactionIdentifier);
904     if (!transaction || !transaction->inProgress()) {
905         LOG_ERROR("Attempt to delete an object store without an in-progress transaction");
906         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store without an in-progress transaction") };
907     }
908     if (transaction->mode() != IDBTransactionMode::Versionchange) {
909         LOG_ERROR("Attempt to delete an object store in a non-version-change transaction");
910         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete an object store in a non-version-change transaction") };
911     }
912
913     // Delete the ObjectStore record
914     {
915         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
916         if (sql.prepare() != SQLITE_OK
917             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
918             || sql.step() != SQLITE_DONE) {
919             LOG_ERROR("Could not delete object store id %" PRIi64 " from ObjectStoreInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
920             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete object store") };
921         }
922     }
923
924     // Delete the ObjectStore's key generator record if there is one.
925     {
926         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM KeyGenerators WHERE objectStoreID = ?;"));
927         if (sql.prepare() != SQLITE_OK
928             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
929             || sql.step() != SQLITE_DONE) {
930             LOG_ERROR("Could not delete object store from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
931             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete key generator for deleted object store") };
932         }
933     }
934
935     // Delete all associated records
936     {
937         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
938         if (sql.prepare() != SQLITE_OK
939             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
940             || sql.step() != SQLITE_DONE) {
941             LOG_ERROR("Could not delete records for object store %" PRIi64 " (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
942             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete records for deleted object store") };
943         }
944     }
945
946     // Delete all associated Indexes
947     {
948         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
949         if (sql.prepare() != SQLITE_OK
950             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
951             || sql.step() != SQLITE_DONE) {
952             LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
953             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex for deleted object store") };
954         }
955     }
956
957     // Delete all associated Index records
958     {
959         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
960         if (sql.prepare() != SQLITE_OK
961             || sql.bindInt64(1, objectStoreIdentifier) != SQLITE_OK
962             || sql.step() != SQLITE_DONE) {
963             LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
964             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete IDBIndex records for deleted object store") };
965         }
966     }
967
968     // Delete all unused Blob URL records.
969     {
970         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobRecords WHERE objectStoreRow NOT IN (SELECT recordID FROM Records)"));
971         if (sql.prepare() != SQLITE_OK
972             || sql.step() != SQLITE_DONE) {
973             LOG_ERROR("Could not delete Blob URL records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
974             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not delete stored blob records for deleted object store") };
975         }
976     }
977
978     // Delete all unused Blob File records.
979     auto error = deleteUnusedBlobFileRecords(*transaction);
980     if (!error.isNull())
981         return error;
982
983     m_databaseInfo->deleteObjectStore(objectStoreIdentifier);
984
985     return { };
986 }
987
988 IDBError SQLiteIDBBackingStore::renameObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName)
989 {
990     LOG(IndexedDB, "SQLiteIDBBackingStore::renameObjectStore - object store %" PRIu64, objectStoreIdentifier);
991
992     ASSERT(m_sqliteDB);
993     ASSERT(m_sqliteDB->isOpen());
994
995     auto* transaction = m_transactions.get(transactionIdentifier);
996     if (!transaction || !transaction->inProgress()) {
997         LOG_ERROR("Attempt to rename an object store without an in-progress transaction");
998         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an object store without an in-progress transaction") };
999     }
1000     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1001         LOG_ERROR("Attempt to rename an object store in a non-version-change transaction");
1002         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an object store in a non-version-change transaction") };
1003     }
1004
1005     {
1006         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE ObjectStoreInfo SET name = ? WHERE id = ?;"));
1007         if (sql.prepare() != SQLITE_OK
1008             || sql.bindText(1, newName) != SQLITE_OK
1009             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1010             || sql.step() != SQLITE_DONE) {
1011             LOG_ERROR("Could not update name for object store id %" PRIi64 " in ObjectStoreInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1012             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename object store") };
1013         }
1014     }
1015
1016     m_databaseInfo->renameObjectStore(objectStoreIdentifier, newName);
1017
1018     return { };
1019 }
1020
1021 IDBError SQLiteIDBBackingStore::clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID)
1022 {
1023     LOG(IndexedDB, "SQLiteIDBBackingStore::clearObjectStore - object store %" PRIu64, objectStoreID);
1024
1025     ASSERT(m_sqliteDB);
1026     ASSERT(m_sqliteDB->isOpen());
1027
1028     auto* transaction = m_transactions.get(transactionIdentifier);
1029     if (!transaction || !transaction->inProgress()) {
1030         LOG_ERROR("Attempt to clear an object store without an in-progress transaction");
1031         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store without an in-progress transaction") };
1032     }
1033     if (transaction->mode() == IDBTransactionMode::Readonly) {
1034         LOG_ERROR("Attempt to clear an object store in a read-only transaction");
1035         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to clear an object store in a read-only transaction") };
1036     }
1037
1038     {
1039         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
1040         if (sql.prepare() != SQLITE_OK
1041             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1042             || sql.step() != SQLITE_DONE) {
1043             LOG_ERROR("Could not clear records from object store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1044             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to clear object store") };
1045         }
1046     }
1047
1048     {
1049         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
1050         if (sql.prepare() != SQLITE_OK
1051             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1052             || sql.step() != SQLITE_DONE) {
1053             LOG_ERROR("Could not delete records from index record store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1054             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to delete index records while clearing object store") };
1055         }
1056     }
1057
1058     transaction->notifyCursorsOfChanges(objectStoreID);
1059
1060     return { };
1061 }
1062
1063 IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
1064 {
1065     LOG(IndexedDB, "SQLiteIDBBackingStore::createIndex - ObjectStore %" PRIu64 ", Index %" PRIu64, info.objectStoreIdentifier(), info.identifier());
1066     ASSERT(m_sqliteDB);
1067     ASSERT(m_sqliteDB->isOpen());
1068
1069     auto* transaction = m_transactions.get(transactionIdentifier);
1070     if (!transaction || !transaction->inProgress()) {
1071         LOG_ERROR("Attempt to create an index without an in-progress transaction");
1072         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index without an in-progress transaction") };
1073     }
1074     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1075         LOG_ERROR("Attempt to create an index in a non-version-change transaction");
1076         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index in a non-version-change transaction") };
1077     }
1078
1079     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
1080     if (!keyPathBlob) {
1081         LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
1082         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to create index in database") };
1083     }
1084
1085     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
1086     if (sql.prepare() != SQLITE_OK
1087         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1088         || sql.bindText(2, info.name()) != SQLITE_OK
1089         || sql.bindInt64(3, info.objectStoreIdentifier()) != SQLITE_OK
1090         || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
1091         || sql.bindInt(5, info.unique()) != SQLITE_OK
1092         || sql.bindInt(6, info.multiEntry()) != SQLITE_OK
1093         || sql.step() != SQLITE_DONE) {
1094         LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1095         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to create index in database") };
1096     }
1097
1098     // Write index records for any records that already exist in this object store.
1099
1100     auto cursor = transaction->maybeOpenBackingStoreCursor(info.objectStoreIdentifier(), 0, IDBKeyRangeData::allKeys());
1101
1102     if (!cursor) {
1103         LOG_ERROR("Cannot open cursor to populate indexes in database");
1104         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
1105     }
1106
1107     while (!cursor->currentKey().isNull()) {
1108         auto& key = cursor->currentKey();
1109         auto* value = cursor->currentValue();
1110         ThreadSafeDataBuffer valueBuffer = value ? value->data() : ThreadSafeDataBuffer();
1111
1112         IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
1113         if (!error.isNull()) {
1114             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
1115             if (sql.prepare() != SQLITE_OK
1116                 || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1117                 || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
1118                 || sql.step() != SQLITE_DONE) {
1119                 LOG_ERROR("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database");
1120                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Index creation failed due to uniqueness constraint failure, but there was an error deleting the Index record from the database") };
1121             }
1122
1123             return error;
1124         }
1125
1126         if (!cursor->advance(1)) {
1127             LOG_ERROR("Error advancing cursor while indexing existing records for new index.");
1128             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error advancing cursor while indexing existing records for new index") };
1129         }
1130     }
1131
1132     auto* objectStore = m_databaseInfo->infoForExistingObjectStore(info.objectStoreIdentifier());
1133     ASSERT(objectStore);
1134     objectStore->addExistingIndex(info);
1135
1136     return { };
1137 }
1138
1139 IDBError SQLiteIDBBackingStore::uncheckedHasIndexRecord(const IDBIndexInfo& info, const IDBKeyData& indexKey, bool& hasRecord)
1140 {
1141     hasRecord = false;
1142
1143     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
1144     if (!indexKeyBuffer) {
1145         LOG_ERROR("Unable to serialize index key to be stored in the database");
1146         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for index record in database") };
1147     }
1148
1149     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT rowid FROM IndexRecords WHERE indexID = ? AND objectStoreID = ? AND key = CAST(? AS TEXT);"));
1150     if (sql.prepare() != SQLITE_OK
1151         || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1152         || sql.bindInt64(2, info.objectStoreIdentifier()) != SQLITE_OK
1153         || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK) {
1154         LOG_ERROR("Error checking for index record in database");
1155         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for index record in database") };
1156     }
1157
1158     int sqlResult = sql.step();
1159     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
1160         return { };
1161
1162     if (sqlResult != SQLITE_ROW) {
1163         // There was an error fetching the record from the database.
1164         LOG_ERROR("Could not check if key exists in index (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1165         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in index") };
1166     }
1167
1168     hasRecord = true;
1169     return { };
1170 }
1171
1172 IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo& info, const IDBKeyData& key, const IndexKey& indexKey)
1173 {
1174     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexKey - (%" PRIu64 ") %s, %s", info.identifier(), key.loggingString().utf8().data(), indexKey.asOneKey().loggingString().utf8().data());
1175
1176     Vector<IDBKeyData> indexKeys;
1177     if (info.multiEntry())
1178         indexKeys = indexKey.multiEntry();
1179     else
1180         indexKeys.append(indexKey.asOneKey());
1181
1182     if (info.unique()) {
1183         bool hasRecord;
1184         IDBError error;
1185         for (auto& indexKey : indexKeys) {
1186             error = uncheckedHasIndexRecord(info, indexKey, hasRecord);
1187             if (!error.isNull())
1188                 return error;
1189             if (hasRecord)
1190                 return IDBError(IDBDatabaseException::ConstraintError);
1191         }
1192     }
1193
1194     for (auto& indexKey : indexKeys) {
1195         auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
1196         if (!error.isNull()) {
1197             LOG_ERROR("Unable to put index record for newly created index");
1198             return error;
1199         }
1200     }
1201
1202     return { };
1203 }
1204
1205 IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
1206 {
1207     LOG(IndexedDB, "SQLiteIDBBackingStore::uncheckedPutIndexRecord - %s, %s", keyValue.loggingString().utf8().data(), indexKey.loggingString().utf8().data());
1208
1209     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
1210     if (!indexKeyBuffer) {
1211         LOG_ERROR("Unable to serialize index key to be stored in the database");
1212         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize index key to be stored in the database") };
1213     }
1214
1215     RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
1216     if (!valueBuffer) {
1217         LOG_ERROR("Unable to serialize the value to be stored in the database");
1218         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize value to be stored in the database") };
1219     }
1220
1221     {
1222         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));"));
1223         if (sql.prepare() != SQLITE_OK
1224             || sql.bindInt64(1, indexID) != SQLITE_OK
1225             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
1226             || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK
1227             || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLITE_OK
1228             || sql.step() != SQLITE_DONE) {
1229             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());
1230             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error putting index record into database") };
1231         }
1232     }
1233
1234     return { };
1235 }
1236
1237
1238 IDBError SQLiteIDBBackingStore::deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier)
1239 {
1240     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteIndex - object store %" PRIu64, objectStoreIdentifier);
1241
1242     ASSERT(m_sqliteDB);
1243     ASSERT(m_sqliteDB->isOpen());
1244
1245     auto* transaction = m_transactions.get(transactionIdentifier);
1246     if (!transaction || !transaction->inProgress()) {
1247         LOG_ERROR("Attempt to delete index without an in-progress transaction");
1248         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index without an in-progress transaction") };
1249     }
1250
1251     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1252         LOG_ERROR("Attempt to delete index during a non-version-change transaction");
1253         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index during a non-version-change transaction") };
1254     }
1255
1256     {
1257         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
1258         if (sql.prepare() != SQLITE_OK
1259             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
1260             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1261             || sql.step() != SQLITE_DONE) {
1262             LOG_ERROR("Could not delete index id %" PRIi64 " from IndexInfo table (%i) - %s", objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1263             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index from database") };
1264         }
1265     }
1266
1267     {
1268         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
1269         if (sql.prepare() != SQLITE_OK
1270             || sql.bindInt64(1, indexIdentifier) != SQLITE_OK
1271             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1272             || sql.step() != SQLITE_DONE) {
1273             LOG_ERROR("Could not delete index records for index id %" PRIi64 " from IndexRecords table (%i) - %s", indexIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1274             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting index records from database") };
1275         }
1276     }
1277
1278     auto* objectStore = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
1279     ASSERT(objectStore);
1280     objectStore->deleteIndex(indexIdentifier);
1281
1282     return { };
1283 }
1284
1285 IDBError SQLiteIDBBackingStore::renameIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
1286 {
1287     LOG(IndexedDB, "SQLiteIDBBackingStore::renameIndex - object store %" PRIu64 ", index %" PRIu64, objectStoreIdentifier, indexIdentifier);
1288
1289     ASSERT(m_sqliteDB);
1290     ASSERT(m_sqliteDB->isOpen());
1291
1292     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
1293     if (!objectStoreInfo)
1294         return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1295
1296     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
1297     if (!indexInfo)
1298         return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1299
1300     auto* transaction = m_transactions.get(transactionIdentifier);
1301     if (!transaction || !transaction->inProgress()) {
1302         LOG_ERROR("Attempt to rename an index without an in-progress transaction");
1303         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an index without an in-progress transaction") };
1304     }
1305
1306     if (transaction->mode() != IDBTransactionMode::Versionchange) {
1307         LOG_ERROR("Attempt to rename an index in a non-version-change transaction");
1308         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename an index in a non-version-change transaction") };
1309     }
1310
1311     {
1312         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE IndexInfo SET name = ? WHERE objectStoreID = ? AND id = ?;"));
1313         if (sql.prepare() != SQLITE_OK
1314             || sql.bindText(1, newName) != SQLITE_OK
1315             || sql.bindInt64(2, objectStoreIdentifier) != SQLITE_OK
1316             || sql.bindInt64(3, indexIdentifier) != SQLITE_OK
1317             || sql.step() != SQLITE_DONE) {
1318             LOG_ERROR("Could not update name for index id (%" PRIi64 ", %" PRIi64 ") in IndexInfo table (%i) - %s", objectStoreIdentifier, indexIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1319             return { IDBDatabaseException::UnknownError, ASCIILiteral("Could not rename index") };
1320         }
1321     }
1322
1323     indexInfo->rename(newName);
1324
1325     return { };
1326 }
1327
1328 IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
1329 {
1330     LOG(IndexedDB, "SQLiteIDBBackingStore::keyExistsInObjectStore - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
1331
1332     ASSERT(m_sqliteDB);
1333     ASSERT(m_sqliteDB->isOpen());
1334
1335     keyExists = false;
1336
1337     auto* transaction = m_transactions.get(transactionIdentifier);
1338     if (!transaction || !transaction->inProgress()) {
1339         LOG_ERROR("Attempt to see if key exists in objectstore without an in-progress transaction");
1340         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to see if key exists in objectstore without an in-progress transaction") };
1341     }
1342
1343     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1344     if (!keyBuffer) {
1345         LOG_ERROR("Unable to serialize IDBKey to check for existence in object store");
1346         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for existence in object store") };
1347     }
1348     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
1349     if (sql.prepare() != SQLITE_OK
1350         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1351         || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
1352         LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1353         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to check for existence of IDBKey in object store") };
1354     }
1355
1356     int sqlResult = sql.step();
1357     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
1358         return { };
1359
1360     if (sqlResult != SQLITE_ROW) {
1361         // There was an error fetching the record from the database.
1362         LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1363         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in object store") };
1364     }
1365
1366     keyExists = true;
1367     return { };
1368 }
1369
1370 IDBError SQLiteIDBBackingStore::deleteUnusedBlobFileRecords(SQLiteIDBTransaction& transaction)
1371 {
1372     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteUnusedBlobFileRecords");
1373
1374     // Gather the set of blob URLs and filenames that are no longer in use.
1375     HashSet<String> removedBlobFilenames;
1376     {
1377         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL NOT IN (SELECT blobURL FROM BlobRecords)"));
1378
1379         if (sql.prepare() != SQLITE_OK) {
1380             LOG_ERROR("Error deleting stored blobs (%i) (Could not gather unused blobURLs) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1381             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1382         }
1383
1384         int result = sql.step();
1385         while (result == SQLITE_ROW) {
1386             removedBlobFilenames.add(sql.getColumnText(0));
1387             result = sql.step();
1388         }
1389
1390         if (result != SQLITE_DONE) {
1391             LOG_ERROR("Error deleting stored blobs (%i) (Could not gather unused blobURLs) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1392             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1393         }
1394     }
1395
1396     // Remove the blob records that are no longer in use.
1397     if (!removedBlobFilenames.isEmpty()) {
1398         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobFiles WHERE blobURL NOT IN (SELECT blobURL FROM BlobRecords)"));
1399
1400         if (sql.prepare() != SQLITE_OK
1401             || sql.step() != SQLITE_DONE) {
1402             LOG_ERROR("Error deleting stored blobs (%i) (Could not delete blobFile records) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1403             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error deleting stored blobs") };
1404         }
1405     }
1406
1407     for (auto& file : removedBlobFilenames)
1408         transaction.addRemovedBlobFile(file);
1409
1410     return { };
1411 }
1412
1413 IDBError SQLiteIDBBackingStore::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const IDBKeyData& keyData)
1414 {
1415     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
1416
1417     ASSERT(m_sqliteDB);
1418     ASSERT(m_sqliteDB->isOpen());
1419     ASSERT(transaction.inProgress());
1420     ASSERT(transaction.mode() != IDBTransactionMode::Readonly);
1421     UNUSED_PARAM(transaction);
1422
1423     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1424     if (!keyBuffer) {
1425         LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
1426         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyData to be removed from the database") };
1427     }
1428
1429     // Get the record ID
1430     int64_t recordID;
1431     {
1432         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT recordID FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1433
1434         if (sql.prepare() != SQLITE_OK
1435             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1436             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
1437             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1438             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1439         }
1440
1441         int result = sql.step();
1442
1443         // If there's no record ID, there's no record to delete.
1444         if (result == SQLITE_DONE)
1445             return { };
1446
1447         if (result != SQLITE_ROW) {
1448             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (unable to fetch record ID) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1449             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1450         }
1451
1452         recordID = sql.getColumnInt64(0);
1453     }
1454
1455     if (recordID < 1) {
1456         LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (record ID is invalid) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1457         return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1458     }
1459
1460     // Delete the blob records for this object store record.
1461     {
1462         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM BlobRecords WHERE objectStoreRow = ?;"));
1463
1464         if (sql.prepare() != SQLITE_OK
1465             || sql.bindInt64(1, recordID) != SQLITE_OK
1466             || sql.step() != SQLITE_DONE) {
1467             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) (Could not delete BlobRecords records) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1468             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1469         }
1470     }
1471
1472     auto error = deleteUnusedBlobFileRecords(transaction);
1473     if (!error.isNull())
1474         return error;
1475
1476     // Delete record from object store
1477     {
1478         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1479
1480         if (sql.prepare() != SQLITE_OK
1481             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1482             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1483             || sql.step() != SQLITE_DONE) {
1484             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1485             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
1486         }
1487     }
1488
1489     // Delete record from indexes store
1490     {
1491         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
1492
1493         if (sql.prepare() != SQLITE_OK
1494             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1495             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1496             || sql.step() != SQLITE_DONE) {
1497             LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1498             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete index entries for object store record") };
1499         }
1500     }
1501
1502     return { };
1503 }
1504
1505 IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange)
1506 {
1507     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRange - range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1508
1509     ASSERT(m_sqliteDB);
1510     ASSERT(m_sqliteDB->isOpen());
1511
1512     auto* transaction = m_transactions.get(transactionIdentifier);
1513     if (!transaction || !transaction->inProgress()) {
1514         LOG_ERROR("Attempt to delete range from database without an in-progress transaction");
1515         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete range from database without an in-progress transaction") };
1516     }
1517     if (transaction->mode() == IDBTransactionMode::Readonly) {
1518         LOG_ERROR("Attempt to delete records from an object store in a read-only transaction");
1519         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete records from an object store in a read-only transaction") };
1520     }
1521
1522     // If the range to delete is exactly one key we can delete it right now.
1523     if (keyRange.isExactlyOneKey()) {
1524         auto error = deleteRecord(*transaction, objectStoreID, keyRange.lowerKey);
1525         if (!error.isNull()) {
1526             LOG_ERROR("Failed to delete record for key '%s'", keyRange.lowerKey.loggingString().utf8().data());
1527             return error;
1528         }
1529
1530         return { };
1531     }
1532
1533     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, 0, keyRange);
1534     if (!cursor) {
1535         LOG_ERROR("Cannot open cursor to delete range of records from the database");
1536         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to delete range of records from the database") };
1537     }
1538
1539     Vector<IDBKeyData> keys;
1540     while (!cursor->didComplete() && !cursor->didError()) {
1541         keys.append(cursor->currentKey());
1542         cursor->advance(1);
1543     }
1544
1545     if (cursor->didError()) {
1546         LOG_ERROR("Cursor failed while accumulating range of records from the database");
1547         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while accumulating range of records from the database") };
1548     }
1549
1550     IDBError error;
1551     for (auto& key : keys) {
1552         error = deleteRecord(*transaction, objectStoreID, key);
1553         if (!error.isNull()) {
1554             LOG_ERROR("deleteRange: Error deleting keys in range");
1555             break;
1556         }
1557     }
1558
1559     transaction->notifyCursorsOfChanges(objectStoreID);
1560
1561     return error;
1562 }
1563
1564 IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1565 {
1566     JSLockHolder locker(vm());
1567
1568     auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
1569     if (jsValue.isUndefinedOrNull())
1570         return { };
1571
1572     IndexKey indexKey;
1573     generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey);
1574
1575     if (indexKey.isNull())
1576         return { };
1577
1578     return uncheckedPutIndexKey(info, key, indexKey);
1579 }
1580
1581 IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
1582 {
1583     JSLockHolder locker(vm());
1584
1585     auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
1586     if (jsValue.isUndefinedOrNull())
1587         return { };
1588
1589     IDBError error;
1590     bool anyRecordsSucceeded = false;
1591     for (auto& index : info.indexMap().values()) {
1592         IndexKey indexKey;
1593         generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
1594
1595         if (indexKey.isNull())
1596             continue;
1597
1598         error = uncheckedPutIndexKey(index, key, indexKey);
1599         if (!error.isNull())
1600             break;
1601
1602         anyRecordsSucceeded = true;
1603     }
1604
1605     if (!error.isNull() && anyRecordsSucceeded) {
1606         RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(key);
1607
1608         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
1609
1610         if (sql.prepare() != SQLITE_OK
1611             || sql.bindInt64(1, info.identifier()) != SQLITE_OK
1612             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1613             || sql.step() != SQLITE_DONE) {
1614             LOG_ERROR("Adding one Index record failed, but failed to remove all others that previously succeeded");
1615             return { IDBDatabaseException::UnknownError, ASCIILiteral("Adding one Index record failed, but failed to remove all others that previously succeeded") };
1616         }
1617     }
1618
1619     return error;
1620 }
1621
1622 IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const IDBValue& value)
1623 {
1624     LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreInfo.identifier());
1625
1626     ASSERT(m_sqliteDB);
1627     ASSERT(m_sqliteDB->isOpen());
1628     ASSERT(value.data().data());
1629     ASSERT(value.blobURLs().size() == value.blobFilePaths().size());
1630
1631     auto* transaction = m_transactions.get(transactionIdentifier);
1632     if (!transaction || !transaction->inProgress()) {
1633         LOG_ERROR("Attempt to store a record in an object store without an in-progress transaction");
1634         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store without an in-progress transaction") };
1635     }
1636     if (transaction->mode() == IDBTransactionMode::Readonly) {
1637         LOG_ERROR("Attempt to store a record in an object store in a read-only transaction");
1638         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store in a read-only transaction") };
1639     }
1640
1641     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
1642     if (!keyBuffer) {
1643         LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
1644         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
1645     }
1646
1647     int64_t recordID = 0;
1648     {
1649         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?, NULL);"));
1650         if (sql.prepare() != SQLITE_OK
1651             || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
1652             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1653             || sql.bindBlob(3, value.data().data()->data(), value.data().data()->size()) != SQLITE_OK
1654             || sql.step() != SQLITE_DONE) {
1655             LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreInfo.identifier(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1656             return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
1657         }
1658
1659         recordID = m_sqliteDB->lastInsertRowID();
1660     }
1661
1662     auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value.data());
1663
1664     if (!error.isNull()) {
1665         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1666         if (sql.prepare() != SQLITE_OK
1667             || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
1668             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1669             || sql.step() != SQLITE_DONE) {
1670             LOG_ERROR("Indexing new object store record failed, but unable to remove the object store record itself");
1671             return { IDBDatabaseException::UnknownError, ASCIILiteral("Indexing new object store record failed, but unable to remove the object store record itself") };
1672         }
1673
1674         return error;
1675     }
1676
1677     const Vector<String>& blobURLs = value.blobURLs();
1678     const Vector<String>& blobFiles = value.blobFilePaths();
1679     for (size_t i = 0; i < blobURLs.size(); ++i) {
1680         auto& url = blobURLs[i];
1681         {
1682             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobRecords VALUES (?, ?);"));
1683             if (sql.prepare() != SQLITE_OK
1684                 || sql.bindInt64(1, recordID) != SQLITE_OK
1685                 || sql.bindText(2, url) != SQLITE_OK
1686                 || sql.step() != SQLITE_DONE) {
1687                 LOG_ERROR("Unable to record Blob record in database");
1688                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob record in database") };
1689             }
1690         }
1691         int64_t potentialFileNameInteger = m_sqliteDB->lastInsertRowID();
1692
1693         // If we already have a file for this blobURL, nothing left to do.
1694         {
1695             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?;"));
1696             if (sql.prepare() != SQLITE_OK
1697                 || sql.bindText(1, url) != SQLITE_OK) {
1698                 LOG_ERROR("Unable to examine Blob filenames in database");
1699                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
1700             }
1701
1702             int result = sql.step();
1703             if (result != SQLITE_ROW && result != SQLITE_DONE) {
1704                 LOG_ERROR("Unable to examine Blob filenames in database");
1705                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
1706             }
1707
1708             if (result == SQLITE_ROW)
1709                 continue;
1710         }
1711
1712         // We don't already have a file for this blobURL, so commit our file as a unique filename
1713         String storedFilename = String::format("%" PRId64 ".blob", potentialFileNameInteger);
1714         {
1715             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobFiles VALUES (?, ?);"));
1716             if (sql.prepare() != SQLITE_OK
1717                 || sql.bindText(1, url) != SQLITE_OK
1718                 || sql.bindText(2, storedFilename) != SQLITE_OK
1719                 || sql.step() != SQLITE_DONE) {
1720                 LOG_ERROR("Unable to record Blob file record in database");
1721                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob file record in database") };
1722             }
1723         }
1724
1725         transaction->addBlobFile(blobFiles[i], storedFilename);
1726     }
1727
1728     transaction->notifyCursorsOfChanges(objectStoreInfo.identifier());
1729
1730     return error;
1731 }
1732
1733 IDBError SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, Vector<String>& blobFilePaths)
1734 {
1735     ASSERT(objectStoreRecord);
1736
1737     HashSet<String> blobURLSet;
1738     {
1739         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT blobURL FROM BlobRecords WHERE objectStoreRow = ?"));
1740         if (sql.prepare() != SQLITE_OK
1741             || sql.bindInt64(1, objectStoreRecord) != SQLITE_OK) {
1742             LOG_ERROR("Could not prepare statement to fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1743             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1744         }
1745
1746         int sqlResult = sql.step();
1747         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1748             // There are no blobURLs in the database for this object store record.
1749             return { };
1750         }
1751
1752         while (sqlResult == SQLITE_ROW) {
1753             blobURLSet.add(sql.getColumnText(0));
1754             sqlResult = sql.step();
1755         }
1756
1757         if (sqlResult != SQLITE_DONE) {
1758             LOG_ERROR("Could not fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1759             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1760         }
1761     }
1762
1763     ASSERT(!blobURLSet.isEmpty());
1764     String databaseDirectory = fullDatabaseDirectory();
1765     for (auto& blobURL : blobURLSet) {
1766         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?"));
1767         if (sql.prepare() != SQLITE_OK
1768             || sql.bindText(1, blobURL) != SQLITE_OK) {
1769             LOG_ERROR("Could not prepare statement to fetch blob filename for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1770             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1771         }
1772
1773         if (sql.step() != SQLITE_ROW) {
1774             LOG_ERROR("Entry for blob filename for blob url %s does not exist (%i) - %s", blobURL.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1775             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
1776         }
1777
1778         blobURLs.append(blobURL);
1779
1780         String fileName = sql.getColumnText(0);
1781         blobFilePaths.append(pathByAppendingComponent(databaseDirectory, fileName));
1782     }
1783
1784     return { };
1785 }
1786
1787 IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, IDBGetResult& resultValue)
1788 {
1789     LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
1790
1791     ASSERT(m_sqliteDB);
1792     ASSERT(m_sqliteDB->isOpen());
1793
1794     auto* transaction = m_transactions.get(transactionIdentifier);
1795     if (!transaction || !transaction->inProgress()) {
1796         LOG_ERROR("Attempt to get a record from database without an in-progress transaction");
1797         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get a record from database without an in-progress transaction") };
1798     }
1799
1800     auto key = keyRange.lowerKey;
1801     if (key.isNull())
1802         key = IDBKeyData::minimum();
1803     RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(key);
1804     if (!lowerBuffer) {
1805         LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
1806         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
1807     }
1808
1809     key = keyRange.upperKey;
1810     if (key.isNull())
1811         key = IDBKeyData::maximum();
1812     RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(key);
1813     if (!upperBuffer) {
1814         LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
1815         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
1816     }
1817
1818     int64_t recordID = 0;
1819     ThreadSafeDataBuffer resultBuffer;
1820     {
1821         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;");
1822         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;");
1823         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;");
1824         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;");
1825
1826         const ASCIILiteral* query = nullptr;
1827
1828         if (keyRange.lowerOpen) {
1829             if (keyRange.upperOpen)
1830                 query = &lowerOpenUpperOpen.get();
1831             else
1832                 query = &lowerOpenUpperClosed.get();
1833         } else {
1834             if (keyRange.upperOpen)
1835                 query = &lowerClosedUpperOpen.get();
1836             else
1837                 query = &lowerClosedUpperClosed.get();
1838         }
1839
1840         ASSERT(query);
1841
1842         SQLiteStatement sql(*m_sqliteDB, *query);
1843         if (sql.prepare() != SQLITE_OK
1844             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1845             || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1846             || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1847             LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1848             return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
1849         }
1850
1851         int sqlResult = sql.step();
1852
1853         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1854             // There was no record for the key in the database.
1855             return { };
1856         }
1857         if (sqlResult != SQLITE_ROW) {
1858             // There was an error fetching the record from the database.
1859             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1860             return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
1861         }
1862
1863         Vector<uint8_t> buffer;
1864         sql.getColumnBlobAsVector(0, buffer);
1865         resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);
1866
1867         recordID = sql.getColumnInt64(1);
1868     }
1869
1870     ASSERT(recordID);
1871     Vector<String> blobURLs, blobFilePaths;
1872     auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
1873     ASSERT(blobURLs.size() == blobFilePaths.size());
1874
1875     if (!error.isNull())
1876         return error;
1877
1878     resultValue = { { resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) } };
1879     return { };
1880 }
1881
1882 IDBError SQLiteIDBBackingStore::getAllRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
1883 {
1884     return getAllRecordsData.indexIdentifier ? getAllIndexRecords(transactionIdentifier, getAllRecordsData, result) : getAllObjectStoreRecords(transactionIdentifier, getAllRecordsData, result);
1885 }
1886
1887 static const ASCIILiteral& queryForGetAllObjectStoreRecords(const IDBGetAllRecordsData& getAllRecordsData)
1888 {
1889     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpenKey("SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1890     static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosedKey("SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1891     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpenKey("SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
1892     static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosedKey("SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
1893     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;");
1894     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;");
1895     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;");
1896     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;");
1897
1898     if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
1899         if (getAllRecordsData.keyRangeData.lowerOpen) {
1900             if (getAllRecordsData.keyRangeData.upperOpen)
1901                 return lowerOpenUpperOpenKey.get();
1902             return lowerOpenUpperClosedKey.get();
1903         }
1904
1905         if (getAllRecordsData.keyRangeData.upperOpen)
1906             return lowerClosedUpperOpenKey.get();
1907         return lowerClosedUpperClosedKey.get();
1908     }
1909
1910     if (getAllRecordsData.keyRangeData.lowerOpen) {
1911         if (getAllRecordsData.keyRangeData.upperOpen)
1912             return lowerOpenUpperOpenValue.get();
1913         return lowerOpenUpperClosedValue.get();
1914     }
1915
1916     if (getAllRecordsData.keyRangeData.upperOpen)
1917         return lowerClosedUpperOpenValue.get();
1918     return lowerClosedUpperClosedValue.get();
1919 }
1920
1921 IDBError SQLiteIDBBackingStore::getAllObjectStoreRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
1922 {
1923     LOG(IndexedDB, "SQLiteIDBBackingStore::getAllObjectStoreRecords");
1924
1925     ASSERT(m_sqliteDB);
1926     ASSERT(m_sqliteDB->isOpen());
1927
1928     auto* transaction = m_transactions.get(transactionIdentifier);
1929     if (!transaction || !transaction->inProgress()) {
1930         LOG_ERROR("Attempt to get records from database without an in-progress transaction");
1931         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get records from database without an in-progress transaction") };
1932     }
1933
1934     auto key = getAllRecordsData.keyRangeData.lowerKey;
1935     if (key.isNull())
1936         key = IDBKeyData::minimum();
1937     auto lowerBuffer = serializeIDBKeyData(key);
1938     if (!lowerBuffer) {
1939         LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
1940         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
1941     }
1942
1943     key = getAllRecordsData.keyRangeData.upperKey;
1944     if (key.isNull())
1945         key = IDBKeyData::maximum();
1946     auto upperBuffer = serializeIDBKeyData(key);
1947     if (!upperBuffer) {
1948         LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
1949         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
1950     }
1951
1952     SQLiteStatement sql(*m_sqliteDB, queryForGetAllObjectStoreRecords(getAllRecordsData));
1953     if (sql.prepare() != SQLITE_OK
1954         || sql.bindInt64(1, getAllRecordsData.objectStoreIdentifier) != SQLITE_OK
1955         || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1956         || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1957         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());
1958         return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
1959     }
1960
1961     result = { getAllRecordsData.getAllType };
1962
1963     uint32_t targetResults;
1964     if (getAllRecordsData.count && getAllRecordsData.count.value())
1965         targetResults = getAllRecordsData.count.value();
1966     else
1967         targetResults = std::numeric_limits<uint32_t>::max();
1968
1969     int sqlResult = sql.step();
1970     uint32_t returnedResults = 0;
1971
1972     while (sqlResult == SQLITE_ROW && returnedResults < targetResults) {
1973         if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values) {
1974             Vector<uint8_t> buffer;
1975             sql.getColumnBlobAsVector(0, buffer);
1976             ThreadSafeDataBuffer resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);
1977
1978             auto recordID = sql.getColumnInt64(1);
1979
1980             ASSERT(recordID);
1981             Vector<String> blobURLs, blobFilePaths;
1982             auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
1983             ASSERT(blobURLs.size() == blobFilePaths.size());
1984
1985             if (!error.isNull())
1986                 return error;
1987
1988             result.addValue({ resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) });
1989         } else {
1990             Vector<uint8_t> keyData;
1991             IDBKeyData key;
1992             sql.getColumnBlobAsVector(0, keyData);
1993
1994             if (!deserializeIDBKeyData(keyData.data(), keyData.size(), key)) {
1995                 LOG_ERROR("Unable to deserialize key data from database while getting all key records");
1996                 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to deserialize key data while getting all key records") };
1997             }
1998
1999             result.addKey(WTFMove(key));
2000         }
2001
2002         ++returnedResults;
2003         sqlResult = sql.step();
2004     }
2005
2006     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE || sqlResult == SQLITE_ROW) {
2007         // Finished getting results
2008         return { };
2009     }
2010
2011     // There was an error fetching records from the database.
2012     LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", getAllRecordsData.objectStoreIdentifier, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2013     return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
2014 }
2015
2016 IDBError SQLiteIDBBackingStore::getAllIndexRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData, IDBGetAllResult& result)
2017 {
2018     LOG(IndexedDB, "SQLiteIDBBackingStore::getAllIndexRecords - %s", getAllRecordsData.keyRangeData.loggingString().utf8().data());
2019
2020     ASSERT(m_sqliteDB);
2021     ASSERT(m_sqliteDB->isOpen());
2022
2023     auto* transaction = m_transactions.get(transactionIdentifier);
2024     if (!transaction || !transaction->inProgress()) {
2025         LOG_ERROR("Attempt to get all index records from database without an in-progress transaction");
2026         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get all index records from database without an in-progress transaction") };
2027     }
2028
2029     auto cursor = transaction->maybeOpenBackingStoreCursor(getAllRecordsData.objectStoreIdentifier, getAllRecordsData.indexIdentifier, getAllRecordsData.keyRangeData);
2030     if (!cursor) {
2031         LOG_ERROR("Cannot open cursor to perform index gets in database");
2032         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to perform index gets in database") };
2033     }
2034
2035     if (cursor->didError()) {
2036         LOG_ERROR("Cursor failed while looking up index records in database");
2037         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index records in database") };
2038     }
2039
2040     result = { getAllRecordsData.getAllType };
2041     uint32_t currentCount = 0;
2042     uint32_t targetCount = getAllRecordsData.count ? getAllRecordsData.count.value() : 0;
2043     if (!targetCount)
2044         targetCount = std::numeric_limits<uint32_t>::max();
2045     while (!cursor->didComplete() && !cursor->didError() && currentCount < targetCount) {
2046         if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
2047             IDBKeyData keyCopy = cursor->currentPrimaryKey();
2048             result.addKey(WTFMove(keyCopy));
2049         } else
2050             result.addValue(cursor->currentValue() ? *cursor->currentValue() : IDBValue());
2051
2052         ++currentCount;
2053         cursor->advance(1);
2054     }
2055
2056     if (cursor->didError()) {
2057         LOG_ERROR("Cursor failed while looking up index records in database");
2058         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index records in database") };
2059     }
2060
2061     return { };
2062 }
2063
2064 IDBError SQLiteIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t indexID, IndexedDB::IndexRecordType type, const IDBKeyRangeData& range, IDBGetResult& getResult)
2065 {
2066     LOG(IndexedDB, "SQLiteIDBBackingStore::getIndexRecord - %s", range.loggingString().utf8().data());
2067
2068     ASSERT(m_sqliteDB);
2069     ASSERT(m_sqliteDB->isOpen());
2070
2071     auto* transaction = m_transactions.get(transactionIdentifier);
2072     if (!transaction || !transaction->inProgress()) {
2073         LOG_ERROR("Attempt to get an index record from database without an in-progress transaction");
2074         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get an index record from database without an in-progress transaction") };
2075     }
2076
2077     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreID, indexID, range);
2078     if (!cursor) {
2079         LOG_ERROR("Cannot open cursor to perform index get in database");
2080         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cannot open cursor to perform index get in database") };
2081     }
2082
2083     if (cursor->didError()) {
2084         LOG_ERROR("Cursor failed while looking up index record in database");
2085         return { IDBDatabaseException::UnknownError, ASCIILiteral("Cursor failed while looking up index record in database") };
2086     }
2087
2088     if (cursor->didComplete())
2089         getResult = { };
2090     else {
2091         if (type == IndexedDB::IndexRecordType::Key)
2092             getResult = { cursor->currentPrimaryKey() };
2093         else
2094             getResult = { cursor->currentValue() ? *cursor->currentValue() : IDBValue(), cursor->currentPrimaryKey() };
2095     }
2096
2097     return { };
2098 }
2099
2100 IDBError SQLiteIDBBackingStore::getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& range, uint64_t& outCount)
2101 {
2102     LOG(IndexedDB, "SQLiteIDBBackingStore::getCount - object store %" PRIu64, objectStoreIdentifier);
2103     ASSERT(m_sqliteDB);
2104     ASSERT(m_sqliteDB->isOpen());
2105
2106     outCount = 0;
2107
2108     auto* transaction = m_transactions.get(transactionIdentifier);
2109     if (!transaction || !transaction->inProgress()) {
2110         LOG_ERROR("Attempt to get count from database without an in-progress transaction");
2111         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get count from database without an in-progress transaction") };
2112     }
2113
2114     auto cursor = transaction->maybeOpenBackingStoreCursor(objectStoreIdentifier, indexIdentifier, range);
2115     if (!cursor) {
2116         LOG_ERROR("Cannot open cursor to populate indexes in database");
2117         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
2118     }
2119
2120     while (cursor->advance(1))
2121         ++outCount;
2122
2123     return { };
2124 }
2125
2126 IDBError SQLiteIDBBackingStore::uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t& outValue)
2127 {
2128     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT currentKey FROM KeyGenerators WHERE objectStoreID = ?;"));
2129     if (sql.prepare() != SQLITE_OK
2130         || sql.bindInt64(1, objectStoreID) != SQLITE_OK) {
2131         LOG_ERROR("Could not retrieve currentKey from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2132         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error getting current key generator value from database") };
2133     }
2134     int result = sql.step();
2135     if (result != SQLITE_ROW) {
2136         LOG_ERROR("Could not retreive key generator value for object store, but it should be there.");
2137         return { IDBDatabaseException::UnknownError, ASCIILiteral("Error finding current key generator value in database") };
2138     }
2139
2140     int64_t value = sql.getColumnInt64(0);
2141     if (value < 0)
2142         return { IDBDatabaseException::ConstraintError, "Current key generator value from database is invalid" };
2143
2144     outValue = value;
2145     return { };
2146 }
2147
2148 IDBError SQLiteIDBBackingStore::uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value)
2149 {
2150     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, ?);"));
2151     if (sql.prepare() != SQLITE_OK
2152         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
2153         || sql.bindInt64(2, value) != SQLITE_OK
2154         || sql.step() != SQLITE_DONE) {
2155         LOG_ERROR("Could not update key generator value (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
2156         return { IDBDatabaseException::ConstraintError, "Error storing new key generator value in database" };
2157     }
2158
2159     return { };
2160 }
2161
2162 IDBError SQLiteIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t& generatedKey)
2163 {
2164     LOG(IndexedDB, "SQLiteIDBBackingStore::generateKeyNumber");
2165
2166     ASSERT(m_sqliteDB);
2167     ASSERT(m_sqliteDB->isOpen());
2168
2169     // The IndexedDatabase spec defines the max key generator value as 2^53;
2170     static uint64_t maxGeneratorValue = 0x20000000000000;
2171
2172     auto* transaction = m_transactions.get(transactionIdentifier);
2173     if (!transaction || !transaction->inProgress()) {
2174         LOG_ERROR("Attempt to generate key in database without an in-progress transaction");
2175         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in database without an in-progress transaction") };
2176     }
2177     if (transaction->mode() == IDBTransactionMode::Readonly) {
2178         LOG_ERROR("Attempt to generate key in a read-only transaction");
2179         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to generate key in a read-only transaction") };
2180     }
2181
2182     uint64_t currentValue;
2183     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
2184     if (!error.isNull())
2185         return error;
2186
2187     if (currentValue + 1 > maxGeneratorValue)
2188         return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
2189
2190     generatedKey = currentValue + 1;
2191     return uncheckedSetKeyGeneratorValue(objectStoreID, generatedKey);
2192 }
2193
2194 IDBError SQLiteIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, uint64_t newKeyNumber)
2195 {
2196     LOG(IndexedDB, "SQLiteIDBBackingStore::revertGeneratedKeyNumber - object store %" PRIu64 ", reverted number %" PRIu64, objectStoreID, newKeyNumber);
2197
2198     ASSERT(m_sqliteDB);
2199     ASSERT(m_sqliteDB->isOpen());
2200
2201     auto* transaction = m_transactions.get(transactionIdentifier);
2202     if (!transaction || !transaction->inProgress()) {
2203         LOG_ERROR("Attempt to revert key generator value in database without an in-progress transaction");
2204         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in database without an in-progress transaction") };
2205     }
2206     if (transaction->mode() == IDBTransactionMode::Readonly) {
2207         LOG_ERROR("Attempt to revert key generator value in a read-only transaction");
2208         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to revert key generator value in a read-only transaction") };
2209     }
2210
2211     ASSERT(newKeyNumber);
2212     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyNumber - 1);
2213 }
2214
2215 IDBError SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, double newKeyNumber)
2216 {
2217     LOG(IndexedDB, "SQLiteIDBBackingStore::maybeUpdateKeyGeneratorNumber");
2218
2219     ASSERT(m_sqliteDB);
2220     ASSERT(m_sqliteDB->isOpen());
2221
2222     auto* transaction = m_transactions.get(transactionIdentifier);
2223     if (!transaction || !transaction->inProgress()) {
2224         LOG_ERROR("Attempt to update key generator value in database without an in-progress transaction");
2225         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in database without an in-progress transaction") };
2226     }
2227     if (transaction->mode() == IDBTransactionMode::Readonly) {
2228         LOG_ERROR("Attempt to update key generator value in a read-only transaction");
2229         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to update key generator value in a read-only transaction") };
2230     }
2231
2232     uint64_t currentValue;
2233     auto error = uncheckedGetKeyGeneratorValue(objectStoreID, currentValue);
2234     if (!error.isNull())
2235         return error;
2236
2237     if (newKeyNumber <= currentValue)
2238         return { };
2239
2240     uint64_t newKeyInteger(newKeyNumber);
2241     if (newKeyInteger <= uint64_t(newKeyNumber))
2242         ++newKeyInteger;
2243
2244     ASSERT(newKeyInteger > uint64_t(newKeyNumber));
2245
2246     return uncheckedSetKeyGeneratorValue(objectStoreID, newKeyInteger - 1);
2247 }
2248
2249 IDBError SQLiteIDBBackingStore::openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info, IDBGetResult& result)
2250 {
2251     ASSERT(m_sqliteDB);
2252     ASSERT(m_sqliteDB->isOpen());
2253
2254     auto* transaction = m_transactions.get(transactionIdentifier);
2255     if (!transaction || !transaction->inProgress()) {
2256         LOG_ERROR("Attempt to open a cursor in database without an in-progress transaction");
2257         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to open a cursor in database without an in-progress transaction") };
2258     }
2259
2260     auto* cursor = transaction->maybeOpenCursor(info);
2261     if (!cursor) {
2262         LOG_ERROR("Unable to open cursor");
2263         return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open cursor") };
2264     }
2265
2266     m_cursors.set(cursor->identifier(), cursor);
2267
2268     cursor->currentData(result);
2269     return { };
2270 }
2271
2272 IDBError SQLiteIDBBackingStore::iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBIterateCursorData& data, IDBGetResult& result)
2273 {
2274     LOG(IndexedDB, "SQLiteIDBBackingStore::iterateCursor");
2275
2276     ASSERT(m_sqliteDB);
2277     ASSERT(m_sqliteDB->isOpen());
2278
2279     auto* cursor = m_cursors.get(cursorIdentifier);
2280     if (!cursor) {
2281         LOG_ERROR("Attempt to iterate a cursor that doesn't exist");
2282         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor that doesn't exist") };
2283     }
2284
2285     ASSERT_UNUSED(transactionIdentifier, cursor->transaction()->transactionIdentifier() == transactionIdentifier);
2286
2287     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
2288         LOG_ERROR("Attempt to iterate a cursor without an in-progress transaction");
2289         return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate a cursor without an in-progress transaction") };
2290     }
2291
2292     auto key = data.keyData;
2293     auto count = data.count;
2294
2295     if (key.isValid()) {
2296         if (!cursor->iterate(key)) {
2297             LOG_ERROR("Attempt to iterate cursor failed");
2298             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to iterate cursor failed") };
2299         }
2300     } else {
2301         if (!count)
2302             count = 1;
2303         if (!cursor->advance(count)) {
2304             LOG_ERROR("Attempt to advance cursor failed");
2305             return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to advance cursor failed") };
2306         }
2307     }
2308
2309     cursor->currentData(result);
2310     return { };
2311 }
2312
2313 IDBObjectStoreInfo* SQLiteIDBBackingStore::infoForObjectStore(uint64_t objectStoreIdentifier)
2314 {
2315     ASSERT(m_databaseInfo);
2316     return m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
2317 }
2318
2319 void SQLiteIDBBackingStore::deleteBackingStore()
2320 {
2321     String dbFilename = fullDatabasePath();
2322
2323     LOG(IndexedDB, "SQLiteIDBBackingStore::deleteBackingStore deleting file '%s' on disk", dbFilename.utf8().data());
2324
2325     Vector<String> blobFiles;
2326     {
2327         bool errored = true;
2328
2329         if (m_sqliteDB) {
2330             SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles;"));
2331             if (sql.prepare() == SQLITE_OK) {
2332                 int result = sql.step();
2333                 while (result == SQLITE_ROW) {
2334                     blobFiles.append(sql.getColumnText(0));
2335                     result = sql.step();
2336                 }
2337
2338                 if (result == SQLITE_DONE)
2339                     errored = false;
2340             }
2341         }
2342
2343         if (errored)
2344             LOG_ERROR("Error getting all blob filenames to be deleted");
2345     }
2346
2347     String databaseDirectory = fullDatabaseDirectory();
2348     for (auto& file : blobFiles) {
2349         String fullPath = pathByAppendingComponent(databaseDirectory, file);
2350         if (!deleteFile(fullPath))
2351             LOG_ERROR("Error deleting blob file %s", fullPath.utf8().data());
2352     }
2353
2354     if (m_sqliteDB) {
2355         m_sqliteDB->close();
2356         m_sqliteDB = nullptr;
2357     }
2358
2359     SQLiteFileSystem::deleteDatabaseFile(dbFilename);
2360     SQLiteFileSystem::deleteEmptyDatabaseDirectory(fullDatabaseDirectory());
2361     SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_absoluteDatabaseDirectory);
2362 }
2363
2364 void SQLiteIDBBackingStore::unregisterCursor(SQLiteIDBCursor& cursor)
2365 {
2366     ASSERT(m_cursors.contains(cursor.identifier()));
2367     m_cursors.remove(cursor.identifier());
2368 }
2369
2370 } // namespace IDBServer
2371 } // namespace WebCore
2372
2373 #endif // ENABLE(INDEXED_DATABASE)