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