15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved. 3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * its contributors may be used to endorse or promote products derived 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * from this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseBackendBase.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h" 341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Logging.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseAuthorizer.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseBase.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseContext.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseManager.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseTracker.h" 4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "modules/webdatabase/sqlite/SQLiteStatement.h" 4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "modules/webdatabase/sqlite/SQLiteTransaction.h" 4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/DatabaseIdentifier.h" 4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/Platform.h" 4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebDatabaseObserver.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/HashMap.h" 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/HashSet.h" 4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/PassRefPtr.h" 4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StdLibExtras.h" 4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/CString.h" 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/StringHash.h" 5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Registering "opened" databases with the DatabaseTracker 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ======================================================= 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The DatabaseTracker maintains a list of databases that have been 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// "opened" so that the client can call interrupt or delete on every database 56bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)// associated with a DatabaseContext. 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// We will only call DatabaseTracker::addOpenDatabase() to add the database 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to the tracker as opened when we've succeeded in opening the database, 60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// and will set m_opened to true. Similarly, we only call 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// DatabaseTracker::removeOpenDatabase() to remove the database from the 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// tracker when we set m_opened to false in closeDatabase(). This sets up 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// a simple symmetry between open and close operations, and a direct 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// correlation to adding and removing databases from the tracker's list, 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// thus ensuring that we have a correct list for the interrupt and 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// delete operations to work on. 67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The only databases instances not tracked by the tracker's open database 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// list are the ones that have not been added yet, or the ones that we 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// attempted an open on but failed to. Such instances only exist in the 71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// DatabaseServer's factory methods for creating database backends. 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The factory methods will either call openAndVerifyVersion() or 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// performOpenAndVerify(). These methods will add the newly instantiated 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// database backend if they succeed in opening the requested database. 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// In the case of failure to open the database, the factory methods will 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// simply discard the newly instantiated database backend when they return. 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The ref counting mechanims will automatically destruct the un-added 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// (and un-returned) databases instances. 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char versionKey[] = "WebKitDatabaseVersionKey"; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char infoTableName[] = "__WebKitDatabaseInfoTable__"; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String formatErrorMessage(const char* message, int sqliteErrorCode, const char* sqliteErrorMessage) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return String::format("%s (%d %s)", message, sqliteErrorCode, sqliteErrorMessage); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool retrieveTextResultFromDatabase(SQLiteDatabase& db, const String& query, String& resultString) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SQLiteStatement statement(db, query); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int result = statement.prepare(); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != SQLResultOk) { 97a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Error (%i) preparing statement to read text result from database (%s)", result, query.ascii().data()); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = statement.step(); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == SQLResultRow) { 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resultString = statement.getColumnText(0); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == SQLResultDone) { 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) resultString = String(); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 111a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Error (%i) reading text result from database (%s)", result, query.ascii().data()); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool setTextValueInDatabase(SQLiteDatabase& db, const String& query, const String& value) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SQLiteStatement statement(db, query); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int result = statement.prepare(); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != SQLResultOk) { 121a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Failed to prepare statement to set value in database (%s)", query.ascii().data()); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) statement.bindText(1, value); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = statement.step(); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != SQLResultDone) { 129a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Failed to step statement to set value in database (%s)", query.ascii().data()); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: move all guid-related functions to a DatabaseVersionTracker class. 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Mutex& guidMutex() 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return mutex; 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)typedef HashMap<DatabaseGuid, String> GuidVersionMap; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static GuidVersionMap& guidToVersionMap() 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ensure the the mutex is locked. 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!guidMutex().tryLock()); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(GuidVersionMap, map, ()); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return map; 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// NOTE: Caller must lock guidMutex(). 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline void updateGuidVersionMap(DatabaseGuid guid, String newVersion) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ensure the the mutex is locked. 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!guidMutex().tryLock()); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: It is not safe to put an empty string into the guidToVersionMap() map. 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // That's because the map is cross-thread, but empty strings are per-thread. 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The copy() function makes a version of the string you can use on the current 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // thread, but we need a string we can keep in a cross-thread data structure. 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: This is a quite-awkward restriction to have to program with. 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Map null string to empty string (see comment above). 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) guidToVersionMap().set(guid, newVersion.isEmpty() ? String() : newVersion.isolatedCopy()); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)typedef HashMap<DatabaseGuid, HashSet<DatabaseBackendBase*>*> GuidDatabaseMap; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static GuidDatabaseMap& guidToDatabaseMap() 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ensure the the mutex is locked. 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!guidMutex().tryLock()); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(GuidDatabaseMap, map, ()); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return map; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static DatabaseGuid guidForOriginAndName(const String& origin, const String& name) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ensure the the mutex is locked. 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!guidMutex().tryLock()); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String stringID = origin + "/" + name; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef HashMap<String, int> IDGuidMap; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(IDGuidMap, stringIdentifierToGUIDMap, ()); 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DatabaseGuid guid = stringIdentifierToGUIDMap.get(stringID); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!guid) { 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static int currentNewGUID = 1; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) guid = currentNewGUID++; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stringIdentifierToGUIDMap.set(stringID, guid); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return guid; 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// static 197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)const char* DatabaseBackendBase::databaseInfoTableName() 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return infoTableName; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 202bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)DatabaseBackendBase::DatabaseBackendBase(PassRefPtr<DatabaseContext> databaseContext, const String& name, 203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const String& expectedVersion, const String& displayName, unsigned long estimatedSize, DatabaseType databaseType) 204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_databaseContext(databaseContext) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_name(name.isolatedCopy()) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_expectedVersion(expectedVersion.isolatedCopy()) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_displayName(displayName.isolatedCopy()) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_estimatedSize(estimatedSize) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_guid(0) 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_opened(false) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_new(false) 212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isSyncDatabase(databaseType == DatabaseType::Sync) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_contextThreadSecurityOrigin = m_databaseContext->securityOrigin()->isolatedCopy(); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer = DatabaseAuthorizer::create(infoTableName); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_name.isNull()) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_name = ""; 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(guidMutex()); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_guid = guidForOriginAndName(securityOrigin()->toString(), name); 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) HashSet<DatabaseBackendBase*>* hashSet = guidToDatabaseMap().get(m_guid); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hashSet) { 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) hashSet = new HashSet<DatabaseBackendBase*>; 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) guidToDatabaseMap().set(m_guid, hashSet); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hashSet->add(this); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_filename = DatabaseManager::manager().fullPathForDatabase(securityOrigin(), m_name); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)DatabaseBackendBase::~DatabaseBackendBase() 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 238926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // SQLite is "multi-thread safe", but each database handle can only be used 239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // on a single thread at a time. 240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // 241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // For DatabaseBackend, we open the SQLite database on the DatabaseThread, 242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // and hence we should also close it on that same thread. This means that the 243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // SQLite database need to be closed by another mechanism (see 244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // DatabaseContext::stopDatabases()). By the time we get here, the SQLite 245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // database should have already been closed. 246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_opened); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::closeDatabase() 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_opened) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_opened = false; 257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // See comment at the top this file regarding calling removeOpenDatabase(). 258926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DatabaseTracker::tracker().removeOpenDatabase(this); 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(guidMutex()); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) HashSet<DatabaseBackendBase*>* hashSet = guidToDatabaseMap().get(m_guid); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(hashSet); 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(hashSet->contains(this)); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hashSet->remove(this); 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hashSet->isEmpty()) { 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) guidToDatabaseMap().remove(m_guid); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete hashSet; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) guidToVersionMap().remove(m_guid); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 274926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String DatabaseBackendBase::version() const 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: In multi-process browsers the cached value may be accurate, but we cannot read the 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // actual version from the database without potentially inducing a deadlock. 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Add an async version getter to the DatabaseAPI. 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getCachedVersion(); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 282926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class DoneCreatingDatabaseOnExitCaller { 283926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public: 284926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DoneCreatingDatabaseOnExitCaller(DatabaseBackendBase* database) 285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_database(database) 286926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_openSucceeded(false) 287926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 288926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 289926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ~DoneCreatingDatabaseOnExitCaller() 290926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 291926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_openSucceeded) 292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DatabaseTracker::tracker().failedToOpenDatabase(m_database); 293926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void setOpenSucceeded() { m_openSucceeded = true; } 296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 297926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private: 298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DatabaseBackendBase* m_database; 299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool m_openSucceeded; 300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}; 301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::performOpenAndVerify(bool shouldSetVersionInNewDatabase, DatabaseError& error, String& errorMessage) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DoneCreatingDatabaseOnExitCaller onExitCaller(this); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(errorMessage.isEmpty()); 306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(error == DatabaseError::None); // Better not have any errors already. 307926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) error = DatabaseError::InvalidDatabaseState; // Presumed failure. We'll clear it if we succeed below. 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const int maxSqliteBusyWaitTime = 30000; 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_sqliteDatabase.open(m_filename, true)) { 312e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(1, InvalidStateError, m_sqliteDatabase.lastError()); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = formatErrorMessage("unable to open database", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_sqliteDatabase.turnOnIncrementalAutoVacuum()) 317a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String currentVersion; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(guidMutex()); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GuidVersionMap::iterator entry = guidToVersionMap().find(m_guid); 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (entry != guidToVersionMap().end()) { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Map null string to empty string (see updateGuidVersionMap()). 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentVersion = entry->value.isNull() ? emptyString() : entry->value.isolatedCopy(); 329a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data()); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: In multi-process browsers the cached value may be inaccurate, but 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // we cannot read the actual version from the database without potentially 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // inducing a form of deadlock, a busytimeout error when trying to 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // access the database. So we'll use the cached value if we're unable to read 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the value from the database file without waiting. 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Add an async openDatabase method to the DatabaseAPI. 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const int noSqliteBusyWaitTime = 0; 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.setBusyTimeout(noSqliteBusyWaitTime); 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String versionFromDatabase; 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (getVersionFromDatabase(versionFromDatabase, false)) { 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentVersion = versionFromDatabase; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateGuidVersionMap(m_guid, currentVersion); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 346a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SQLiteTransaction transaction(m_sqliteDatabase); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transaction.begin(); 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!transaction.inProgress()) { 351e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(2, InvalidStateError, m_sqliteDatabase.lastError()); 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = formatErrorMessage("unable to open database, failed to start transaction", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String tableName(infoTableName); 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_sqliteDatabase.tableExists(tableName)) { 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_new = true; 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 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);")) { 362e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(3, InvalidStateError, m_sqliteDatabase.lastError()); 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = formatErrorMessage("unable to open database, failed to create 'info' table", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transaction.rollback(); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (!getVersionFromDatabase(currentVersion, false)) { 369e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(4, InvalidStateError, m_sqliteDatabase.lastError()); 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = formatErrorMessage("unable to open database, failed to read current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transaction.rollback(); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentVersion.length()) { 377a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Retrieved current version %s from database %s", currentVersion.ascii().data(), databaseDebugName().ascii().data()); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (!m_new || shouldSetVersionInNewDatabase) { 379a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data()); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!setVersionInDatabase(m_expectedVersion, false)) { 381e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatabase.lastError()); 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = formatErrorMessage("unable to open database, failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transaction.rollback(); 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentVersion = m_expectedVersion; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateGuidVersionMap(m_guid, currentVersion); 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transaction.commit(); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentVersion.isNull()) { 395a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(StorageAPI, "Database %s does not have its version set", databaseDebugName().ascii().data()); 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentVersion = ""; 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the expected version isn't the empty string, ensure that the current database version we have matches that version. Otherwise, set an exception. 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the expected version is the empty string, then we always return with whatever version of the database we have. 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((!m_new || shouldSetVersionInNewDatabase) && m_expectedVersion.length() && m_expectedVersion != currentVersion) { 402e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch reportOpenDatabaseResult(6, InvalidStateError, 0); 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) errorMessage = "unable to open database, version mismatch, '" + m_expectedVersion + "' does not match the currentVersion of '" + currentVersion + "'"; 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.close(); 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer); 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // See comment at the top this file regarding calling addOpenDatabase(). 412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DatabaseTracker::tracker().addOpenDatabase(this); 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_opened = true; 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 415926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Declare success: 416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) error = DatabaseError::None; // Clear the presumed error from above. 417926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) onExitCaller.setOpenSucceeded(); 418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_new && !shouldSetVersionInNewDatabase) 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_expectedVersion = ""; // The caller provided a creationCallback which will set the expected version. 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reportOpenDatabaseResult(0, -1, 0); // OK 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SecurityOrigin* DatabaseBackendBase::securityOrigin() const 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_contextThreadSecurityOrigin.get(); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String DatabaseBackendBase::stringIdentifier() const 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return a deep copy for ref counting thread safety 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_name.isolatedCopy(); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 437926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String DatabaseBackendBase::displayName() const 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return a deep copy for ref counting thread safety 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_displayName.isolatedCopy(); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 443926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)unsigned long DatabaseBackendBase::estimatedSize() const 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_estimatedSize; 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 448926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String DatabaseBackendBase::fileName() const 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Return a deep copy for ref counting thread safety 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_filename.isolatedCopy(); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 454926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)DatabaseDetails DatabaseBackendBase::details() const 455926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 456926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return DatabaseDetails(stringIdentifier(), displayName(), estimatedSize(), 0); 457926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 458926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 459926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::getVersionFromDatabase(String& version, bool shouldCacheVersion) 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String query(String("SELECT value FROM ") + infoTableName + " WHERE key = '" + versionKey + "';"); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->disable(); 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, query, version); 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result) { 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shouldCacheVersion) 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCachedVersion(version); 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 470a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Failed to retrieve version from database %s", databaseDebugName().ascii().data()); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->enable(); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::setVersionInDatabase(const String& version, bool shouldCacheVersion) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The INSERT will replace an existing entry for the database with the new version number, due to the UNIQUE ON CONFLICT REPLACE 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // clause in the CREATE statement (see Database::performOpenAndVerify()). 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String query(String("INSERT INTO ") + infoTableName + " (key, value) VALUES ('" + versionKey + "', ?);"); 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->disable(); 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool result = setTextValueInDatabase(m_sqliteDatabase, query, version); 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result) { 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shouldCacheVersion) 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCachedVersion(version); 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 490a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), query.ascii().data()); 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->enable(); 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::setExpectedVersion(const String& version) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_expectedVersion = version.isolatedCopy(); 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 502926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String DatabaseBackendBase::getCachedVersion() const 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(guidMutex()); 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return guidToVersionMap().get(m_guid).isolatedCopy(); 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 508926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::setCachedVersion(const String& actualVersion) 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Update the in memory database version map. 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(guidMutex()); 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateGuidVersionMap(m_guid, actualVersion); 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::getActualVersionForTransaction(String &actualVersion) 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_sqliteDatabase.transactionInProgress()); 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: In multi-process browsers the cached value may be inaccurate. 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // So we retrieve the value from the database and update the cached value here. 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getVersionFromDatabase(actualVersion, true); 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::disableAuthorizer() 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->disable(); 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::enableAuthorizer() 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->enable(); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::setAuthorizerReadOnly() 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->setReadOnly(); 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 541926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::setAuthorizerPermissions(int permissions) 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->setPermissions(permissions); 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::lastActionChangedDatabase() 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_databaseAuthorizer->lastActionChangedDatabase(); 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 553926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::lastActionWasInsert() 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_databaseAuthorizer->lastActionWasInsert(); 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::resetDeletes() 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->resetDeletes(); 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::hadDeletes() 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_databaseAuthorizer); 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_databaseAuthorizer->hadDeletes(); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 571926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::resetAuthorizer() 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_databaseAuthorizer) 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_databaseAuthorizer->reset(); 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)unsigned long long DatabaseBackendBase::maximumSize() const 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DatabaseTracker::tracker().getMaxSizeForDatabase(this); 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 582926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::incrementalVacuumIfNeeded() 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int64_t freeSpaceSize = m_sqliteDatabase.freeSpaceSize(); 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int64_t totalSize = m_sqliteDatabase.totalSize(); 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (totalSize <= 10 * freeSpaceSize) { 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int result = m_sqliteDatabase.runIncrementalVacuumCommand(); 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reportVacuumDatabaseResult(result); 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != SQLResultOk) 590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_frontend->logErrorMessage(formatErrorMessage("error vacuuming database", result, m_sqliteDatabase.lastErrorMsg())); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 594926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::interrupt() 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sqliteDatabase.interrupt(); 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 599926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool DatabaseBackendBase::isInterrupted() 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(m_sqliteDatabase.databaseMutex()); 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_sqliteDatabase.isInterrupted(); 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// These are used to generate histograms of errors seen with websql. 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// See about:histograms in chromium. 607926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportOpenDatabaseResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 60951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 61051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportOpenDatabaseResult( 61151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 61251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), 61351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) errorSite, webSqlErrorCode, sqliteErrorCode); 61451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 617926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportChangeVersionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 61951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 62051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportChangeVersionResult( 62151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 62251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), 62351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) errorSite, webSqlErrorCode, sqliteErrorCode); 62451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportStartTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 62951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 63051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportStartTransactionResult( 63151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 63251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), 63351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) errorSite, webSqlErrorCode, sqliteErrorCode); 63451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportCommitTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 63951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 64051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportCommitTransactionResult( 64151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 64251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), 64351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) errorSite, webSqlErrorCode, sqliteErrorCode); 64451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 647926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 64951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 65051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportExecuteStatementResult( 65151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 65251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), 65351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) errorSite, webSqlErrorCode, sqliteErrorCode); 65451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 657926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DatabaseBackendBase::reportVacuumDatabaseResult(int sqliteErrorCode) 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 65951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (blink::Platform::current()->databaseObserver()) { 66051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->databaseObserver()->reportVacuumDatabaseResult( 66151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) createDatabaseIdentifierFromSecurityOrigin(securityOrigin()), 66251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) stringIdentifier(), isSyncDatabase(), sqliteErrorCode); 66351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 668