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