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