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