1 /* 2 * Copyright (C) 2007, 2008 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 Computer, 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 #include "config.h" 29 #include "DatabaseTask.h" 30 31 #if ENABLE(DATABASE) 32 33 #include "Database.h" 34 #include "Logging.h" 35 36 namespace WebCore { 37 38 DatabaseTaskSynchronizer::DatabaseTaskSynchronizer() 39 : m_taskCompleted(false) 40 #ifndef NDEBUG 41 , m_hasCheckedForTermination(false) 42 #endif 43 { 44 } 45 46 void DatabaseTaskSynchronizer::waitForTaskCompletion() 47 { 48 m_synchronousMutex.lock(); 49 if (!m_taskCompleted) 50 m_synchronousCondition.wait(m_synchronousMutex); 51 m_synchronousMutex.unlock(); 52 } 53 54 void DatabaseTaskSynchronizer::taskCompleted() 55 { 56 m_synchronousMutex.lock(); 57 m_taskCompleted = true; 58 m_synchronousCondition.signal(); 59 m_synchronousMutex.unlock(); 60 } 61 62 DatabaseTask::DatabaseTask(Database* database, DatabaseTaskSynchronizer* synchronizer) 63 : m_database(database) 64 , m_synchronizer(synchronizer) 65 #if !LOG_DISABLED 66 , m_complete(false) 67 #endif 68 { 69 } 70 71 DatabaseTask::~DatabaseTask() 72 { 73 #if !LOG_DISABLED 74 ASSERT(m_complete || !m_synchronizer); 75 #endif 76 } 77 78 void DatabaseTask::performTask() 79 { 80 // Database tasks are meant to be used only once, so make sure this one hasn't been performed before. 81 #if !LOG_DISABLED 82 ASSERT(!m_complete); 83 #endif 84 85 LOG(StorageAPI, "Performing %s %p\n", debugTaskName(), this); 86 87 m_database->resetAuthorizer(); 88 doPerformTask(); 89 90 if (m_synchronizer) 91 m_synchronizer->taskCompleted(); 92 93 #if !LOG_DISABLED 94 m_complete = true; 95 #endif 96 } 97 98 // *** DatabaseOpenTask *** 99 // Opens the database file and verifies the version matches the expected version. 100 101 Database::DatabaseOpenTask::DatabaseOpenTask(Database* database, bool setVersionInNewDatabase, DatabaseTaskSynchronizer* synchronizer, ExceptionCode& code, bool& success) 102 : DatabaseTask(database, synchronizer) 103 , m_setVersionInNewDatabase(setVersionInNewDatabase) 104 , m_code(code) 105 , m_success(success) 106 { 107 ASSERT(synchronizer); // A task with output parameters is supposed to be synchronous. 108 } 109 110 void Database::DatabaseOpenTask::doPerformTask() 111 { 112 m_success = database()->performOpenAndVerify(m_setVersionInNewDatabase, m_code); 113 } 114 115 #if !LOG_DISABLED 116 const char* Database::DatabaseOpenTask::debugTaskName() const 117 { 118 return "DatabaseOpenTask"; 119 } 120 #endif 121 122 // *** DatabaseCloseTask *** 123 // Closes the database. 124 125 Database::DatabaseCloseTask::DatabaseCloseTask(Database* database, DatabaseTaskSynchronizer* synchronizer) 126 : DatabaseTask(database, synchronizer) 127 { 128 } 129 130 void Database::DatabaseCloseTask::doPerformTask() 131 { 132 database()->close(); 133 } 134 135 #if !LOG_DISABLED 136 const char* Database::DatabaseCloseTask::debugTaskName() const 137 { 138 return "DatabaseCloseTask"; 139 } 140 #endif 141 142 // *** DatabaseTransactionTask *** 143 // Starts a transaction that will report its results via a callback. 144 145 Database::DatabaseTransactionTask::DatabaseTransactionTask(PassRefPtr<SQLTransaction> transaction) 146 : DatabaseTask(transaction->database(), 0) 147 , m_transaction(transaction) 148 { 149 } 150 151 void Database::DatabaseTransactionTask::doPerformTask() 152 { 153 if (m_transaction->performNextStep()) 154 m_transaction->database()->inProgressTransactionCompleted(); 155 } 156 157 #if !LOG_DISABLED 158 const char* Database::DatabaseTransactionTask::debugTaskName() const 159 { 160 return "DatabaseTransactionTask"; 161 } 162 #endif 163 164 // *** DatabaseTableNamesTask *** 165 // Retrieves a list of all tables in the database - for WebInspector support. 166 167 Database::DatabaseTableNamesTask::DatabaseTableNamesTask(Database* database, DatabaseTaskSynchronizer* synchronizer, Vector<String>& names) 168 : DatabaseTask(database, synchronizer) 169 , m_tableNames(names) 170 { 171 ASSERT(synchronizer); // A task with output parameters is supposed to be synchronous. 172 } 173 174 void Database::DatabaseTableNamesTask::doPerformTask() 175 { 176 m_tableNames = database()->performGetTableNames(); 177 } 178 179 #if !LOG_DISABLED 180 const char* Database::DatabaseTableNamesTask::debugTaskName() const 181 { 182 return "DatabaseTableNamesTask"; 183 } 184 #endif 185 186 } // namespace WebCore 187 188 #endif 189