Make IDBKeyData from a struct to a class.
[WebKit-https.git] / Source / WebKit2 / DatabaseProcess / IndexedDB / sqlite / UniqueIDBDatabaseBackingStoreSQLite.cpp
1 /*
2  * Copyright (C) 2013 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 "UniqueIDBDatabaseBackingStoreSQLite.h"
28
29 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
30
31 #include "ArgumentDecoder.h"
32 #include "IDBSerialization.h"
33 #include "Logging.h"
34 #include "SQLiteIDBCursor.h"
35 #include "SQLiteIDBTransaction.h"
36 #include <WebCore/FileSystem.h>
37 #include <WebCore/IDBBindingUtilities.h>
38 #include <WebCore/IDBDatabaseMetadata.h>
39 #include <WebCore/IDBGetResult.h>
40 #include <WebCore/IDBKeyData.h>
41 #include <WebCore/IDBKeyRange.h>
42 #include <WebCore/SQLiteDatabase.h>
43 #include <WebCore/SQLiteStatement.h>
44 #include <WebCore/SQLiteTransaction.h>
45 #include <WebCore/SharedBuffer.h>
46 #include <wtf/NeverDestroyed.h>
47 #include <wtf/RunLoop.h>
48
49 using namespace JSC;
50 using namespace WebCore;
51
52 namespace WebKit {
53
54 // Current version of the metadata schema being used in the metadata database.
55 static const int currentMetadataVersion = 1;
56
57 static const String v1RecordsTableSchema(const String& tableName)
58 {
59     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)");
60 }
61
62 static const String& v1RecordsTableSchema()
63 {
64     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("Records"));
65     return v1RecordsTableSchemaString;
66 }
67
68 static const String& v1RecordsTableSchemaAlternate()
69 {
70     static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("\"Records\""));
71     return v1RecordsTableSchemaString;
72 }
73
74 static const String v2RecordsTableSchema(const String& tableName)
75 {
76     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)");
77 }
78
79 static const String& v2RecordsTableSchema()
80 {
81     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("Records"));
82     return v2RecordsTableSchemaString;
83 }
84
85 static const String& v2RecordsTableSchemaAlternate()
86 {
87     static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("\"Records\""));
88     return v2RecordsTableSchemaString;
89 }
90
91 static int64_t generateDatabaseId()
92 {
93     static int64_t databaseID = 0;
94
95     ASSERT(!RunLoop::isMain());
96     return ++databaseID;
97 }
98
99 UniqueIDBDatabaseBackingStoreSQLite::UniqueIDBDatabaseBackingStoreSQLite(const UniqueIDBDatabaseIdentifier& identifier, const String& databaseDirectory)
100     : m_identifier(identifier)
101     , m_absoluteDatabaseDirectory(databaseDirectory)
102 {
103     // The backing store is meant to be created and used entirely on a background thread.
104     ASSERT(!RunLoop::isMain());
105 }
106
107 UniqueIDBDatabaseBackingStoreSQLite::~UniqueIDBDatabaseBackingStoreSQLite()
108 {
109     ASSERT(!RunLoop::isMain());
110
111     m_transactions.clear();
112     m_sqliteDB = nullptr;
113
114     if (m_vm) {
115         JSLockHolder locker(m_vm.get());
116         m_globalObject.clear();
117         m_vm = nullptr;
118     }
119 }
120
121 static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
122 {
123     String currentSchema;
124     {
125         // Fetch the schema for an existing records table.
126         SQLiteStatement statement(database, "SELECT type, sql FROM sqlite_master WHERE tbl_name='Records'");
127         if (statement.prepare() != SQLITE_OK) {
128             LOG_ERROR("Unable to prepare statement to fetch schema for the Records table.");
129             return false;
130         }
131
132         int sqliteResult = statement.step();
133
134         // If there is no Records table at all, create it and then bail.
135         if (sqliteResult == SQLITE_DONE) {
136             if (!database.executeCommand(v2RecordsTableSchema())) {
137                 LOG_ERROR("Could not create Records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
138                 return false;
139             }
140
141             return true;
142         }
143
144         if (sqliteResult != SQLITE_ROW) {
145             LOG_ERROR("Error executing statement to fetch schema for the Records table.");
146             return false;
147         }
148
149         currentSchema = statement.getColumnText(1);
150     }
151
152     ASSERT(!currentSchema.isEmpty());
153
154     // If the schema in the backing store is the current schema, we're done.
155     if (currentSchema == v2RecordsTableSchema() || currentSchema == v2RecordsTableSchemaAlternate())
156         return true;
157
158     // If the record table is not the current schema then it must be one of the previous schemas.
159     // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
160     if (currentSchema != v1RecordsTableSchema() && currentSchema != v1RecordsTableSchemaAlternate())
161         RELEASE_ASSERT_NOT_REACHED();
162
163     SQLiteTransaction transaction(database);
164     transaction.begin();
165
166     // Create a temporary table with the correct schema and migrate all existing content over.
167     if (!database.executeCommand(v2RecordsTableSchema("_Temp_Records"))) {
168         LOG_ERROR("Could not create temporary records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
169         return false;
170     }
171
172     if (!database.executeCommand("INSERT INTO _Temp_Records SELECT * FROM Records")) {
173         LOG_ERROR("Could not migrate existing Records content (%i) - %s", database.lastError(), database.lastErrorMsg());
174         return false;
175     }
176
177     if (!database.executeCommand("DROP TABLE Records")) {
178         LOG_ERROR("Could not drop existing Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
179         return false;
180     }
181
182     if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records")) {
183         LOG_ERROR("Could not rename temporary Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
184         return false;
185     }
186
187     transaction.commit();
188
189     return true;
190 }
191
192 bool UniqueIDBDatabaseBackingStoreSQLite::ensureValidRecordsTable()
193 {
194     ASSERT(!RunLoop::isMain());
195     ASSERT(m_sqliteDB);
196     ASSERT(m_sqliteDB->isOpen());
197
198     if (!createOrMigrateRecordsTableIfNecessary(*m_sqliteDB))
199         return false;
200
201     // Whether the updated records table already existed or if it was just created and the data migrated over,
202     // make sure the uniqueness index exists.
203     if (!m_sqliteDB->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);")) {
204         LOG_ERROR("Could not create RecordsIndex on Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
205         return false;
206     }
207
208     return true;
209 }
210
211 std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata()
212 {
213     ASSERT(!RunLoop::isMain());
214     ASSERT(m_sqliteDB);
215     ASSERT(m_sqliteDB->isOpen());
216
217     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);")) {
218         LOG_ERROR("Could not create IDBDatabaseInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
219         m_sqliteDB = nullptr;
220         return nullptr;
221     }
222
223     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);")) {
224         LOG_ERROR("Could not create ObjectStoreInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
225         m_sqliteDB = nullptr;
226         return nullptr;
227     }
228
229     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);")) {
230         LOG_ERROR("Could not create IndexInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
231         m_sqliteDB = nullptr;
232         return nullptr;
233     }
234
235     if (!m_sqliteDB->executeCommand("CREATE TABLE IndexRecords (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);")) {
236         LOG_ERROR("Could not create IndexRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
237         m_sqliteDB = nullptr;
238         return nullptr;
239     }
240
241     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);")) {
242         LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
243         m_sqliteDB = nullptr;
244         return nullptr;
245     }
246
247     {
248         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);"));
249         if (sql.prepare() != SQLITE_OK
250             || sql.bindInt(1, currentMetadataVersion) != SQLITE_OK
251             || sql.step() != SQLITE_DONE) {
252             LOG_ERROR("Could not insert database metadata version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
253             m_sqliteDB = nullptr;
254             return nullptr;
255         }
256     }
257     {
258         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseName', ?);"));
259         if (sql.prepare() != SQLITE_OK
260             || sql.bindText(1, m_identifier.databaseName()) != SQLITE_OK
261             || sql.step() != SQLITE_DONE) {
262             LOG_ERROR("Could not insert database name into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
263             m_sqliteDB = nullptr;
264             return nullptr;
265         }
266     }
267     {
268         // Database versions are defined to be a uin64_t in the spec but sqlite3 doesn't support native binding of unsigned integers.
269         // Therefore we'll store the version as a String.
270         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseVersion', ?);"));
271         if (sql.prepare() != SQLITE_OK
272             || sql.bindText(1, String::number(IDBDatabaseMetadata::NoIntVersion)) != SQLITE_OK
273             || sql.step() != SQLITE_DONE) {
274             LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
275             m_sqliteDB = nullptr;
276             return nullptr;
277         }
278     }
279
280     if (!m_sqliteDB->executeCommand(ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MaxObjectStoreID', 1);"))) {
281         LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
282         m_sqliteDB = nullptr;
283         return nullptr;
284     }
285
286     // This initial metadata matches the default values we just put into the metadata database.
287     auto metadata = std::make_unique<IDBDatabaseMetadata>();
288     metadata->name = m_identifier.databaseName();
289     metadata->version = IDBDatabaseMetadata::NoIntVersion;
290     metadata->maxObjectStoreId = 1;
291
292     return metadata;
293 }
294
295 std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata()
296 {
297     ASSERT(!RunLoop::isMain());
298     ASSERT(m_sqliteDB);
299
300     if (!m_sqliteDB->tableExists(ASCIILiteral("IDBDatabaseInfo")))
301         return nullptr;
302
303     auto metadata = std::make_unique<IDBDatabaseMetadata>();
304     {
305         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM IDBDatabaseInfo WHERE key = 'MetadataVersion';"));
306         if (sql.isColumnNull(0))
307             return nullptr;
308         metadata->version = sql.getColumnInt(0);
309     }
310     {
311         SQLiteStatement sql(*m_sqliteDB, "SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseName';");
312         if (sql.isColumnNull(0))
313             return nullptr;
314         metadata->name = sql.getColumnText(0);
315         if (metadata->name != m_identifier.databaseName()) {
316             LOG_ERROR("Database name in the metadata database ('%s') does not match the expected name ('%s')", metadata->name.utf8().data(), m_identifier.databaseName().utf8().data());
317             return nullptr;
318         }
319     }
320     {
321         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseVersion';"));
322         if (sql.isColumnNull(0))
323             return nullptr;
324         String stringVersion = sql.getColumnText(0);
325         bool ok;
326         metadata->version = stringVersion.toUInt64Strict(&ok);
327         if (!ok) {
328             LOG_ERROR("Database version on disk ('%s') does not cleanly convert to an unsigned 64-bit integer version", stringVersion.utf8().data());
329             return nullptr;
330         }
331     }
332
333     {
334         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, keyPath, autoInc, maxIndexID FROM ObjectStoreInfo;"));
335         if (sql.prepare() != SQLITE_OK)
336             return nullptr;
337
338         int result = sql.step();
339         while (result == SQLITE_ROW) {
340             IDBObjectStoreMetadata osMetadata;
341             osMetadata.id = sql.getColumnInt64(0);
342             osMetadata.name = sql.getColumnText(1);
343
344             Vector<char> keyPathBuffer;
345             sql.getColumnBlobAsVector(2, keyPathBuffer);
346
347             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), osMetadata.keyPath)) {
348                 LOG_ERROR("Unable to extract key path metadata from database");
349                 return nullptr;
350             }
351
352             osMetadata.autoIncrement = sql.getColumnInt(3);
353             osMetadata.maxIndexId = sql.getColumnInt64(4);
354
355             metadata->objectStores.set(osMetadata.id, osMetadata);
356             result = sql.step();
357         }
358
359         if (result != SQLITE_DONE) {
360             LOG_ERROR("Error fetching object store metadata from database on disk");
361             return nullptr;
362         }
363     }
364
365     {
366         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
367         if (sql.prepare() != SQLITE_OK)
368             return nullptr;
369
370         int result = sql.step();
371         while (result == SQLITE_ROW) {
372             IDBIndexMetadata indexMetadata;
373
374             indexMetadata.id = sql.getColumnInt64(0);
375             indexMetadata.name = sql.getColumnText(1);
376             int64_t objectStoreID = sql.getColumnInt64(2);
377
378             Vector<char> keyPathBuffer;
379             sql.getColumnBlobAsVector(3, keyPathBuffer);
380
381             if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexMetadata.keyPath)) {
382                 LOG_ERROR("Unable to extract key path metadata from database");
383                 return nullptr;
384             }
385
386             indexMetadata.unique = sql.getColumnInt(4);
387             indexMetadata.multiEntry = sql.getColumnInt(5);
388
389             auto objectStoreMetadataIt = metadata->objectStores.find(objectStoreID);
390             if (objectStoreMetadataIt == metadata->objectStores.end()) {
391                 LOG_ERROR("Found index referring to a non-existant object store");
392                 return nullptr;
393             }
394
395             objectStoreMetadataIt->value.indexes.set(indexMetadata.id, indexMetadata);
396
397             result = sql.step();
398         }
399
400         if (result != SQLITE_DONE) {
401             LOG_ERROR("Error fetching index metadata from database on disk");
402             return nullptr;
403         }
404     }
405
406     return metadata;
407 }
408
409 std::unique_ptr<SQLiteDatabase> UniqueIDBDatabaseBackingStoreSQLite::openSQLiteDatabaseAtPath(const String& path)
410 {
411     ASSERT(!RunLoop::isMain());
412
413     auto sqliteDatabase = std::make_unique<SQLiteDatabase>();
414     if (!sqliteDatabase->open(path)) {
415         LOG_ERROR("Failed to open SQLite database at path '%s'", path.utf8().data());
416         return nullptr;
417     }
418
419     // Since a WorkQueue isn't bound to a specific thread, we have to disable threading checks
420     // even though we never access the database from different threads simultaneously.
421     sqliteDatabase->disableThreadingChecks();
422
423     return sqliteDatabase;
424 }
425
426 std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::getOrEstablishMetadata()
427 {
428     ASSERT(!RunLoop::isMain());
429
430     String dbFilename = UniqueIDBDatabase::calculateAbsoluteDatabaseFilename(m_absoluteDatabaseDirectory);
431
432     m_sqliteDB = openSQLiteDatabaseAtPath(dbFilename);
433     if (!m_sqliteDB)
434         return nullptr;
435
436     m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
437         return idbKeyCollate(aLength, a, bLength, b);
438     });
439
440     if (!ensureValidRecordsTable()) {
441         LOG_ERROR("Error creating or migrating Records table in database");
442         m_sqliteDB = nullptr;
443         return nullptr;
444     }
445
446     std::unique_ptr<IDBDatabaseMetadata> metadata = extractExistingMetadata();
447     if (!metadata)
448         metadata = createAndPopulateInitialMetadata();
449
450     if (!metadata)
451         LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data());
452
453     // The database id is a runtime concept and doesn't need to be stored in the metadata database.
454     metadata->id = generateDatabaseId();
455
456     return metadata;
457 }
458
459 bool UniqueIDBDatabaseBackingStoreSQLite::establishTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>&, IndexedDB::TransactionMode mode)
460 {
461     ASSERT(!RunLoop::isMain());
462
463     if (!m_transactions.add(transactionIdentifier, std::make_unique<SQLiteIDBTransaction>(*this, transactionIdentifier, mode)).isNewEntry) {
464         LOG_ERROR("Attempt to establish transaction identifier that already exists");
465         return false;
466     }
467
468     return true;
469 }
470
471 bool UniqueIDBDatabaseBackingStoreSQLite::beginTransaction(const IDBIdentifier& transactionIdentifier)
472 {
473     ASSERT(!RunLoop::isMain());
474
475     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
476     if (!transaction) {
477         LOG_ERROR("Attempt to begin a transaction that hasn't been established");
478         return false;
479     }
480
481     return transaction->begin(*m_sqliteDB);
482 }
483
484 bool UniqueIDBDatabaseBackingStoreSQLite::commitTransaction(const IDBIdentifier& transactionIdentifier)
485 {
486     ASSERT(!RunLoop::isMain());
487
488     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
489     if (!transaction) {
490         LOG_ERROR("Attempt to commit a transaction that hasn't been established");
491         return false;
492     }
493
494     return transaction->commit();
495 }
496
497 bool UniqueIDBDatabaseBackingStoreSQLite::resetTransaction(const IDBIdentifier& transactionIdentifier)
498 {
499     ASSERT(!RunLoop::isMain());
500
501     std::unique_ptr<SQLiteIDBTransaction> transaction = m_transactions.take(transactionIdentifier);
502     if (!transaction) {
503         LOG_ERROR("Attempt to reset a transaction that hasn't been established");
504         return false;
505     }
506
507     return transaction->reset();
508 }
509
510 bool UniqueIDBDatabaseBackingStoreSQLite::rollbackTransaction(const IDBIdentifier& transactionIdentifier)
511 {
512     ASSERT(!RunLoop::isMain());
513
514     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
515     if (!transaction) {
516         LOG_ERROR("Attempt to rollback a transaction that hasn't been established");
517         return false;
518     }
519
520     if (!transaction->inProgress()) {
521         LOG_ERROR("Attempt to rollback a transaction that hasn't begun");
522         return false;
523     }
524
525     return transaction->rollback();
526 }
527
528 bool UniqueIDBDatabaseBackingStoreSQLite::changeDatabaseVersion(const IDBIdentifier& transactionIdentifier, uint64_t newVersion)
529 {
530     ASSERT(!RunLoop::isMain());
531     ASSERT(m_sqliteDB);
532     ASSERT(m_sqliteDB->isOpen());
533
534     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
535     if (!transaction || !transaction->inProgress()) {
536         LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
537         return false;
538     }
539     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
540         LOG_ERROR("Attempt to change database version during a non version-change transaction");
541         return false;
542     }
543
544     {
545         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE IDBDatabaseInfo SET value = ? where key = 'DatabaseVersion';"));
546         if (sql.prepare() != SQLITE_OK
547             || sql.bindText(1, String::number(newVersion)) != SQLITE_OK
548             || sql.step() != SQLITE_DONE) {
549             LOG_ERROR("Could not update database version in IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
550             return false;
551         }
552     }
553
554     return true;
555 }
556
557 bool UniqueIDBDatabaseBackingStoreSQLite::createObjectStore(const IDBIdentifier& transactionIdentifier, const IDBObjectStoreMetadata& metadata)
558 {
559     ASSERT(!RunLoop::isMain());
560     ASSERT(m_sqliteDB);
561     ASSERT(m_sqliteDB->isOpen());
562
563     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
564     if (!transaction || !transaction->inProgress()) {
565         LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
566         return false;
567     }
568     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
569         LOG_ERROR("Attempt to change database version during a non version-change transaction");
570         return false;
571     }
572
573     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(metadata.keyPath);
574     if (!keyPathBlob) {
575         LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
576         return false;
577     }
578
579     {
580         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
581         if (sql.prepare() != SQLITE_OK
582             || sql.bindInt64(1, metadata.id) != SQLITE_OK
583             || sql.bindText(2, metadata.name) != SQLITE_OK
584             || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
585             || sql.bindInt(4, metadata.autoIncrement) != SQLITE_OK
586             || sql.bindInt64(5, metadata.maxIndexId) != SQLITE_OK
587             || sql.step() != SQLITE_DONE) {
588             LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
589             return false;
590         }
591     }
592
593     {
594         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, 0);"));
595         if (sql.prepare() != SQLITE_OK
596             || sql.bindInt64(1, metadata.id) != SQLITE_OK
597             || sql.step() != SQLITE_DONE) {
598             LOG_ERROR("Could not seed initial key generator value for ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
599             return false;
600         }
601     }
602
603     return true;
604 }
605
606 bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID)
607 {
608     ASSERT(!RunLoop::isMain());
609     ASSERT(m_sqliteDB);
610     ASSERT(m_sqliteDB->isOpen());
611
612     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
613     if (!transaction || !transaction->inProgress()) {
614         LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
615         return false;
616     }
617     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
618         LOG_ERROR("Attempt to change database version during a non version-change transaction");
619         return false;
620     }
621
622     // Delete the ObjectStore record
623     {
624         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
625         if (sql.prepare() != SQLITE_OK
626             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
627             || sql.step() != SQLITE_DONE) {
628             LOG_ERROR("Could not delete object store id %" PRIi64 " from ObjectStoreInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
629             return false;
630         }
631     }
632
633     // Delete the ObjectStore's key generator record if there is one.
634     {
635         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM KeyGenerators WHERE objectStoreID = ?;"));
636         if (sql.prepare() != SQLITE_OK
637             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
638             || sql.step() != SQLITE_DONE) {
639             LOG_ERROR("Could not delete object store from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
640             return false;
641         }
642     }
643
644     // Delete all associated records
645     {
646         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
647         if (sql.prepare() != SQLITE_OK
648             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
649             || sql.step() != SQLITE_DONE) {
650             LOG_ERROR("Could not delete records for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
651             return false;
652         }
653     }
654
655     // Delete all associated Indexes
656     {
657         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
658         if (sql.prepare() != SQLITE_OK
659             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
660             || sql.step() != SQLITE_DONE) {
661             LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
662             return false;
663         }
664     }
665
666     // Delete all associated Index records
667     {
668         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
669         if (sql.prepare() != SQLITE_OK
670             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
671             || sql.step() != SQLITE_DONE) {
672             LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
673             return false;
674         }
675     }
676
677     return true;
678 }
679
680 bool UniqueIDBDatabaseBackingStoreSQLite::clearObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID)
681 {
682     ASSERT(!RunLoop::isMain());
683     ASSERT(m_sqliteDB);
684     ASSERT(m_sqliteDB->isOpen());
685
686     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
687     if (!transaction || !transaction->inProgress()) {
688         LOG_ERROR("Attempt to change database version with an establish, in-progress transaction");
689         return false;
690     }
691     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
692         LOG_ERROR("Attempt to change database version during a read-only transaction");
693         return false;
694     }
695
696     {
697         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
698         if (sql.prepare() != SQLITE_OK
699             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
700             || sql.step() != SQLITE_DONE) {
701             LOG_ERROR("Could not delete records from object store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
702             return false;
703         }
704     }
705
706     {
707         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
708         if (sql.prepare() != SQLITE_OK
709             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
710             || sql.step() != SQLITE_DONE) {
711             LOG_ERROR("Could not delete records from index record store id %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
712             return false;
713         }
714     }
715
716     return true;
717 }
718
719 bool UniqueIDBDatabaseBackingStoreSQLite::createIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBIndexMetadata& metadata)
720 {
721     ASSERT(!RunLoop::isMain());
722     ASSERT(m_sqliteDB);
723     ASSERT(m_sqliteDB->isOpen());
724
725     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
726     if (!transaction || !transaction->inProgress()) {
727         LOG_ERROR("Attempt to create index without an established, in-progress transaction");
728         return false;
729     }
730     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
731         LOG_ERROR("Attempt to create index during a non-version-change transaction");
732         return false;
733     }
734
735     RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(metadata.keyPath);
736     if (!keyPathBlob) {
737         LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
738         return false;
739     }
740
741     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
742     if (sql.prepare() != SQLITE_OK
743         || sql.bindInt64(1, metadata.id) != SQLITE_OK
744         || sql.bindText(2, metadata.name) != SQLITE_OK
745         || sql.bindInt64(3, objectStoreID) != SQLITE_OK
746         || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
747         || sql.bindInt(5, metadata.unique) != SQLITE_OK
748         || sql.bindInt(6, metadata.multiEntry) != SQLITE_OK
749         || sql.step() != SQLITE_DONE) {
750         LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
751         return false;
752     }
753
754     // Write index records for any records that already exist in this object store.
755     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, IDBIndexMetadata::InvalidId, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyAndValue, IDBDatabaseBackend::NormalTask, IDBKeyRangeData());
756
757     if (!cursor) {
758         LOG_ERROR("Cannot open cursor to populate indexes in database");
759         return false;
760     }
761
762     m_cursors.set(cursor->identifier(), cursor);
763
764     std::unique_ptr<JSLockHolder> locker;
765     while (!cursor->currentKey().isNull()) {
766         const IDBKeyData& key = cursor->currentKey();
767         const Vector<uint8_t>& valueBuffer = cursor->currentValueBuffer();
768
769         if (!m_globalObject) {
770             ASSERT(!m_vm);
771             m_vm = VM::create();
772             locker = std::make_unique<JSLockHolder>(m_vm.get());
773             m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
774         }
775
776         if (!locker)
777             locker = std::make_unique<JSLockHolder>(m_vm.get());
778
779         Deprecated::ScriptValue value = deserializeIDBValueBuffer(m_globalObject->globalExec(), valueBuffer, true);
780         Vector<IDBKeyData> indexKeys;
781         generateIndexKeysForValue(m_globalObject->globalExec(), metadata, value, indexKeys);
782
783         for (auto& indexKey : indexKeys) {
784             if (!uncheckedPutIndexRecord(objectStoreID, metadata.id, key, indexKey)) {
785                 LOG_ERROR("Unable to put index record for newly created index");
786                 return false;
787             }
788         }
789
790         if (!cursor->advance(1)) {
791             LOG_ERROR("Error advancing cursor while indexing existing records for new index.");
792             return false;
793         }
794     }
795
796     transaction->closeCursor(*cursor);
797
798     return true;
799 }
800
801 bool UniqueIDBDatabaseBackingStoreSQLite::deleteIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID)
802 {
803     ASSERT(!RunLoop::isMain());
804     ASSERT(m_sqliteDB);
805     ASSERT(m_sqliteDB->isOpen());
806
807     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
808     if (!transaction || !transaction->inProgress()) {
809         LOG_ERROR("Attempt to delete index without an established, in-progress transaction");
810         return false;
811     }
812     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
813         LOG_ERROR("Attempt to delete index during a non-version-change transaction");
814         return false;
815     }
816
817     {
818         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
819         if (sql.prepare() != SQLITE_OK
820             || sql.bindInt64(1, indexID) != SQLITE_OK
821             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
822             || sql.step() != SQLITE_DONE) {
823             LOG_ERROR("Could not delete index id %" PRIi64 " from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
824             return false;
825         }
826     }
827
828     {
829         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
830         if (sql.prepare() != SQLITE_OK
831             || sql.bindInt64(1, indexID) != SQLITE_OK
832             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
833             || sql.step() != SQLITE_DONE) {
834             LOG_ERROR("Could not delete index records for index id %" PRIi64 " from IndexRecords table (%i) - %s", indexID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
835             return false;
836         }
837     }
838
839     return true;
840 }
841
842 bool UniqueIDBDatabaseBackingStoreSQLite::generateKeyNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t& generatedKey)
843 {
844     ASSERT(!RunLoop::isMain());
845     ASSERT(m_sqliteDB);
846     ASSERT(m_sqliteDB->isOpen());
847
848     // The IndexedDatabase spec defines the max key generator value as 2^53;
849     static const int64_t maxGeneratorValue = 9007199254740992LL;
850
851     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
852     if (!transaction || !transaction->inProgress()) {
853         LOG_ERROR("Attempt to generate key in database without an established, in-progress transaction");
854         return false;
855     }
856     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
857         LOG_ERROR("Attempt to generate key in database during read-only transaction");
858         return false;
859     }
860
861     int64_t currentValue;
862     {
863         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT currentKey FROM KeyGenerators WHERE objectStoreID = ?;"));
864         if (sql.prepare() != SQLITE_OK
865             || sql.bindInt64(1, objectStoreID) != SQLITE_OK) {
866             LOG_ERROR("Could not delete index id %" PRIi64 " from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
867             return false;
868         }
869         int result = sql.step();
870         if (result != SQLITE_ROW) {
871             LOG_ERROR("Could not retreive key generator value for object store, but it should be there.");
872             return false;
873         }
874
875         currentValue = sql.getColumnInt64(0);
876     }
877
878     if (currentValue < 0 || currentValue > maxGeneratorValue)
879         return false;
880
881     generatedKey = currentValue + 1;
882     return true;
883 }
884
885 bool UniqueIDBDatabaseBackingStoreSQLite::updateKeyGeneratorNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t keyNumber, bool)
886 {
887     ASSERT(!RunLoop::isMain());
888     ASSERT(m_sqliteDB);
889     ASSERT(m_sqliteDB->isOpen());
890
891     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
892     if (!transaction || !transaction->inProgress()) {
893         LOG_ERROR("Attempt to update key generator in database without an established, in-progress transaction");
894         return false;
895     }
896     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
897         LOG_ERROR("Attempt to update key generator in database during read-only transaction");
898         return false;
899     }
900
901     {
902         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, ?);"));
903         if (sql.prepare() != SQLITE_OK
904             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
905             || sql.bindInt64(2, keyNumber) != SQLITE_OK
906             || sql.step() != SQLITE_DONE) {
907             LOG_ERROR("Could not update key generator value (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
908             return false;
909         }
910     }
911
912     return true;
913 }
914
915 bool UniqueIDBDatabaseBackingStoreSQLite::keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
916 {
917     ASSERT(!RunLoop::isMain());
918     ASSERT(m_sqliteDB);
919     ASSERT(m_sqliteDB->isOpen());
920
921     keyExists = false;
922
923     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
924     if (!transaction || !transaction->inProgress()) {
925         LOG_ERROR("Attempt to see if key exists in objectstore without established, in-progress transaction");
926         return false;
927     }
928
929     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
930     if (!keyBuffer) {
931         LOG_ERROR("Unable to serialize IDBKey to check for existence");
932         return false;
933     }
934
935     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
936     if (sql.prepare() != SQLITE_OK
937         || sql.bindInt64(1, objectStoreID) != SQLITE_OK
938         || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
939         LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
940         return false;
941     }
942
943     int sqlResult = sql.step();
944     if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
945         keyExists = false;
946         return true;
947     }
948
949     if (sqlResult != SQLITE_ROW) {
950         // There was an error fetching the record from the database.
951         LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
952         return false;
953     }
954
955     keyExists = true;
956     return true;
957 }
958
959 bool UniqueIDBDatabaseBackingStoreSQLite::putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyData& keyData, const uint8_t* valueBuffer, size_t valueSize)
960 {
961     ASSERT(!RunLoop::isMain());
962     ASSERT(m_sqliteDB);
963     ASSERT(m_sqliteDB->isOpen());
964
965     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
966     if (!transaction || !transaction->inProgress()) {
967         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
968         return false;
969     }
970     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
971         LOG_ERROR("Attempt to put a record into database during read-only transaction");
972         return false;
973     }
974
975     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
976     if (!keyBuffer) {
977         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
978         return false;
979     }
980     {
981         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
982         if (sql.prepare() != SQLITE_OK
983             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
984             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
985             || sql.bindBlob(3, valueBuffer, valueSize) != SQLITE_OK
986             || sql.step() != SQLITE_DONE) {
987             LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
988             return false;
989         }
990     }
991
992     return true;
993 }
994
995 bool UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey)
996 {
997     ASSERT(!RunLoop::isMain());
998     ASSERT(m_sqliteDB);
999     ASSERT(m_sqliteDB->isOpen());
1000
1001     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1002     if (!transaction || !transaction->inProgress()) {
1003         LOG_ERROR("Attempt to put index record into database without an established, in-progress transaction");
1004         return false;
1005     }
1006     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1007         LOG_ERROR("Attempt to put index record into database during read-only transaction");
1008         return false;
1009     }
1010
1011     return uncheckedPutIndexRecord(objectStoreID, indexID, keyValue, indexKey);
1012 }
1013
1014 bool UniqueIDBDatabaseBackingStoreSQLite::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
1015 {
1016     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
1017     if (!indexKeyBuffer) {
1018         LOG_ERROR("Unable to serialize index key to be stored in the database");
1019         return false;
1020     }
1021
1022     RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
1023     if (!valueBuffer) {
1024         LOG_ERROR("Unable to serialize the value to be stored in the database");
1025         return false;
1026     }
1027     {
1028         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));"));
1029         if (sql.prepare() != SQLITE_OK
1030             || sql.bindInt64(1, indexID) != SQLITE_OK
1031             || sql.bindInt64(2, objectStoreID) != SQLITE_OK
1032             || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK
1033             || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLITE_OK
1034             || sql.step() != SQLITE_DONE) {
1035             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());
1036             return false;
1037         }
1038     }
1039
1040     return true;
1041 }
1042
1043 bool UniqueIDBDatabaseBackingStoreSQLite::getIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRangeData, IndexedDB::CursorType cursorType, IDBGetResult& result)
1044 {
1045     ASSERT(!RunLoop::isMain());
1046     ASSERT(m_sqliteDB);
1047     ASSERT(m_sqliteDB->isOpen());
1048
1049     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1050     if (!transaction || !transaction->inProgress()) {
1051         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
1052         return false;
1053     }
1054
1055     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, IndexedDB::CursorDirection::Next, cursorType, IDBDatabaseBackend::NormalTask, keyRangeData);
1056
1057     if (!cursor) {
1058         LOG_ERROR("Cannot open cursor to perform index get in database");
1059         return false;
1060     }
1061
1062     // Even though we're only using this cursor locally, add it to our cursor set.
1063     m_cursors.set(cursor->identifier(), cursor);
1064
1065     if (cursorType == IndexedDB::CursorType::KeyOnly)
1066         result = IDBGetResult(cursor->currentPrimaryKey());
1067     else {
1068         result = IDBGetResult(SharedBuffer::create(cursor->currentValueBuffer().data(), cursor->currentValueBuffer().size()));
1069         result.keyData = cursor->currentPrimaryKey();
1070     }
1071
1072     // Closing the cursor will destroy the cursor object and remove it from our cursor set.
1073     transaction->closeCursor(*cursor);
1074
1075     return true;
1076 }
1077
1078 bool UniqueIDBDatabaseBackingStoreSQLite::deleteRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyData& keyData)
1079 {
1080     ASSERT(!RunLoop::isMain());
1081     ASSERT(m_sqliteDB);
1082     ASSERT(m_sqliteDB->isOpen());
1083
1084     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1085     if (!transaction || !transaction->inProgress()) {
1086         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
1087         return false;
1088     }
1089
1090     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1091         LOG_ERROR("Attempt to delete range from a read-only transaction");
1092         return false;
1093     }
1094
1095     return deleteRecord(*transaction, objectStoreID, keyData);
1096 }
1097
1098 bool UniqueIDBDatabaseBackingStoreSQLite::deleteRange(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyRangeData& keyRangeData)
1099 {
1100     ASSERT(!RunLoop::isMain());
1101     ASSERT(m_sqliteDB);
1102     ASSERT(m_sqliteDB->isOpen());
1103
1104     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1105     if (!transaction || !transaction->inProgress()) {
1106         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
1107         return false;
1108     }
1109
1110     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
1111         LOG_ERROR("Attempt to delete range from a read-only transaction");
1112         return false;
1113     }
1114
1115     // If the range to delete is exactly one key we can delete it right now.
1116     if (keyRangeData.isExactlyOneKey()) {
1117         if (!deleteRecord(*transaction, objectStoreID, keyRangeData.lowerKey)) {
1118             LOG_ERROR("Failed to delete record for key '%s'", keyRangeData.lowerKey.loggingString().utf8().data());
1119             return false;
1120         }
1121         return true;
1122     }
1123
1124     // Otherwise the range might span multiple keys so we collect them with a cursor.
1125     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, IDBIndexMetadata::InvalidId, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyAndValue, IDBDatabaseBackend::NormalTask, keyRangeData);
1126
1127     if (!cursor) {
1128         LOG_ERROR("Cannot open cursor to perform index get in database");
1129         return false;
1130     }
1131
1132     m_cursors.set(cursor->identifier(), cursor);
1133
1134     Vector<IDBKeyData> keys;
1135     do
1136         keys.append(cursor->currentKey());
1137     while (cursor->advance(1));
1138
1139     bool cursorDidError = cursor->didError();
1140
1141     // closeCursor() will remove the cursor from m_cursors and delete the cursor object
1142     transaction->closeCursor(*cursor);
1143
1144     if (cursorDidError) {
1145         LOG_ERROR("Unable to iterate over object store to deleteRange in database");
1146         return false;
1147     }
1148
1149     for (auto& key : keys) {
1150         if (!deleteRecord(*transaction, objectStoreID, key)) {
1151             LOG_ERROR("Failed to delete record for key '%s'", key.loggingString().utf8().data());
1152             return false;
1153         }
1154     }
1155
1156     return true;
1157 }
1158
1159 bool UniqueIDBDatabaseBackingStoreSQLite::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const WebCore::IDBKeyData& key)
1160 {
1161     ASSERT(!RunLoop::isMain());
1162     ASSERT(m_sqliteDB);
1163     ASSERT(m_sqliteDB->isOpen());
1164
1165     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(key);
1166     if (!keyBuffer) {
1167         LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
1168         return false;
1169     }
1170
1171     // Delete record from object store
1172     {
1173         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1174
1175         if (sql.prepare() != SQLITE_OK
1176             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1177             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1178             || sql.step() != SQLITE_DONE) {
1179             LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1180             return false;
1181         }
1182     }
1183
1184     // Delete record from indexes store
1185     {
1186         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
1187
1188         if (sql.prepare() != SQLITE_OK
1189             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1190             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
1191             || sql.step() != SQLITE_DONE) {
1192             LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1193             return false;
1194         }
1195     }
1196
1197     return true;
1198 }
1199
1200 bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKey& key, RefPtr<SharedBuffer>& result)
1201 {
1202     ASSERT(!RunLoop::isMain());
1203     ASSERT(m_sqliteDB);
1204     ASSERT(m_sqliteDB->isOpen());
1205
1206     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1207     if (!transaction || !transaction->inProgress()) {
1208         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
1209         return false;
1210     }
1211
1212     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(IDBKeyData(&key));
1213     if (!keyBuffer) {
1214         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
1215         return false;
1216     }
1217
1218     {
1219         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
1220         if (sql.prepare() != SQLITE_OK
1221             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1222             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
1223             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1224             return false;
1225         }
1226
1227         int sqlResult = sql.step();
1228         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1229             // There was no record for the key in the database.
1230             return true;
1231         }
1232         if (sqlResult != SQLITE_ROW) {
1233             // There was an error fetching the record from the database.
1234             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1235             return false;
1236         }
1237
1238         Vector<char> buffer;
1239         sql.getColumnBlobAsVector(0, buffer);
1240         result = SharedBuffer::create(static_cast<const char*>(buffer.data()), buffer.size());
1241     }
1242
1243     return true;
1244 }
1245
1246 bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyRange& keyRange, RefPtr<SharedBuffer>& result, RefPtr<IDBKey>& resultKey)
1247 {
1248     ASSERT(!RunLoop::isMain());
1249     ASSERT(m_sqliteDB);
1250     ASSERT(m_sqliteDB->isOpen());
1251
1252     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1253     if (!transaction || !transaction->inProgress()) {
1254         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
1255         return false;
1256     }
1257
1258     RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(IDBKeyData(keyRange.lower().get()));
1259     if (!lowerBuffer) {
1260         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
1261         return false;
1262     }
1263
1264     RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(IDBKeyData(keyRange.upper().get()));
1265     if (!upperBuffer) {
1266         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
1267         return false;
1268     }
1269
1270     {
1271         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;"));
1272         if (sql.prepare() != SQLITE_OK
1273             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
1274             || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
1275             || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
1276             LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1277             return false;
1278         }
1279
1280         int sqlResult = sql.step();
1281
1282         if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
1283             // There was no record for the key in the database.
1284             return true;
1285         }
1286         if (sqlResult != SQLITE_ROW) {
1287             // There was an error fetching the record from the database.
1288             LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1289             return false;
1290         }
1291
1292         Vector<char> buffer;
1293         sql.getColumnBlobAsVector(0, buffer);
1294         result = SharedBuffer::create(static_cast<const char*>(buffer.data()), buffer.size());
1295     }
1296
1297     return true;
1298 }
1299
1300 bool UniqueIDBDatabaseBackingStoreSQLite::count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRangeData, int64_t& count)
1301 {
1302     ASSERT(!RunLoop::isMain());
1303     ASSERT(m_sqliteDB);
1304     ASSERT(m_sqliteDB->isOpen());
1305
1306     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1307     if (!transaction || !transaction->inProgress()) {
1308         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
1309         return false;
1310     }
1311
1312     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyOnly, IDBDatabaseBackend::NormalTask, keyRangeData);
1313
1314     if (!cursor) {
1315         LOG_ERROR("Cannot open cursor to get count in database");
1316         return false;
1317     }
1318
1319     m_cursors.set(cursor->identifier(), cursor);
1320
1321     count = 0;
1322     while (cursor->advance(1))
1323         ++count;
1324
1325     transaction->closeCursor(*cursor);
1326
1327     return true;
1328 }
1329
1330 bool UniqueIDBDatabaseBackingStoreSQLite::openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, IndexedDB::CursorDirection cursorDirection, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, const IDBKeyRangeData& keyRange, int64_t& cursorID, IDBKeyData& key, IDBKeyData& primaryKey, Vector<uint8_t>& valueBuffer)
1331 {
1332     ASSERT(!RunLoop::isMain());
1333     ASSERT(m_sqliteDB);
1334     ASSERT(m_sqliteDB->isOpen());
1335
1336     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1337     if (!transaction || !transaction->inProgress()) {
1338         LOG_ERROR("Attempt to open a cursor in database without an established, in-progress transaction");
1339         return false;
1340     }
1341
1342     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange);
1343     if (!cursor)
1344         return false;
1345
1346     m_cursors.set(cursor->identifier(), cursor);
1347     cursorID = cursor->identifier().id();
1348     key = cursor->currentKey();
1349     primaryKey = cursor->currentPrimaryKey();
1350     valueBuffer = cursor->currentValueBuffer();
1351
1352     return true;
1353 }
1354
1355 bool UniqueIDBDatabaseBackingStoreSQLite::advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, IDBKeyData& key, IDBKeyData& primaryKey, Vector<uint8_t>& valueBuffer)
1356 {
1357     ASSERT(!RunLoop::isMain());
1358     ASSERT(m_sqliteDB);
1359     ASSERT(m_sqliteDB->isOpen());
1360
1361     SQLiteIDBCursor* cursor = m_cursors.get(cursorIdentifier);
1362     if (!cursor) {
1363         LOG_ERROR("Attempt to advance a cursor that doesn't exist");
1364         return false;
1365     }
1366     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
1367         LOG_ERROR("Attempt to advance a cursor without an established, in-progress transaction");
1368         return false;
1369     }
1370
1371     if (!cursor->advance(count)) {
1372         LOG_ERROR("Attempt to advance cursor %" PRIi64 " steps failed", count);
1373         return false;
1374     }
1375
1376     key = cursor->currentKey();
1377     primaryKey = cursor->currentPrimaryKey();
1378     valueBuffer = cursor->currentValueBuffer();
1379
1380     return true;
1381 }
1382
1383 bool UniqueIDBDatabaseBackingStoreSQLite::iterateCursor(const IDBIdentifier& cursorIdentifier, const IDBKeyData& targetKey, IDBKeyData& key, IDBKeyData& primaryKey, Vector<uint8_t>& valueBuffer)
1384 {
1385     ASSERT(!RunLoop::isMain());
1386     ASSERT(m_sqliteDB);
1387     ASSERT(m_sqliteDB->isOpen());
1388
1389     SQLiteIDBCursor* cursor = m_cursors.get(cursorIdentifier);
1390     if (!cursor) {
1391         LOG_ERROR("Attempt to iterate a cursor that doesn't exist");
1392         return false;
1393     }
1394     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
1395         LOG_ERROR("Attempt to iterate a cursor without an established, in-progress transaction");
1396         return false;
1397     }
1398
1399     if (!cursor->iterate(targetKey)) {
1400         LOG_ERROR("Attempt to iterate cursor failed");
1401         return false;
1402     }
1403
1404     key = cursor->currentKey();
1405     primaryKey = cursor->currentPrimaryKey();
1406     valueBuffer = cursor->currentValueBuffer();
1407
1408     return true;
1409 }
1410
1411 void UniqueIDBDatabaseBackingStoreSQLite::notifyCursorsOfChanges(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID)
1412 {
1413     ASSERT(!RunLoop::isMain());
1414     ASSERT(m_sqliteDB);
1415     ASSERT(m_sqliteDB->isOpen());
1416
1417     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1418     if (!transaction || !transaction->inProgress()) {
1419         LOG_ERROR("Attempt to notify cursors of changes in database without an established, in-progress transaction");
1420         return;
1421     }
1422
1423     transaction->notifyCursorsOfChanges(objectStoreID);
1424 }
1425
1426 int UniqueIDBDatabaseBackingStoreSQLite::idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
1427 {
1428     IDBKeyData a, b;
1429     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(aBuffer), aLength, a)) {
1430         LOG_ERROR("Unable to deserialize key A in collation function.");
1431
1432         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
1433         // We arbitrarily choose "A > B"
1434         return 1;
1435     }
1436     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(bBuffer), bLength, b)) {
1437         LOG_ERROR("Unable to deserialize key B in collation function.");
1438
1439         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
1440         // We arbitrarily choose "A > B"
1441         return 1;
1442     }
1443
1444     return a.compare(b);
1445 }
1446
1447 void UniqueIDBDatabaseBackingStoreSQLite::unregisterCursor(SQLiteIDBCursor* cursor)
1448 {
1449     ASSERT(m_cursors.contains(cursor->identifier()));
1450     m_cursors.remove(cursor->identifier());
1451 }
1452
1453 } // namespace WebKit
1454
1455 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)