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