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