fc0393245c03765a0267c5cec3aa76579f185c9b
[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 IDBKey&, bool& keyExists)
732 {
733     // FIXME: When Get support is implemented, we need to implement this also (<rdar://problem/15779644>)
734     return false;
735 }
736
737 bool UniqueIDBDatabaseBackingStoreSQLite::putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKey& key, const uint8_t* valueBuffer, size_t valueSize)
738 {
739     ASSERT(!isMainThread());
740     ASSERT(m_sqliteDB);
741     ASSERT(m_sqliteDB->isOpen());
742
743     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
744     if (!transaction || !transaction->inProgress()) {
745         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
746         return false;
747     }
748     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
749         LOG_ERROR("Attempt to put a record into database during read-only transaction");
750         return false;
751     }
752
753     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(IDBKeyData(&key));
754     if (!keyBuffer) {
755         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
756         return false;
757     }
758     {
759         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
760         if (sql.prepare() != SQLResultOk
761             || sql.bindInt64(1, objectStoreID) != SQLResultOk
762             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLResultOk
763             || sql.bindBlob(3, valueBuffer, valueSize) != SQLResultOk
764             || sql.step() != SQLResultDone) {
765             LOG_ERROR("Could not put record for object store %lli in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
766             return false;
767         }
768     }
769
770     return true;
771 }
772
773 bool UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey)
774 {
775     ASSERT(!isMainThread());
776     ASSERT(m_sqliteDB);
777     ASSERT(m_sqliteDB->isOpen());
778
779     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
780     if (!transaction || !transaction->inProgress()) {
781         LOG_ERROR("Attempt to put index record into database without an established, in-progress transaction");
782         return false;
783     }
784     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
785         LOG_ERROR("Attempt to put index record into database during read-only transaction");
786         return false;
787     }
788
789     RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
790     if (!indexKeyBuffer) {
791         LOG_ERROR("Unable to serialize index key to be stored in the database");
792         return false;
793     }
794
795     RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
796     if (!valueBuffer) {
797         LOG_ERROR("Unable to serialize the value to be stored in the database");
798         return false;
799     }
800     {
801         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), ?);"));
802         if (sql.prepare() != SQLResultOk
803             || sql.bindInt64(1, indexID) != SQLResultOk
804             || sql.bindInt64(2, objectStoreID) != SQLResultOk
805             || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLResultOk
806             || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLResultOk
807             || sql.step() != SQLResultDone) {
808             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());
809             return false;
810         }
811     }
812
813     return true;
814 }
815
816 bool UniqueIDBDatabaseBackingStoreSQLite::getIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRangeData, RefPtr<SharedBuffer>& result)
817 {
818     ASSERT(!isMainThread());
819     ASSERT(m_sqliteDB);
820     ASSERT(m_sqliteDB->isOpen());
821
822     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
823     if (!transaction || !transaction->inProgress()) {
824         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
825         return false;
826     }
827
828     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyAndValue, IDBDatabaseBackend::NormalTask, keyRangeData);
829
830     if (!cursor) {
831         LOG_ERROR("Cannot open cursor to perform index get in database");
832         return false;
833     }
834
835     // Even though we're only using this cursor locally, add it to our cursor set.
836     m_cursors.set(cursor->identifier(), cursor);
837
838     result = SharedBuffer::create(cursor->currentValueBuffer().data(), cursor->currentValueBuffer().size());
839
840     // Closing the cursor will destroy the cursor object and remove it from our cursor set.
841     transaction->closeCursor(*cursor);
842
843     return true;
844 }
845
846 bool UniqueIDBDatabaseBackingStoreSQLite::deleteRange(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyRangeData& keyRangeData)
847 {
848     ASSERT(!isMainThread());
849     ASSERT(m_sqliteDB);
850     ASSERT(m_sqliteDB->isOpen());
851
852     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
853     if (!transaction || !transaction->inProgress()) {
854         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
855         return false;
856     }
857
858     if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
859         LOG_ERROR("Attempt to delete range from a read-only transaction");
860         return false;
861     }
862
863     // If the range to delete is exactly one key we can delete it right now.
864     if (keyRangeData.isExactlyOneKey()) {
865         if (!deleteRecord(*transaction, objectStoreID, keyRangeData.lowerKey)) {
866             LOG_ERROR("Failed to delete record for key '%s'", keyRangeData.lowerKey.loggingString().utf8().data());
867             return false;
868         }
869         return true;
870     }
871
872     // Otherwise the range might span multiple keys so we collect them with a cursor.
873     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, IDBIndexMetadata::InvalidId, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyAndValue, IDBDatabaseBackend::NormalTask, keyRangeData);
874
875     if (!cursor) {
876         LOG_ERROR("Cannot open cursor to perform index get in database");
877         return false;
878     }
879
880     m_cursors.set(cursor->identifier(), cursor);
881
882     Vector<IDBKeyData> keys;
883     do
884         keys.append(cursor->currentKey());
885     while (cursor->advance(1));
886
887     bool cursorDidError = cursor->didError();
888
889     // closeCursor() will remove the cursor from m_cursors and delete the cursor object
890     transaction->closeCursor(*cursor);
891
892     if (cursorDidError) {
893         LOG_ERROR("Unable to iterate over object store to deleteRange in database");
894         return false;
895     }
896
897     for (auto& key : keys) {
898         if (!deleteRecord(*transaction, objectStoreID, key)) {
899             LOG_ERROR("Failed to delete record for key '%s'", key.loggingString().utf8().data());
900             return false;
901         }
902     }
903
904     return true;
905 }
906
907 bool UniqueIDBDatabaseBackingStoreSQLite::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const WebCore::IDBKeyData& key)
908 {
909     ASSERT(!isMainThread());
910     ASSERT(m_sqliteDB);
911     ASSERT(m_sqliteDB->isOpen());
912
913     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(key);
914     if (!keyBuffer) {
915         LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
916         return false;
917     }
918
919     // Delete record from object store
920     {
921         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
922
923         if (sql.prepare() != SQLResultOk
924             || sql.bindInt64(1, objectStoreID) != SQLResultOk
925             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLResultOk
926             || sql.step() != SQLResultDone) {
927             LOG_ERROR("Could not delete record from object store %lli (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
928             return false;
929         }
930     }
931
932     // Delete record from indexes store
933     {
934         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
935
936         if (sql.prepare() != SQLResultOk
937             || sql.bindInt64(1, objectStoreID) != SQLResultOk
938             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLResultOk
939             || sql.step() != SQLResultDone) {
940             LOG_ERROR("Could not delete record from indexes for object store %lli (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
941             return false;
942         }
943     }
944
945     return true;
946 }
947
948 bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKey& key, RefPtr<SharedBuffer>& result)
949 {
950     ASSERT(!isMainThread());
951     ASSERT(m_sqliteDB);
952     ASSERT(m_sqliteDB->isOpen());
953
954     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
955     if (!transaction || !transaction->inProgress()) {
956         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
957         return false;
958     }
959
960     RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(IDBKeyData(&key));
961     if (!keyBuffer) {
962         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
963         return false;
964     }
965
966     {
967         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM Records WHERE objectStoreID = ? AND key = ?;"));
968         if (sql.prepare() != SQLResultOk
969             || sql.bindInt64(1, objectStoreID) != SQLResultOk
970             || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLResultOk) {
971             LOG_ERROR("Could not get record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
972             return false;
973         }
974
975         int sqlResult = sql.step();
976         if (sqlResult == SQLResultOk || sqlResult == SQLResultDone) {
977             // There was no record for the key in the database.
978             return true;
979         }
980         if (sqlResult != SQLResultRow) {
981             // There was an error fetching the record from the database.
982             LOG_ERROR("Could not get record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
983             return false;
984         }
985
986         Vector<char> buffer;
987         sql.getColumnBlobAsVector(0, buffer);
988         result = SharedBuffer::create(static_cast<const char*>(buffer.data()), buffer.size());
989     }
990
991     return true;
992 }
993
994 bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKeyRange& keyRange, RefPtr<SharedBuffer>& result, RefPtr<IDBKey>& resultKey)
995 {
996     ASSERT(!isMainThread());
997     ASSERT(m_sqliteDB);
998     ASSERT(m_sqliteDB->isOpen());
999
1000     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1001     if (!transaction || !transaction->inProgress()) {
1002         LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
1003         return false;
1004     }
1005
1006     RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(IDBKeyData(keyRange.lower().get()));
1007     if (!lowerBuffer) {
1008         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
1009         return false;
1010     }
1011
1012     RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(IDBKeyData(keyRange.upper().get()));
1013     if (!upperBuffer) {
1014         LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
1015         return false;
1016     }
1017
1018     {
1019         SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM Records WHERE objectStoreID = ? AND key >= ? AND key <= ? ORDER BY key;"));
1020         if (sql.prepare() != SQLResultOk
1021             || sql.bindInt64(1, objectStoreID) != SQLResultOk
1022             || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLResultOk
1023             || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLResultOk) {
1024             LOG_ERROR("Could not get key range record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1025             return false;
1026         }
1027
1028         int sqlResult = sql.step();
1029
1030         if (sqlResult == SQLResultOk || sqlResult == SQLResultDone) {
1031             // There was no record for the key in the database.
1032             return true;
1033         }
1034         if (sqlResult != SQLResultRow) {
1035             // There was an error fetching the record from the database.
1036             LOG_ERROR("Could not get record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
1037             return false;
1038         }
1039
1040         Vector<char> buffer;
1041         sql.getColumnBlobAsVector(0, buffer);
1042         result = SharedBuffer::create(static_cast<const char*>(buffer.data()), buffer.size());
1043     }
1044
1045     return true;
1046 }
1047
1048 bool UniqueIDBDatabaseBackingStoreSQLite::count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRangeData, int64_t& count)
1049 {
1050     ASSERT(!isMainThread());
1051     ASSERT(m_sqliteDB);
1052     ASSERT(m_sqliteDB->isOpen());
1053
1054     SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
1055     if (!transaction || !transaction->inProgress()) {
1056         LOG_ERROR("Attempt to get count from database without an established, in-progress transaction");
1057         return false;
1058     }
1059
1060     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, IndexedDB::CursorDirection::Next, IndexedDB::CursorType::KeyOnly, IDBDatabaseBackend::NormalTask, keyRangeData);
1061
1062     if (!cursor) {
1063         LOG_ERROR("Cannot open cursor to get count in database");
1064         return false;
1065     }
1066
1067     m_cursors.set(cursor->identifier(), cursor);
1068
1069     count = 0;
1070     while (cursor->advance(1))
1071         ++count;
1072
1073     transaction->closeCursor(*cursor);
1074
1075     return true;
1076 }
1077
1078 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)
1079 {
1080     ASSERT(!isMainThread());
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 open a cursor in database without an established, in-progress transaction");
1087         return false;
1088     }
1089
1090     SQLiteIDBCursor* cursor = transaction->openCursor(objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange);
1091     if (!cursor)
1092         return false;
1093
1094     m_cursors.set(cursor->identifier(), cursor);
1095     cursorID = cursor->identifier().id();
1096     key = cursor->currentKey();
1097     primaryKey = cursor->currentPrimaryKey();
1098     valueBuffer = cursor->currentValueBuffer();
1099     valueKey = cursor->currentValueKey();
1100
1101     return true;
1102 }
1103
1104 bool UniqueIDBDatabaseBackingStoreSQLite::advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& valueBuffer, IDBKeyData& valueKey)
1105 {
1106     ASSERT(!isMainThread());
1107     ASSERT(m_sqliteDB);
1108     ASSERT(m_sqliteDB->isOpen());
1109
1110     SQLiteIDBCursor* cursor = m_cursors.get(cursorIdentifier);
1111     if (!cursor) {
1112         LOG_ERROR("Attempt to advance a cursor that doesn't exist");
1113         return false;
1114     }
1115     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
1116         LOG_ERROR("Attempt to advance a cursor without an established, in-progress transaction");
1117         return false;
1118     }
1119
1120     if (!cursor->advance(count)) {
1121         LOG_ERROR("Attempt to advance cursor %lli steps failed", count);
1122         return false;
1123     }
1124
1125     key = cursor->currentKey();
1126     primaryKey = cursor->currentPrimaryKey();
1127     valueBuffer = cursor->currentValueBuffer();
1128     valueKey = cursor->currentValueKey();
1129
1130     return true;
1131 }
1132
1133 bool UniqueIDBDatabaseBackingStoreSQLite::iterateCursor(const IDBIdentifier& cursorIdentifier, const IDBKeyData& targetKey, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& valueBuffer, IDBKeyData& valueKey)
1134 {
1135     ASSERT(!isMainThread());
1136     ASSERT(m_sqliteDB);
1137     ASSERT(m_sqliteDB->isOpen());
1138
1139     SQLiteIDBCursor* cursor = m_cursors.get(cursorIdentifier);
1140     if (!cursor) {
1141         LOG_ERROR("Attempt to iterate a cursor that doesn't exist");
1142         return false;
1143     }
1144     if (!cursor->transaction() || !cursor->transaction()->inProgress()) {
1145         LOG_ERROR("Attempt to iterate a cursor without an established, in-progress transaction");
1146         return false;
1147     }
1148
1149     if (!cursor->iterate(targetKey)) {
1150         LOG_ERROR("Attempt to iterate cursor failed");
1151         return false;
1152     }
1153
1154     key = cursor->currentKey();
1155     primaryKey = cursor->currentPrimaryKey();
1156     valueBuffer = cursor->currentValueBuffer();
1157     valueKey = cursor->currentValueKey();
1158
1159     return true;
1160 }
1161
1162 int UniqueIDBDatabaseBackingStoreSQLite::idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
1163 {
1164     IDBKeyData a, b;
1165     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(aBuffer), aLength, a)) {
1166         LOG_ERROR("Unable to deserialize key A in collation function.");
1167
1168         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
1169         // We arbitrarily choose "A > B"
1170         return 1;
1171     }
1172     if (!deserializeIDBKeyData(static_cast<const uint8_t*>(bBuffer), bLength, b)) {
1173         LOG_ERROR("Unable to deserialize key B in collation function.");
1174
1175         // There's no way to indicate an error to SQLite - we have to return a sorting decision.
1176         // We arbitrarily choose "A > B"
1177         return 1;
1178     }
1179
1180     return a.compare(b);
1181 }
1182
1183 void UniqueIDBDatabaseBackingStoreSQLite::unregisterCursor(SQLiteIDBCursor* cursor)
1184 {
1185     ASSERT(m_cursors.contains(cursor->identifier()));
1186     m_cursors.remove(cursor->identifier());
1187 }
1188
1189 } // namespace WebKit
1190
1191 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)