Rename Mutex to DeprecatedMutex
[WebKit-https.git] / Source / WebCore / platform / sql / SQLiteDatabase.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "SQLiteDatabase.h"
29
30 #include "DatabaseAuthorizer.h"
31 #include "Logging.h"
32 #include "SQLiteFileSystem.h"
33 #include "SQLiteStatement.h"
34 #include <thread>
35 #include <wtf/Threading.h>
36 #include <wtf/text/CString.h>
37 #include <wtf/text/WTFString.h>
38
39 namespace WebCore {
40
41 static const char notOpenErrorMessage[] = "database is not open";
42
43 static void unauthorizedSQLFunction(sqlite3_context *context, int, sqlite3_value **)
44 {
45     const char* functionName = (const char*)sqlite3_user_data(context);
46     String errorMessage = String::format("Function %s is unauthorized", functionName);
47     sqlite3_result_error(context, errorMessage.utf8().data(), -1);
48 }
49
50 SQLiteDatabase::SQLiteDatabase()
51     : m_db(0)
52     , m_pageSize(-1)
53     , m_transactionInProgress(false)
54     , m_sharable(false)
55     , m_openingThread(0)
56     , m_interrupted(false)
57     , m_openError(SQLITE_ERROR)
58     , m_openErrorMessage()
59     , m_lastChangesCount(0)
60 {
61 }
62
63 SQLiteDatabase::~SQLiteDatabase()
64 {
65     close();
66 }
67
68 bool SQLiteDatabase::open(const String& filename, bool forWebSQLDatabase)
69 {
70     close();
71
72     m_openError = SQLiteFileSystem::openDatabase(filename, &m_db, forWebSQLDatabase);
73     if (m_openError != SQLITE_OK) {
74         m_openErrorMessage = m_db ? sqlite3_errmsg(m_db) : "sqlite_open returned null";
75         LOG_ERROR("SQLite database failed to load from %s\nCause - %s", filename.ascii().data(),
76             m_openErrorMessage.data());
77         sqlite3_close(m_db);
78         m_db = 0;
79         return false;
80     }
81
82     overrideUnauthorizedFunctions();
83
84     m_openError = sqlite3_extended_result_codes(m_db, 1);
85     if (m_openError != SQLITE_OK) {
86         m_openErrorMessage = sqlite3_errmsg(m_db);
87         LOG_ERROR("SQLite database error when enabling extended errors - %s", m_openErrorMessage.data());
88         sqlite3_close(m_db);
89         m_db = 0;
90         return false;
91     }
92
93     if (isOpen())
94         m_openingThread = currentThread();
95     else
96         m_openErrorMessage = "sqlite_open returned null";
97
98     if (!SQLiteStatement(*this, ASCIILiteral("PRAGMA temp_store = MEMORY;")).executeCommand())
99         LOG_ERROR("SQLite database could not set temp_store to memory");
100
101     SQLiteStatement walStatement(*this, ASCIILiteral("PRAGMA journal_mode=WAL;"));
102     int result = walStatement.step();
103     if (result != SQLITE_OK && result != SQLITE_ROW)
104         LOG_ERROR("SQLite database failed to set journal_mode to WAL, error: %s",  lastErrorMsg());
105
106 #ifndef NDEBUG
107     if (result == SQLITE_ROW) {
108         String mode = walStatement.getColumnText(0);
109         if (!equalIgnoringCase(mode, "wal"))
110             LOG_ERROR("journal_mode of database should be 'wal', but is '%s'", mode.utf8().data());
111     }
112 #endif
113
114     return isOpen();
115 }
116
117 void SQLiteDatabase::close()
118 {
119     if (m_db) {
120         // FIXME: This is being called on the main thread during JS GC. <rdar://problem/5739818>
121         // ASSERT(currentThread() == m_openingThread);
122         sqlite3* db = m_db;
123         {
124             DeprecatedMutexLocker locker(m_databaseClosingMutex);
125             m_db = 0;
126         }
127         sqlite3_close(db);
128     }
129
130     m_openingThread = 0;
131     m_openError = SQLITE_ERROR;
132     m_openErrorMessage = CString();
133 }
134
135 void SQLiteDatabase::overrideUnauthorizedFunctions()
136 {
137     static const std::pair<const char*, int> functionParameters[] = {
138         { "rtreenode", 2 },
139         { "rtreedepth", 1 },
140         { "eval", 1 },
141         { "eval", 2 },
142         { "printf", -1 },
143         { "fts3_tokenizer", 1 },
144         { "fts3_tokenizer", 2 },
145     };
146
147     for (auto& functionParameter : functionParameters)
148         sqlite3_create_function(m_db, functionParameter.first, functionParameter.second, SQLITE_UTF8, const_cast<char*>(functionParameter.first), unauthorizedSQLFunction, 0, 0);
149 }
150
151 void SQLiteDatabase::interrupt()
152 {
153     m_interrupted = true;
154     while (!m_lockingMutex.tryLock()) {
155         DeprecatedMutexLocker locker(m_databaseClosingMutex);
156         if (!m_db)
157             return;
158         sqlite3_interrupt(m_db);
159         std::this_thread::yield();
160     }
161
162     m_lockingMutex.unlock();
163 }
164
165 bool SQLiteDatabase::isInterrupted()
166 {
167     ASSERT(!m_lockingMutex.tryLock());
168     return m_interrupted;
169 }
170
171 void SQLiteDatabase::setFullsync(bool fsync) 
172 {
173     if (fsync) 
174         executeCommand(ASCIILiteral("PRAGMA fullfsync = 1;"));
175     else
176         executeCommand(ASCIILiteral("PRAGMA fullfsync = 0;"));
177 }
178
179 int64_t SQLiteDatabase::maximumSize()
180 {
181     int64_t maxPageCount = 0;
182
183     {
184         DeprecatedMutexLocker locker(m_authorizerLock);
185         enableAuthorizer(false);
186         SQLiteStatement statement(*this, ASCIILiteral("PRAGMA max_page_count"));
187         maxPageCount = statement.getColumnInt64(0);
188         enableAuthorizer(true);
189     }
190
191     return maxPageCount * pageSize();
192 }
193
194 void SQLiteDatabase::setMaximumSize(int64_t size)
195 {
196     if (size < 0)
197         size = 0;
198     
199     int currentPageSize = pageSize();
200
201     ASSERT(currentPageSize || !m_db);
202     int64_t newMaxPageCount = currentPageSize ? size / currentPageSize : 0;
203     
204     DeprecatedMutexLocker locker(m_authorizerLock);
205     enableAuthorizer(false);
206
207     SQLiteStatement statement(*this, "PRAGMA max_page_count = " + String::number(newMaxPageCount));
208     statement.prepare();
209     if (statement.step() != SQLITE_ROW)
210         LOG_ERROR("Failed to set maximum size of database to %lli bytes", static_cast<long long>(size));
211
212     enableAuthorizer(true);
213
214 }
215
216 int SQLiteDatabase::pageSize()
217 {
218     // Since the page size of a database is locked in at creation and therefore cannot be dynamic, 
219     // we can cache the value for future use
220     if (m_pageSize == -1) {
221         DeprecatedMutexLocker locker(m_authorizerLock);
222         enableAuthorizer(false);
223         
224         SQLiteStatement statement(*this, ASCIILiteral("PRAGMA page_size"));
225         m_pageSize = statement.getColumnInt(0);
226         
227         enableAuthorizer(true);
228     }
229
230     return m_pageSize;
231 }
232
233 int64_t SQLiteDatabase::freeSpaceSize()
234 {
235     int64_t freelistCount = 0;
236
237     {
238         DeprecatedMutexLocker locker(m_authorizerLock);
239         enableAuthorizer(false);
240         // Note: freelist_count was added in SQLite 3.4.1.
241         SQLiteStatement statement(*this, ASCIILiteral("PRAGMA freelist_count"));
242         freelistCount = statement.getColumnInt64(0);
243         enableAuthorizer(true);
244     }
245
246     return freelistCount * pageSize();
247 }
248
249 int64_t SQLiteDatabase::totalSize()
250 {
251     int64_t pageCount = 0;
252
253     {
254         DeprecatedMutexLocker locker(m_authorizerLock);
255         enableAuthorizer(false);
256         SQLiteStatement statement(*this, ASCIILiteral("PRAGMA page_count"));
257         pageCount = statement.getColumnInt64(0);
258         enableAuthorizer(true);
259     }
260
261     return pageCount * pageSize();
262 }
263
264 void SQLiteDatabase::setSynchronous(SynchronousPragma sync)
265 {
266     executeCommand("PRAGMA synchronous = " + String::number(sync));
267 }
268
269 void SQLiteDatabase::setBusyTimeout(int ms)
270 {
271     if (m_db)
272         sqlite3_busy_timeout(m_db, ms);
273     else
274         LOG(SQLDatabase, "BusyTimeout set on non-open database");
275 }
276
277 void SQLiteDatabase::setBusyHandler(int(*handler)(void*, int))
278 {
279     if (m_db)
280         sqlite3_busy_handler(m_db, handler, NULL);
281     else
282         LOG(SQLDatabase, "Busy handler set on non-open database");
283 }
284
285 bool SQLiteDatabase::executeCommand(const String& sql)
286 {
287     return SQLiteStatement(*this, sql).executeCommand();
288 }
289
290 bool SQLiteDatabase::returnsAtLeastOneResult(const String& sql)
291 {
292     return SQLiteStatement(*this, sql).returnsAtLeastOneResult();
293 }
294
295 bool SQLiteDatabase::tableExists(const String& tablename)
296 {
297     if (!isOpen())
298         return false;
299
300     String statement = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = '" + tablename + "';";
301
302     SQLiteStatement sql(*this, statement);
303     sql.prepare();
304     return sql.step() == SQLITE_ROW;
305 }
306
307 void SQLiteDatabase::clearAllTables()
308 {
309     String query = ASCIILiteral("SELECT name FROM sqlite_master WHERE type='table';");
310     Vector<String> tables;
311     if (!SQLiteStatement(*this, query).returnTextResults(0, tables)) {
312         LOG(SQLDatabase, "Unable to retrieve list of tables from database");
313         return;
314     }
315     
316     for (Vector<String>::iterator table = tables.begin(); table != tables.end(); ++table ) {
317         if (*table == "sqlite_sequence")
318             continue;
319         if (!executeCommand("DROP TABLE " + *table))
320             LOG(SQLDatabase, "Unable to drop table %s", (*table).ascii().data());
321     }
322 }
323
324 int SQLiteDatabase::runVacuumCommand()
325 {
326     if (!executeCommand(ASCIILiteral("VACUUM;")))
327         LOG(SQLDatabase, "Unable to vacuum database - %s", lastErrorMsg());
328     return lastError();
329 }
330
331 int SQLiteDatabase::runIncrementalVacuumCommand()
332 {
333     DeprecatedMutexLocker locker(m_authorizerLock);
334     enableAuthorizer(false);
335
336     if (!executeCommand(ASCIILiteral("PRAGMA incremental_vacuum")))
337         LOG(SQLDatabase, "Unable to run incremental vacuum - %s", lastErrorMsg());
338
339     enableAuthorizer(true);
340     return lastError();
341 }
342
343 int64_t SQLiteDatabase::lastInsertRowID()
344 {
345     if (!m_db)
346         return 0;
347     return sqlite3_last_insert_rowid(m_db);
348 }
349
350 void SQLiteDatabase::updateLastChangesCount()
351 {
352     if (!m_db)
353         return;
354
355     m_lastChangesCount = sqlite3_total_changes(m_db);
356 }
357
358 int SQLiteDatabase::lastChanges()
359 {
360     if (!m_db)
361         return 0;
362
363     return sqlite3_total_changes(m_db) - m_lastChangesCount;
364 }
365
366 int SQLiteDatabase::lastError()
367 {
368     return m_db ? sqlite3_errcode(m_db) : m_openError;
369 }
370
371 const char* SQLiteDatabase::lastErrorMsg()
372 {
373     if (m_db)
374         return sqlite3_errmsg(m_db);
375     return m_openErrorMessage.isNull() ? notOpenErrorMessage : m_openErrorMessage.data();
376 }
377
378 #ifndef NDEBUG
379 void SQLiteDatabase::disableThreadingChecks()
380 {
381     // This doesn't guarantee that SQList was compiled with -DTHREADSAFE, or that you haven't turned off the mutexes.
382 #if SQLITE_VERSION_NUMBER >= 3003001
383     m_sharable = true;
384 #else
385     ASSERT(0); // Your SQLite doesn't support sharing handles across threads.
386 #endif
387 }
388 #endif
389
390 int SQLiteDatabase::authorizerFunction(void* userData, int actionCode, const char* parameter1, const char* parameter2, const char* /*databaseName*/, const char* /*trigger_or_view*/)
391 {
392     DatabaseAuthorizer* auth = static_cast<DatabaseAuthorizer*>(userData);
393     ASSERT(auth);
394
395     switch (actionCode) {
396         case SQLITE_CREATE_INDEX:
397             return auth->createIndex(parameter1, parameter2);
398         case SQLITE_CREATE_TABLE:
399             return auth->createTable(parameter1);
400         case SQLITE_CREATE_TEMP_INDEX:
401             return auth->createTempIndex(parameter1, parameter2);
402         case SQLITE_CREATE_TEMP_TABLE:
403             return auth->createTempTable(parameter1);
404         case SQLITE_CREATE_TEMP_TRIGGER:
405             return auth->createTempTrigger(parameter1, parameter2);
406         case SQLITE_CREATE_TEMP_VIEW:
407             return auth->createTempView(parameter1);
408         case SQLITE_CREATE_TRIGGER:
409             return auth->createTrigger(parameter1, parameter2);
410         case SQLITE_CREATE_VIEW:
411             return auth->createView(parameter1);
412         case SQLITE_DELETE:
413             return auth->allowDelete(parameter1);
414         case SQLITE_DROP_INDEX:
415             return auth->dropIndex(parameter1, parameter2);
416         case SQLITE_DROP_TABLE:
417             return auth->dropTable(parameter1);
418         case SQLITE_DROP_TEMP_INDEX:
419             return auth->dropTempIndex(parameter1, parameter2);
420         case SQLITE_DROP_TEMP_TABLE:
421             return auth->dropTempTable(parameter1);
422         case SQLITE_DROP_TEMP_TRIGGER:
423             return auth->dropTempTrigger(parameter1, parameter2);
424         case SQLITE_DROP_TEMP_VIEW:
425             return auth->dropTempView(parameter1);
426         case SQLITE_DROP_TRIGGER:
427             return auth->dropTrigger(parameter1, parameter2);
428         case SQLITE_DROP_VIEW:
429             return auth->dropView(parameter1);
430         case SQLITE_INSERT:
431             return auth->allowInsert(parameter1);
432         case SQLITE_PRAGMA:
433             return auth->allowPragma(parameter1, parameter2);
434         case SQLITE_READ:
435             return auth->allowRead(parameter1, parameter2);
436         case SQLITE_SELECT:
437             return auth->allowSelect();
438         case SQLITE_TRANSACTION:
439             return auth->allowTransaction();
440         case SQLITE_UPDATE:
441             return auth->allowUpdate(parameter1, parameter2);
442         case SQLITE_ATTACH:
443             return auth->allowAttach(parameter1);
444         case SQLITE_DETACH:
445             return auth->allowDetach(parameter1);
446         case SQLITE_ALTER_TABLE:
447             return auth->allowAlterTable(parameter1, parameter2);
448         case SQLITE_REINDEX:
449             return auth->allowReindex(parameter1);
450 #if SQLITE_VERSION_NUMBER >= 3003013 
451         case SQLITE_ANALYZE:
452             return auth->allowAnalyze(parameter1);
453         case SQLITE_CREATE_VTABLE:
454             return auth->createVTable(parameter1, parameter2);
455         case SQLITE_DROP_VTABLE:
456             return auth->dropVTable(parameter1, parameter2);
457         case SQLITE_FUNCTION:
458             return auth->allowFunction(parameter2);
459 #endif
460         default:
461             ASSERT_NOT_REACHED();
462             return SQLAuthDeny;
463     }
464 }
465
466 void SQLiteDatabase::setAuthorizer(PassRefPtr<DatabaseAuthorizer> auth)
467 {
468     if (!m_db) {
469         LOG_ERROR("Attempt to set an authorizer on a non-open SQL database");
470         ASSERT_NOT_REACHED();
471         return;
472     }
473
474     DeprecatedMutexLocker locker(m_authorizerLock);
475
476     m_authorizer = auth;
477     
478     enableAuthorizer(true);
479 }
480
481 void SQLiteDatabase::enableAuthorizer(bool enable)
482 {
483     if (m_authorizer && enable)
484         sqlite3_set_authorizer(m_db, SQLiteDatabase::authorizerFunction, m_authorizer.get());
485     else
486         sqlite3_set_authorizer(m_db, NULL, 0);
487 }
488
489 bool SQLiteDatabase::isAutoCommitOn() const
490 {
491     return sqlite3_get_autocommit(m_db);
492 }
493
494 bool SQLiteDatabase::turnOnIncrementalAutoVacuum()
495 {
496     SQLiteStatement statement(*this, ASCIILiteral("PRAGMA auto_vacuum"));
497     int autoVacuumMode = statement.getColumnInt(0);
498     int error = lastError();
499
500     // Check if we got an error while trying to get the value of the auto_vacuum flag.
501     // If we got a SQLITE_BUSY error, then there's probably another transaction in
502     // progress on this database. In this case, keep the current value of the
503     // auto_vacuum flag and try to set it to INCREMENTAL the next time we open this
504     // database. If the error is not SQLITE_BUSY, then we probably ran into a more
505     // serious problem and should return false (to log an error message).
506     if (error != SQLITE_ROW)
507         return false;
508
509     switch (autoVacuumMode) {
510     case AutoVacuumIncremental:
511         return true;
512     case AutoVacuumFull:
513         return executeCommand(ASCIILiteral("PRAGMA auto_vacuum = 2"));
514     case AutoVacuumNone:
515     default:
516         if (!executeCommand(ASCIILiteral("PRAGMA auto_vacuum = 2")))
517             return false;
518         runVacuumCommand();
519         error = lastError();
520         return (error == SQLITE_OK);
521     }
522 }
523
524 static void destroyCollationFunction(void* arg)
525 {
526     auto f = static_cast<std::function<int(int, const void*, int, const void*)>*>(arg);
527     delete f;
528 }
529
530 static int callCollationFunction(void* arg, int aLength, const void* a, int bLength, const void* b)
531 {
532     auto f = static_cast<std::function<int(int, const void*, int, const void*)>*>(arg);
533     return (*f)(aLength, a, bLength, b);
534 }
535
536 void SQLiteDatabase::setCollationFunction(const String& collationName, std::function<int(int, const void*, int, const void*)> collationFunction)
537 {
538     auto functionObject = new std::function<int(int, const void*, int, const void*)>(collationFunction);
539     sqlite3_create_collation_v2(m_db, collationName.utf8().data(), SQLITE_UTF8, functionObject, callCollationFunction, destroyCollationFunction);
540 }
541
542 void SQLiteDatabase::removeCollationFunction(const String& collationName)
543 {
544     sqlite3_create_collation_v2(m_db, collationName.utf8().data(), SQLITE_UTF8, nullptr, nullptr, nullptr);
545 }
546
547 } // namespace WebCore