Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / Modules / webdatabase / Database.cpp
1 /*
2  * Copyright (C) 2007, 2008, 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "Database.h"
31
32 #include "ChangeVersionData.h"
33 #include "ChangeVersionWrapper.h"
34 #include "DatabaseAuthorizer.h"
35 #include "DatabaseCallback.h"
36 #include "DatabaseContext.h"
37 #include "DatabaseManager.h"
38 #include "DatabaseTask.h"
39 #include "DatabaseThread.h"
40 #include "DatabaseTracker.h"
41 #include "Document.h"
42 #include "JSDOMWindow.h"
43 #include "Logging.h"
44 #include "Page.h"
45 #include "SQLError.h"
46 #include "SQLTransaction.h"
47 #include "SQLTransactionCallback.h"
48 #include "SQLTransactionErrorCallback.h"
49 #include "SQLiteDatabaseTracker.h"
50 #include "SQLiteStatement.h"
51 #include "SQLiteTransaction.h"
52 #include "ScriptExecutionContext.h"
53 #include "SecurityOrigin.h"
54 #include "VoidCallback.h"
55 #include <wtf/NeverDestroyed.h>
56 #include <wtf/PassRefPtr.h>
57 #include <wtf/RefPtr.h>
58 #include <wtf/StdLibExtras.h>
59 #include <wtf/text/CString.h>
60
61 namespace WebCore {
62
63 // Registering "opened" databases with the DatabaseTracker
64 // =======================================================
65 // The DatabaseTracker maintains a list of databases that have been
66 // "opened" so that the client can call interrupt or delete on every database
67 // associated with a DatabaseContext.
68 //
69 // We will only call DatabaseTracker::addOpenDatabase() to add the database
70 // to the tracker as opened when we've succeeded in opening the database,
71 // and will set m_opened to true. Similarly, we only call
72 // DatabaseTracker::removeOpenDatabase() to remove the database from the
73 // tracker when we set m_opened to false in closeDatabase(). This sets up
74 // a simple symmetry between open and close operations, and a direct
75 // correlation to adding and removing databases from the tracker's list,
76 // thus ensuring that we have a correct list for the interrupt and
77 // delete operations to work on.
78 //
79 // The only databases instances not tracked by the tracker's open database
80 // list are the ones that have not been added yet, or the ones that we
81 // attempted an open on but failed to. Such instances only exist in the
82 // DatabaseServer's factory methods for creating database backends.
83 //
84 // The factory methods will either call openAndVerifyVersion() or
85 // performOpenAndVerify(). These methods will add the newly instantiated
86 // database backend if they succeed in opening the requested database.
87 // In the case of failure to open the database, the factory methods will
88 // simply discard the newly instantiated database backend when they return.
89 // The ref counting mechanims will automatically destruct the un-added
90 // (and un-returned) databases instances.
91
92 static const char versionKey[] = "WebKitDatabaseVersionKey";
93 static const char unqualifiedInfoTableName[] = "__WebKitDatabaseInfoTable__";
94
95 static const char* fullyQualifiedInfoTableName()
96 {
97     static const char qualifier[] = "main.";
98     static char qualifiedName[sizeof(qualifier) + sizeof(unqualifiedInfoTableName) - 1];
99
100     static std::once_flag onceFlag;
101     std::call_once(onceFlag, [] {
102         strcpy(qualifiedName, qualifier);
103         strcpy(qualifiedName + sizeof(qualifier) - 1, unqualifiedInfoTableName);
104     });
105
106     return qualifiedName;
107 }
108
109 static String formatErrorMessage(const char* message, int sqliteErrorCode, const char* sqliteErrorMessage)
110 {
111     return String::format("%s (%d %s)", message, sqliteErrorCode, sqliteErrorMessage);
112 }
113
114 static bool setTextValueInDatabase(SQLiteDatabase& db, const String& query, const String& value)
115 {
116     SQLiteStatement statement(db, query);
117     int result = statement.prepare();
118
119     if (result != SQLITE_OK) {
120         LOG_ERROR("Failed to prepare statement to set value in database (%s)", query.ascii().data());
121         return false;
122     }
123
124     statement.bindText(1, value);
125
126     result = statement.step();
127     if (result != SQLITE_DONE) {
128         LOG_ERROR("Failed to step statement to set value in database (%s)", query.ascii().data());
129         return false;
130     }
131
132     return true;
133 }
134
135 static bool retrieveTextResultFromDatabase(SQLiteDatabase& db, const String& query, String& resultString)
136 {
137     SQLiteStatement statement(db, query);
138     int result = statement.prepare();
139
140     if (result != SQLITE_OK) {
141         LOG_ERROR("Error (%i) preparing statement to read text result from database (%s)", result, query.ascii().data());
142         return false;
143     }
144
145     result = statement.step();
146     if (result == SQLITE_ROW) {
147         resultString = statement.getColumnText(0);
148         return true;
149     }
150     if (result == SQLITE_DONE) {
151         resultString = String();
152         return true;
153     }
154
155     LOG_ERROR("Error (%i) reading text result from database (%s)", result, query.ascii().data());
156     return false;
157 }
158
159 // FIXME: move all guid-related functions to a DatabaseVersionTracker class.
160 static StaticLock guidMutex;
161
162 typedef HashMap<DatabaseGuid, String> GuidVersionMap;
163 static GuidVersionMap& guidToVersionMap()
164 {
165     static NeverDestroyed<GuidVersionMap> map;
166     return map;
167 }
168
169 // NOTE: Caller must lock guidMutex().
170 static inline void updateGuidVersionMap(DatabaseGuid guid, String newVersion)
171 {
172     // Note: It is not safe to put an empty string into the guidToVersionMap() map.
173     // That's because the map is cross-thread, but empty strings are per-thread.
174     // The copy() function makes a version of the string you can use on the current
175     // thread, but we need a string we can keep in a cross-thread data structure.
176     // FIXME: This is a quite-awkward restriction to have to program with.
177
178     // Map null string to empty string (see comment above).
179     guidToVersionMap().set(guid, newVersion.isEmpty() ? String() : newVersion.isolatedCopy());
180 }
181
182 typedef HashMap<DatabaseGuid, std::unique_ptr<HashSet<Database*>>> GuidDatabaseMap;
183
184 static GuidDatabaseMap& guidToDatabaseMap()
185 {
186     static NeverDestroyed<GuidDatabaseMap> map;
187     return map;
188 }
189
190 static DatabaseGuid guidForOriginAndName(const String& origin, const String& name)
191 {
192     String stringID = origin + "/" + name;
193
194     static NeverDestroyed<HashMap<String, int>> map;
195     DatabaseGuid guid = map.get().get(stringID);
196     if (!guid) {
197         static int currentNewGUID = 1;
198         guid = currentNewGUID++;
199         map.get().set(stringID, guid);
200     }
201
202     return guid;
203 }
204
205 Database::Database(PassRefPtr<DatabaseContext> databaseContext, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize)
206     : m_scriptExecutionContext(databaseContext->scriptExecutionContext())
207     , m_databaseContext(databaseContext)
208     , m_deleted(false)
209     , m_name(name.isolatedCopy())
210     , m_expectedVersion(expectedVersion.isolatedCopy())
211     , m_displayName(displayName.isolatedCopy())
212     , m_estimatedSize(estimatedSize)
213     , m_opened(false)
214     , m_new(false)
215     , m_transactionInProgress(false)
216     , m_isTransactionQueueEnabled(true)
217 {
218     m_contextThreadSecurityOrigin = m_databaseContext->securityOrigin()->isolatedCopy();
219
220     m_databaseAuthorizer = DatabaseAuthorizer::create(unqualifiedInfoTableName);
221
222     if (m_name.isNull())
223         m_name = emptyString();
224
225     {
226         std::lock_guard<StaticLock> locker(guidMutex);
227
228         m_guid = guidForOriginAndName(securityOrigin()->toString(), name);
229         std::unique_ptr<HashSet<Database*>>& hashSet = guidToDatabaseMap().add(m_guid, nullptr).iterator->value;
230         if (!hashSet)
231             hashSet = std::make_unique<HashSet<Database*>>();
232         hashSet->add(this);
233     }
234
235     m_filename = DatabaseManager::singleton().fullPathForDatabase(securityOrigin(), m_name);
236
237     m_databaseThreadSecurityOrigin = m_contextThreadSecurityOrigin->isolatedCopy();
238
239     ASSERT(m_databaseContext->databaseThread());
240 }
241
242 Database::~Database()
243 {
244     // The reference to the ScriptExecutionContext needs to be cleared on the JavaScript thread.  If we're on that thread already, we can just let the RefPtr's destruction do the dereffing.
245     if (!m_scriptExecutionContext->isContextThread()) {
246         // Grab a pointer to the script execution here because we're releasing it when we pass it to
247         // DerefContextTask::create.
248         PassRefPtr<ScriptExecutionContext> passedContext = m_scriptExecutionContext.release();
249         passedContext->postTask({ScriptExecutionContext::Task::CleanupTask, [passedContext] (ScriptExecutionContext& context) {
250             ASSERT_UNUSED(context, &context == passedContext);
251             RefPtr<ScriptExecutionContext> scriptExecutionContext(passedContext);
252         }});
253     }
254
255     // SQLite is "multi-thread safe", but each database handle can only be used
256     // on a single thread at a time.
257     //
258     // For DatabaseBackend, we open the SQLite database on the DatabaseThread,
259     // and hence we should also close it on that same thread. This means that the
260     // SQLite database need to be closed by another mechanism (see
261     // DatabaseContext::stopDatabases()). By the time we get here, the SQLite
262     // database should have already been closed.
263
264     ASSERT(!m_opened);
265 }
266
267 bool Database::openAndVerifyVersion(bool setVersionInNewDatabase, DatabaseError& error, String& errorMessage)
268 {
269     DatabaseTaskSynchronizer synchronizer;
270     if (!databaseContext()->databaseThread() || databaseContext()->databaseThread()->terminationRequested(&synchronizer))
271         return false;
272
273     bool success = false;
274     auto task = std::make_unique<DatabaseOpenTask>(*this, setVersionInNewDatabase, synchronizer, error, errorMessage, success);
275     databaseContext()->databaseThread()->scheduleImmediateTask(WTFMove(task));
276     synchronizer.waitForTaskCompletion();
277
278     return success;
279 }
280
281 void Database::close()
282 {
283     ASSERT(databaseContext()->databaseThread());
284     ASSERT(currentThread() == databaseContext()->databaseThread()->getThreadID());
285
286     {
287         LockHolder locker(m_transactionInProgressMutex);
288
289         // Clean up transactions that have not been scheduled yet:
290         // Transaction phase 1 cleanup. See comment on "What happens if a
291         // transaction is interrupted?" at the top of SQLTransactionBackend.cpp.
292         RefPtr<SQLTransactionBackend> transaction;
293         while (!m_transactionQueue.isEmpty()) {
294             transaction = m_transactionQueue.takeFirst();
295             transaction->notifyDatabaseThreadIsShuttingDown();
296         }
297
298         m_isTransactionQueueEnabled = false;
299         m_transactionInProgress = false;
300     }
301
302     closeDatabase();
303
304     // DatabaseThread keeps databases alive by referencing them in its
305     // m_openDatabaseSet. DatabaseThread::recordDatabaseClose() will remove
306     // this database from that set (which effectively deref's it). We hold on
307     // to it with a local pointer here for a liitle longer, so that we can
308     // unschedule any DatabaseTasks that refer to it before the database gets
309     // deleted.
310     Ref<Database> protect(*this);
311     databaseContext()->databaseThread()->recordDatabaseClosed(this);
312     databaseContext()->databaseThread()->unscheduleDatabaseTasks(this);
313 }
314
315 class DoneCreatingDatabaseOnExitCaller {
316 public:
317     DoneCreatingDatabaseOnExitCaller(Database* database)
318         : m_database(database)
319         , m_openSucceeded(false)
320     {
321     }
322     ~DoneCreatingDatabaseOnExitCaller()
323     {
324         DatabaseTracker::tracker().doneCreatingDatabase(m_database);
325     }
326
327     void setOpenSucceeded() { m_openSucceeded = true; }
328
329 private:
330     Database* m_database;
331     bool m_openSucceeded;
332 };
333
334 bool Database::performOpenAndVerify(bool shouldSetVersionInNewDatabase, DatabaseError& error, String& errorMessage)
335 {
336     DoneCreatingDatabaseOnExitCaller onExitCaller(this);
337     ASSERT(errorMessage.isEmpty());
338     ASSERT(error == DatabaseError::None); // Better not have any errors already.
339     error = DatabaseError::InvalidDatabaseState; // Presumed failure. We'll clear it if we succeed below.
340
341     const int maxSqliteBusyWaitTime = 30000;
342
343 #if PLATFORM(IOS)
344     {
345         // Make sure we wait till the background removal of the empty database files finished before trying to open any database.
346         LockHolder locker(DatabaseTracker::openDatabaseMutex());
347     }
348 #endif
349
350     SQLiteTransactionInProgressAutoCounter transactionCounter;
351
352     if (!m_sqliteDatabase.open(m_filename, true)) {
353         errorMessage = formatErrorMessage("unable to open database", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
354         return false;
355     }
356     if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum())
357         LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
358
359     m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime);
360
361     String currentVersion;
362     {
363         std::lock_guard<StaticLock> locker(guidMutex);
364
365         auto entry = guidToVersionMap().find(m_guid);
366         if (entry != guidToVersionMap().end()) {
367             // Map null string to empty string (see updateGuidVersionMap()).
368             currentVersion = entry->value.isNull() ? emptyString() : entry->value.isolatedCopy();
369             LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data());
370         } else {
371             LOG(StorageAPI, "No cached version for guid %i", m_guid);
372
373             SQLiteTransaction transaction(m_sqliteDatabase);
374             transaction.begin();
375             if (!transaction.inProgress()) {
376                 errorMessage = formatErrorMessage("unable to open database, failed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
377                 m_sqliteDatabase.close();
378                 return false;
379             }
380
381             String tableName(unqualifiedInfoTableName);
382             if (!m_sqliteDatabase.tableExists(tableName)) {
383                 m_new = true;
384
385                 if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + tableName + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
386                     errorMessage = formatErrorMessage("unable to open database, failed to create 'info' table", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
387                     transaction.rollback();
388                     m_sqliteDatabase.close();
389                     return false;
390                 }
391             } else if (!getVersionFromDatabase(currentVersion, false)) {
392                 errorMessage = formatErrorMessage("unable to open database, failed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
393                 transaction.rollback();
394                 m_sqliteDatabase.close();
395                 return false;
396             }
397
398             if (currentVersion.length()) {
399                 LOG(StorageAPI, "Retrieved current version %s from database %s", currentVersion.ascii().data(), databaseDebugName().ascii().data());
400             } else if (!m_new || shouldSetVersionInNewDatabase) {
401                 LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());
402                 if (!setVersionInDatabase(m_expectedVersion, false)) {
403                     errorMessage = formatErrorMessage("unable to open database, failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
404                     transaction.rollback();
405                     m_sqliteDatabase.close();
406                     return false;
407                 }
408                 currentVersion = m_expectedVersion;
409             }
410             updateGuidVersionMap(m_guid, currentVersion);
411             transaction.commit();
412         }
413     }
414
415     if (currentVersion.isNull()) {
416         LOG(StorageAPI, "Database %s does not have its version set", databaseDebugName().ascii().data());
417         currentVersion = "";
418     }
419
420     // If the expected version isn't the empty string, ensure that the current database version we have matches that version. Otherwise, set an exception.
421     // If the expected version is the empty string, then we always return with whatever version of the database we have.
422     if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length() && m_expectedVersion != currentVersion) {
423         errorMessage = "unable to open database, version mismatch, '" + m_expectedVersion + "' does not match the currentVersion of '" + currentVersion + "'";
424         m_sqliteDatabase.close();
425         return false;
426     }
427
428     ASSERT(m_databaseAuthorizer);
429     m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer);
430
431     // See comment at the top this file regarding calling addOpenDatabase().
432     DatabaseTracker::tracker().addOpenDatabase(static_cast<Database*>(this));
433     m_opened = true;
434
435     // Declare success:
436     error = DatabaseError::None; // Clear the presumed error from above.
437     onExitCaller.setOpenSucceeded();
438
439     if (m_new && !shouldSetVersionInNewDatabase)
440         m_expectedVersion = ""; // The caller provided a creationCallback which will set the expected version.
441
442     if (databaseContext()->databaseThread())
443         databaseContext()->databaseThread()->recordDatabaseOpen(this);
444
445     return true;
446 }
447
448 void Database::closeDatabase()
449 {
450     if (!m_opened)
451         return;
452
453     m_sqliteDatabase.close();
454     m_opened = false;
455     // See comment at the top this file regarding calling removeOpenDatabase().
456     DatabaseTracker::tracker().removeOpenDatabase(this);
457     {
458         std::lock_guard<StaticLock> locker(guidMutex);
459
460         auto it = guidToDatabaseMap().find(m_guid);
461         ASSERT(it != guidToDatabaseMap().end());
462         ASSERT(it->value);
463         ASSERT(it->value->contains(this));
464         it->value->remove(this);
465         if (it->value->isEmpty()) {
466             guidToDatabaseMap().remove(it);
467             guidToVersionMap().remove(m_guid);
468         }
469     }
470 }
471
472 bool Database::getVersionFromDatabase(String& version, bool shouldCacheVersion)
473 {
474     String query(String("SELECT value FROM ") + fullyQualifiedInfoTableName() +  " WHERE key = '" + versionKey + "';");
475
476     m_databaseAuthorizer->disable();
477
478     bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, query, version);
479     if (result) {
480         if (shouldCacheVersion)
481             setCachedVersion(version);
482     } else
483         LOG_ERROR("Failed to retrieve version from database %s", databaseDebugName().ascii().data());
484
485     m_databaseAuthorizer->enable();
486
487     return result;
488 }
489
490 bool Database::setVersionInDatabase(const String& version, bool shouldCacheVersion)
491 {
492     // The INSERT will replace an existing entry for the database with the new version number, due to the UNIQUE ON CONFLICT REPLACE
493     // clause in the CREATE statement (see Database::performOpenAndVerify()).
494     String query(String("INSERT INTO ") + fullyQualifiedInfoTableName() +  " (key, value) VALUES ('" + versionKey + "', ?);");
495
496     m_databaseAuthorizer->disable();
497
498     bool result = setTextValueInDatabase(m_sqliteDatabase, query, version);
499     if (result) {
500         if (shouldCacheVersion)
501             setCachedVersion(version);
502     } else
503         LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), query.ascii().data());
504
505     m_databaseAuthorizer->enable();
506
507     return result;
508 }
509
510 void Database::setExpectedVersion(const String& version)
511 {
512     m_expectedVersion = version.isolatedCopy();
513 }
514
515 String Database::getCachedVersion() const
516 {
517     std::lock_guard<StaticLock> locker(guidMutex);
518
519     return guidToVersionMap().get(m_guid).isolatedCopy();
520 }
521
522 void Database::setCachedVersion(const String& actualVersion)
523 {
524     // Update the in memory database version map.
525     std::lock_guard<StaticLock> locker(guidMutex);
526
527     updateGuidVersionMap(m_guid, actualVersion);
528 }
529
530 bool Database::getActualVersionForTransaction(String &actualVersion)
531 {
532     ASSERT(m_sqliteDatabase.transactionInProgress());
533
534     // Note: In multi-process browsers the cached value may be inaccurate.
535     // So we retrieve the value from the database and update the cached value here.
536     return getVersionFromDatabase(actualVersion, true);
537 }
538
539 void Database::scheduleTransaction()
540 {
541     ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.
542     RefPtr<SQLTransactionBackend> transaction;
543
544     if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty())
545         transaction = m_transactionQueue.takeFirst();
546
547     if (transaction && databaseContext()->databaseThread()) {
548         auto task = std::make_unique<DatabaseTransactionTask>(transaction);
549         LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction());
550         m_transactionInProgress = true;
551         databaseContext()->databaseThread()->scheduleTask(WTFMove(task));
552     } else
553         m_transactionInProgress = false;
554 }
555
556 PassRefPtr<SQLTransactionBackend> Database::runTransaction(PassRefPtr<SQLTransaction> transaction, bool readOnly, const ChangeVersionData* data)
557 {
558     LockHolder locker(m_transactionInProgressMutex);
559     if (!m_isTransactionQueueEnabled)
560         return 0;
561
562     RefPtr<SQLTransactionWrapper> wrapper;
563     if (data)
564         wrapper = ChangeVersionWrapper::create(data->oldVersion(), data->newVersion());
565
566     RefPtr<SQLTransactionBackend> transactionBackend = SQLTransactionBackend::create(this, transaction, wrapper, readOnly);
567     m_transactionQueue.append(transactionBackend);
568     if (!m_transactionInProgress)
569         scheduleTransaction();
570
571     return transactionBackend;
572 }
573
574 void Database::scheduleTransactionStep(SQLTransactionBackend* transaction)
575 {
576     if (!databaseContext()->databaseThread())
577         return;
578
579     auto task = std::make_unique<DatabaseTransactionTask>(transaction);
580     LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get());
581     databaseContext()->databaseThread()->scheduleTask(WTFMove(task));
582 }
583
584 void Database::inProgressTransactionCompleted()
585 {
586     LockHolder locker(m_transactionInProgressMutex);
587     m_transactionInProgress = false;
588     scheduleTransaction();
589 }
590
591 bool Database::hasPendingTransaction()
592 {
593     LockHolder locker(m_transactionInProgressMutex);
594     return m_transactionInProgress || !m_transactionQueue.isEmpty();
595 }
596
597 SQLTransactionClient* Database::transactionClient() const
598 {
599     return databaseContext()->databaseThread()->transactionClient();
600 }
601
602 SQLTransactionCoordinator* Database::transactionCoordinator() const
603 {
604     return databaseContext()->databaseThread()->transactionCoordinator();
605 }
606
607 String Database::version() const
608 {
609     if (m_deleted)
610         return String();
611
612     // Note: In multi-process browsers the cached value may be accurate, but we cannot read the
613     // actual version from the database without potentially inducing a deadlock.
614     // FIXME: Add an async version getter to the DatabaseAPI.
615     return getCachedVersion();
616 }
617
618 void Database::markAsDeletedAndClose()
619 {
620     if (m_deleted || !databaseContext()->databaseThread())
621         return;
622
623     LOG(StorageAPI, "Marking %s (%p) as deleted", stringIdentifier().ascii().data(), this);
624     m_deleted = true;
625
626     DatabaseTaskSynchronizer synchronizer;
627     if (databaseContext()->databaseThread()->terminationRequested(&synchronizer)) {
628         LOG(StorageAPI, "Database handle %p is on a terminated DatabaseThread, cannot be marked for normal closure\n", this);
629         return;
630     }
631
632     auto task = std::make_unique<DatabaseCloseTask>(*this, synchronizer);
633     databaseContext()->databaseThread()->scheduleImmediateTask(WTFMove(task));
634     synchronizer.waitForTaskCompletion();
635 }
636
637 void Database::changeVersion(const String& oldVersion, const String& newVersion,
638                              PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
639                              PassRefPtr<VoidCallback> successCallback)
640 {
641     ChangeVersionData data(oldVersion, newVersion);
642     runTransaction(callback, errorCallback, successCallback, false, &data);
643 }
644
645 void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback)
646 {
647     runTransaction(callback, errorCallback, successCallback, false);
648 }
649
650 void Database::readTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback)
651 {
652     runTransaction(callback, errorCallback, successCallback, true);
653 }
654
655 String Database::stringIdentifier() const
656 {
657     // Return a deep copy for ref counting thread safety
658     return m_name.isolatedCopy();
659 }
660
661 String Database::displayName() const
662 {
663     // Return a deep copy for ref counting thread safety
664     return m_displayName.isolatedCopy();
665 }
666
667 unsigned long Database::estimatedSize() const
668 {
669     return m_estimatedSize;
670 }
671
672 String Database::fileName() const
673 {
674     // Return a deep copy for ref counting thread safety
675     return m_filename.isolatedCopy();
676 }
677
678 DatabaseDetails Database::details() const
679 {
680     // This code path is only used for database quota delegate calls, so file dates are irrelevant and left uninitialized.
681     return DatabaseDetails(stringIdentifier(), displayName(), estimatedSize(), 0, 0, 0);
682 }
683
684 void Database::disableAuthorizer()
685 {
686     ASSERT(m_databaseAuthorizer);
687     m_databaseAuthorizer->disable();
688 }
689
690 void Database::enableAuthorizer()
691 {
692     ASSERT(m_databaseAuthorizer);
693     m_databaseAuthorizer->enable();
694 }
695
696 void Database::setAuthorizerPermissions(int permissions)
697 {
698     ASSERT(m_databaseAuthorizer);
699     m_databaseAuthorizer->setPermissions(permissions);
700 }
701
702 bool Database::lastActionChangedDatabase()
703 {
704     ASSERT(m_databaseAuthorizer);
705     return m_databaseAuthorizer->lastActionChangedDatabase();
706 }
707
708 bool Database::lastActionWasInsert()
709 {
710     ASSERT(m_databaseAuthorizer);
711     return m_databaseAuthorizer->lastActionWasInsert();
712 }
713
714 void Database::resetDeletes()
715 {
716     ASSERT(m_databaseAuthorizer);
717     m_databaseAuthorizer->resetDeletes();
718 }
719
720 bool Database::hadDeletes()
721 {
722     ASSERT(m_databaseAuthorizer);
723     return m_databaseAuthorizer->hadDeletes();
724 }
725
726 void Database::resetAuthorizer()
727 {
728     if (m_databaseAuthorizer)
729         m_databaseAuthorizer->reset();
730 }
731
732 void Database::runTransaction(RefPtr<SQLTransactionCallback>&& callback, RefPtr<SQLTransactionErrorCallback>&& errorCallback, RefPtr<VoidCallback>&& successCallback, bool readOnly, const ChangeVersionData* changeVersionData)
733 {
734     RefPtr<SQLTransaction> transaction = SQLTransaction::create(*this, WTFMove(callback), WTFMove(successCallback), errorCallback.copyRef(), readOnly);
735
736     RefPtr<SQLTransactionBackend> transactionBackend = runTransaction(transaction.release(), readOnly, changeVersionData);
737     if (!transactionBackend && errorCallback) {
738         WTF::RefPtr<SQLTransactionErrorCallback> errorCallbackProtector = WTFMove(errorCallback);
739         m_scriptExecutionContext->postTask([errorCallbackProtector](ScriptExecutionContext&) {
740             errorCallbackProtector->handleEvent(SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed").ptr());
741         });
742     }
743 }
744
745 void Database::scheduleTransactionCallback(SQLTransaction* transaction)
746 {
747     RefPtr<SQLTransaction> transactionProtector(transaction);
748     m_scriptExecutionContext->postTask([transactionProtector] (ScriptExecutionContext&) {
749         transactionProtector->performPendingCallback();
750     });
751 }
752
753 Vector<String> Database::performGetTableNames()
754 {
755     disableAuthorizer();
756
757     SQLiteStatement statement(sqliteDatabase(), "SELECT name FROM sqlite_master WHERE type='table';");
758     if (statement.prepare() != SQLITE_OK) {
759         LOG_ERROR("Unable to retrieve list of tables for database %s", databaseDebugName().ascii().data());
760         enableAuthorizer();
761         return Vector<String>();
762     }
763
764     Vector<String> tableNames;
765     int result;
766     while ((result = statement.step()) == SQLITE_ROW) {
767         String name = statement.getColumnText(0);
768         if (name != unqualifiedInfoTableName)
769             tableNames.append(name);
770     }
771
772     enableAuthorizer();
773
774     if (result != SQLITE_DONE) {
775         LOG_ERROR("Error getting tables for database %s", databaseDebugName().ascii().data());
776         return Vector<String>();
777     }
778
779     return tableNames;
780 }
781
782 void Database::incrementalVacuumIfNeeded()
783 {
784     SQLiteTransactionInProgressAutoCounter transactionCounter;
785
786     int64_t freeSpaceSize = m_sqliteDatabase.freeSpaceSize();
787     int64_t totalSize = m_sqliteDatabase.totalSize();
788     if (totalSize <= 10 * freeSpaceSize) {
789         int result = m_sqliteDatabase.runIncrementalVacuumCommand();
790         if (result != SQLITE_OK)
791             logErrorMessage(formatErrorMessage("error vacuuming database", result, m_sqliteDatabase.lastErrorMsg()));
792     }
793 }
794
795 void Database::logErrorMessage(const String& message)
796 {
797     m_scriptExecutionContext->addConsoleMessage(MessageSource::Storage, MessageLevel::Error, message);
798 }
799
800 Vector<String> Database::tableNames()
801 {
802     // FIXME: Not using isolatedCopy on these strings looks ok since threads take strict turns
803     // in dealing with them. However, if the code changes, this may not be true anymore.
804     Vector<String> result;
805     DatabaseTaskSynchronizer synchronizer;
806     if (!databaseContext()->databaseThread() || databaseContext()->databaseThread()->terminationRequested(&synchronizer))
807         return result;
808
809     auto task = std::make_unique<DatabaseTableNamesTask>(*this, synchronizer, result);
810     databaseContext()->databaseThread()->scheduleImmediateTask(WTFMove(task));
811     synchronizer.waitForTaskCompletion();
812
813     return result;
814 }
815
816 SecurityOrigin* Database::securityOrigin() const
817 {
818     if (m_scriptExecutionContext->isContextThread())
819         return m_contextThreadSecurityOrigin.get();
820     if (currentThread() == databaseContext()->databaseThread()->getThreadID())
821         return m_databaseThreadSecurityOrigin.get();
822     return 0;
823 }
824
825 unsigned long long Database::maximumSize() const
826 {
827     return DatabaseTracker::tracker().getMaxSizeForDatabase(this);
828 }
829
830 #if !LOG_DISABLED || !ERROR_DISABLED
831 String Database::databaseDebugName() const
832 {
833     return m_contextThreadSecurityOrigin->toString() + "::" + m_name;
834 }
835 #endif
836
837 } // namespace WebCore