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