summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/sql
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitd8543bb6618c17b12da906afa77d216f58cf4058 (patch)
treec58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/platform/sql
downloadexternal_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2
external/webkit r30707
Diffstat (limited to 'WebCore/platform/sql')
-rw-r--r--WebCore/platform/sql/SQLValue.cpp56
-rw-r--r--WebCore/platform/sql/SQLValue.h58
-rw-r--r--WebCore/platform/sql/SQLiteAuthorizer.cpp39
-rw-r--r--WebCore/platform/sql/SQLiteAuthorizer.h88
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.cpp353
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.h130
-rw-r--r--WebCore/platform/sql/SQLiteStatement.cpp453
-rw-r--r--WebCore/platform/sql/SQLiteStatement.h100
-rw-r--r--WebCore/platform/sql/SQLiteTransaction.cpp80
-rw-r--r--WebCore/platform/sql/SQLiteTransaction.h56
10 files changed, 1413 insertions, 0 deletions
diff --git a/WebCore/platform/sql/SQLValue.cpp b/WebCore/platform/sql/SQLValue.cpp
new file mode 100644
index 0000000..7e178f9
--- /dev/null
+++ b/WebCore/platform/sql/SQLValue.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SQLValue.h"
+
+namespace WebCore {
+
+SQLValue::SQLValue(const SQLValue& val)
+{
+ m_number = val.m_number;
+ m_string = val.m_string.copy();
+ m_type = val.m_type;
+}
+
+String SQLValue::string() const
+{
+ ASSERT(m_type == StringValue);
+
+ // Must return a copy since ref-shared Strings are not thread safe
+ return m_string.copy();
+}
+
+double SQLValue::number() const
+{
+ ASSERT(m_type == NumberValue);
+
+ return m_number;
+}
+
+}
diff --git a/WebCore/platform/sql/SQLValue.h b/WebCore/platform/sql/SQLValue.h
new file mode 100644
index 0000000..7d85051
--- /dev/null
+++ b/WebCore/platform/sql/SQLValue.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SQLValue_h
+#define SQLValue_h
+
+#include "PlatformString.h"
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+ class SQLValue {
+ public:
+ enum Type { NullValue, NumberValue, StringValue };
+
+ SQLValue() : m_type(NullValue) { }
+ SQLValue(double number) : m_type(NumberValue), m_number(number) { }
+ SQLValue(const String& s) : m_type(StringValue), m_string(s) { }
+ SQLValue(const SQLValue&);
+
+ Type type() const { return m_type; }
+
+ String string() const;
+ double number() const;
+
+ private:
+ Type m_type;
+ double m_number;
+ String m_string;
+ };
+};
+
+#endif
diff --git a/WebCore/platform/sql/SQLiteAuthorizer.cpp b/WebCore/platform/sql/SQLiteAuthorizer.cpp
new file mode 100644
index 0000000..e1014ec
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteAuthorizer.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "SQLiteAuthorizer.h"
+
+#include <sqlite3.h>
+
+namespace WebCore {
+
+const int SQLAuthAllow = SQLITE_OK;
+const int SQLAuthIgnore = SQLITE_IGNORE;
+const int SQLAuthDeny = SQLITE_DENY;
+
+} // namespace WebCore
diff --git a/WebCore/platform/sql/SQLiteAuthorizer.h b/WebCore/platform/sql/SQLiteAuthorizer.h
new file mode 100644
index 0000000..0bb0fb3
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteAuthorizer.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SQLiteAuthorizer_h
+#define SQLiteAuthorizer_h
+
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class String;
+
+extern const int SQLAuthAllow;
+extern const int SQLAuthIgnore;
+extern const int SQLAuthDeny;
+
+class SQLiteAuthorizer : public ThreadSafeShared<SQLiteAuthorizer> {
+public:
+ virtual ~SQLiteAuthorizer() { }
+
+ virtual int createTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowAlterTable(const String& databaseName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createView(const String& viewName) { return SQLAuthAllow; }
+ virtual int createTempView(const String& viewName) { return SQLAuthAllow; }
+ virtual int dropView(const String& viewName) { return SQLAuthAllow; }
+ virtual int dropTempView(const String& viewName) { return SQLAuthAllow; }
+
+ virtual int createVTable(const String& tableName, const String& moduleName) { return SQLAuthAllow; }
+ virtual int dropVTable(const String& tableName, const String& moduleName) { return SQLAuthAllow; }
+
+ virtual int allowDelete(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowInsert(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowUpdate(const String& tableName, const String& columnName) { return SQLAuthAllow; }
+ virtual int allowTransaction() { return SQLAuthAllow; }
+
+ virtual int allowSelect() { return SQLAuthAllow; }
+ virtual int allowRead(const String& tableName, const String& columnName) { return SQLAuthAllow; }
+
+ virtual int allowAttach(const String& filename) { return SQLAuthAllow; }
+ virtual int allowDetach(const String& databaseName) { return SQLAuthAllow; }
+
+ virtual int allowReindex(const String& indexName) { return SQLAuthAllow; }
+ virtual int allowAnalyze(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowFunction(const String& functionName) { return SQLAuthAllow; }
+ virtual int allowPragma(const String& pragmaName, const String& firstArgument) { return SQLAuthAllow; }
+};
+
+} // namespace WebCore
+
+#endif // SQLiteAuthorizer_h
diff --git a/WebCore/platform/sql/SQLiteDatabase.cpp b/WebCore/platform/sql/SQLiteDatabase.cpp
new file mode 100644
index 0000000..7768f66
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteDatabase.cpp
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SQLiteDatabase.h"
+
+#include "Logging.h"
+#include "SQLiteAuthorizer.h"
+#include "SQLiteStatement.h"
+
+#include <sqlite3.h>
+
+namespace WebCore {
+
+const int SQLResultDone = SQLITE_DONE;
+const int SQLResultError = SQLITE_ERROR;
+const int SQLResultOk = SQLITE_OK;
+const int SQLResultRow = SQLITE_ROW;
+const int SQLResultSchema = SQLITE_SCHEMA;
+const int SQLResultFull = SQLITE_FULL;
+
+
+SQLiteDatabase::SQLiteDatabase()
+ : m_db(0)
+ , m_pageSize(-1)
+ , m_transactionInProgress(false)
+ , m_openingThread(0)
+{
+}
+
+SQLiteDatabase::~SQLiteDatabase()
+{
+ close();
+}
+
+bool SQLiteDatabase::open(const String& filename)
+{
+ close();
+
+ // SQLite expects a null terminator on its UTF-16 strings.
+ String path = filename;
+ m_lastError = sqlite3_open16(path.charactersWithNullTermination(), &m_db);
+ if (m_lastError != SQLITE_OK) {
+ LOG_ERROR("SQLite database failed to load from %s\nCause - %s", filename.ascii().data(),
+ sqlite3_errmsg(m_db));
+ sqlite3_close(m_db);
+ m_db = 0;
+ return false;
+ }
+
+ if (isOpen())
+ m_openingThread = currentThread();
+
+ if (!SQLiteStatement(*this, "PRAGMA temp_store = MEMORY;").executeCommand())
+ LOG_ERROR("SQLite database could not set temp_store to memory");
+
+ return isOpen();
+}
+
+void SQLiteDatabase::close()
+{
+ if (m_db) {
+ // FIXME: This is being called on themain thread during JS GC. <rdar://problem/5739818>
+ // ASSERT(currentThread() == m_openingThread);
+ sqlite3_close(m_db);
+ m_db = 0;
+ }
+
+ m_openingThread = 0;
+}
+
+void SQLiteDatabase::setFullsync(bool fsync)
+{
+ if (fsync)
+ executeCommand("PRAGMA fullfsync = 1;");
+ else
+ executeCommand("PRAGMA fullfsync = 0;");
+}
+
+int64_t SQLiteDatabase::maximumSize()
+{
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+
+ SQLiteStatement statement(*this, "PRAGMA max_page_count");
+ int64_t size = statement.getColumnInt64(0) * pageSize();
+
+ enableAuthorizer(true);
+ return size;
+}
+
+void SQLiteDatabase::setMaximumSize(int64_t size)
+{
+ if (size < 0)
+ size = 0;
+
+ int currentPageSize = pageSize();
+
+ ASSERT(currentPageSize);
+ int64_t newMaxPageCount = currentPageSize ? size / currentPageSize : 0;
+
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+
+ SQLiteStatement statement(*this, "PRAGMA max_page_count = " + String::number(newMaxPageCount));
+ statement.prepare();
+ if (statement.step() != SQLResultRow)
+ LOG_ERROR("Failed to set maximum size of database to %lli bytes", size);
+
+ enableAuthorizer(true);
+
+}
+
+int SQLiteDatabase::pageSize()
+{
+ // Since the page size of a database is locked in at creation and therefore cannot be dynamic,
+ // we can cache the value for future use
+ if (m_pageSize == -1) {
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+
+ SQLiteStatement statement(*this, "PRAGMA page_size");
+ m_pageSize = statement.getColumnInt(0);
+
+ enableAuthorizer(true);
+ }
+
+ return m_pageSize;
+}
+
+void SQLiteDatabase::setSynchronous(SynchronousPragma sync)
+{
+ executeCommand(String::format("PRAGMA synchronous = %i", sync));
+}
+
+void SQLiteDatabase::setBusyTimeout(int ms)
+{
+ if (m_db)
+ sqlite3_busy_timeout(m_db, ms);
+ else
+ LOG(SQLDatabase, "BusyTimeout set on non-open database");
+}
+
+void SQLiteDatabase::setBusyHandler(int(*handler)(void*, int))
+{
+ if (m_db)
+ sqlite3_busy_handler(m_db, handler, NULL);
+ else
+ LOG(SQLDatabase, "Busy handler set on non-open database");
+}
+
+bool SQLiteDatabase::executeCommand(const String& sql)
+{
+ return SQLiteStatement(*this, sql).executeCommand();
+}
+
+bool SQLiteDatabase::returnsAtLeastOneResult(const String& sql)
+{
+ return SQLiteStatement(*this, sql).returnsAtLeastOneResult();
+}
+
+bool SQLiteDatabase::tableExists(const String& tablename)
+{
+ if (!isOpen())
+ return false;
+
+ String statement = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = '" + tablename + "';";
+
+ SQLiteStatement sql(*this, statement);
+ sql.prepare();
+ return sql.step() == SQLITE_ROW;
+}
+
+void SQLiteDatabase::clearAllTables()
+{
+ String query = "SELECT name FROM sqlite_master WHERE type='table';";
+ Vector<String> tables;
+ if (!SQLiteStatement(*this, query).returnTextResults(0, tables)) {
+ LOG(SQLDatabase, "Unable to retrieve list of tables from database");
+ return;
+ }
+
+ for (Vector<String>::iterator table = tables.begin(); table != tables.end(); ++table ) {
+ if (*table == "sqlite_sequence")
+ continue;
+ if (!executeCommand("DROP TABLE " + *table))
+ LOG(SQLDatabase, "Unable to drop table %s", (*table).ascii().data());
+ }
+}
+
+void SQLiteDatabase::runVacuumCommand()
+{
+ if (!executeCommand("VACUUM;"))
+ LOG(SQLDatabase, "Unable to vacuum database - %s", lastErrorMsg());
+}
+
+int64_t SQLiteDatabase::lastInsertRowID()
+{
+ if (!m_db)
+ return 0;
+ return sqlite3_last_insert_rowid(m_db);
+}
+
+int SQLiteDatabase::lastChanges()
+{
+ if (!m_db)
+ return 0;
+ return sqlite3_changes(m_db);
+}
+
+int SQLiteDatabase::lastError()
+{
+ return m_db ? sqlite3_errcode(m_db) : SQLITE_ERROR;
+}
+
+const char* SQLiteDatabase::lastErrorMsg()
+{
+ return sqlite3_errmsg(m_db);
+}
+
+int SQLiteDatabase::authorizerFunction(void* userData, int actionCode, const char* parameter1, const char* parameter2, const char* /*databaseName*/, const char* /*trigger_or_view*/)
+{
+ SQLiteAuthorizer* auth = static_cast<SQLiteAuthorizer*>(userData);
+ ASSERT(auth);
+
+ switch (actionCode) {
+ case SQLITE_CREATE_INDEX:
+ return auth->createIndex(parameter1, parameter2);
+ case SQLITE_CREATE_TABLE:
+ return auth->createTable(parameter1);
+ case SQLITE_CREATE_TEMP_INDEX:
+ return auth->createTempIndex(parameter1, parameter2);
+ case SQLITE_CREATE_TEMP_TABLE:
+ return auth->createTempTable(parameter1);
+ case SQLITE_CREATE_TEMP_TRIGGER:
+ return auth->createTempTrigger(parameter1, parameter2);
+ case SQLITE_CREATE_TEMP_VIEW:
+ return auth->createTempView(parameter1);
+ case SQLITE_CREATE_TRIGGER:
+ return auth->createTrigger(parameter1, parameter2);
+ case SQLITE_CREATE_VIEW:
+ return auth->createView(parameter1);
+ case SQLITE_DELETE:
+ return auth->allowDelete(parameter1);
+ case SQLITE_DROP_INDEX:
+ return auth->dropIndex(parameter1, parameter2);
+ case SQLITE_DROP_TABLE:
+ return auth->dropTable(parameter1);
+ case SQLITE_DROP_TEMP_INDEX:
+ return auth->dropTempIndex(parameter1, parameter2);
+ case SQLITE_DROP_TEMP_TABLE:
+ return auth->dropTempTable(parameter1);
+ case SQLITE_DROP_TEMP_TRIGGER:
+ return auth->dropTempTrigger(parameter1, parameter2);
+ case SQLITE_DROP_TEMP_VIEW:
+ return auth->dropTempView(parameter1);
+ case SQLITE_DROP_TRIGGER:
+ return auth->dropTrigger(parameter1, parameter2);
+ case SQLITE_DROP_VIEW:
+ return auth->dropView(parameter1);
+ case SQLITE_INSERT:
+ return auth->allowInsert(parameter1);
+ case SQLITE_PRAGMA:
+ return auth->allowPragma(parameter1, parameter2);
+ case SQLITE_READ:
+ return auth->allowRead(parameter1, parameter2);
+ case SQLITE_SELECT:
+ return auth->allowSelect();
+ case SQLITE_TRANSACTION:
+ return auth->allowTransaction();
+ case SQLITE_UPDATE:
+ return auth->allowUpdate(parameter1, parameter2);
+ case SQLITE_ATTACH:
+ return auth->allowAttach(parameter1);
+ case SQLITE_DETACH:
+ return auth->allowDetach(parameter1);
+ case SQLITE_ALTER_TABLE:
+ return auth->allowAlterTable(parameter1, parameter2);
+ case SQLITE_REINDEX:
+ return auth->allowReindex(parameter1);
+#if SQLITE_VERSION_NUMBER >= 3003013
+ case SQLITE_ANALYZE:
+ return auth->allowAnalyze(parameter1);
+ case SQLITE_CREATE_VTABLE:
+ return auth->createVTable(parameter1, parameter2);
+ case SQLITE_DROP_VTABLE:
+ return auth->dropVTable(parameter1, parameter2);
+ case SQLITE_FUNCTION:
+ return auth->allowFunction(parameter1);
+#endif
+ default:
+ ASSERT_NOT_REACHED();
+ return SQLAuthDeny;
+ }
+}
+
+void SQLiteDatabase::setAuthorizer(PassRefPtr<SQLiteAuthorizer> auth)
+{
+ if (!m_db) {
+ LOG_ERROR("Attempt to set an authorizer on a non-open SQL database");
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ MutexLocker locker(m_authorizerLock);
+
+ m_authorizer = auth;
+
+ enableAuthorizer(true);
+}
+
+void SQLiteDatabase::enableAuthorizer(bool enable)
+{
+ if (m_authorizer && enable)
+ sqlite3_set_authorizer(m_db, SQLiteDatabase::authorizerFunction, m_authorizer.get());
+ else
+ sqlite3_set_authorizer(m_db, NULL, 0);
+}
+
+void SQLiteDatabase::lock()
+{
+ m_lockingMutex.lock();
+}
+
+void SQLiteDatabase::unlock()
+{
+ m_lockingMutex.unlock();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/sql/SQLiteDatabase.h b/WebCore/platform/sql/SQLiteDatabase.h
new file mode 100644
index 0000000..20f461d
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteDatabase.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SQLDatabase_h
+#define SQLDatabase_h
+
+#include "PlatformString.h"
+#include <wtf/Threading.h>
+
+#if COMPILER(MSVC)
+#pragma warning(disable: 4800)
+#endif
+
+struct sqlite3;
+
+namespace WebCore {
+
+class SQLiteAuthorizer;
+class SQLiteStatement;
+class SQLiteTransaction;
+
+extern const int SQLResultDone;
+extern const int SQLResultError;
+extern const int SQLResultOk;
+extern const int SQLResultRow;
+extern const int SQLResultSchema;
+extern const int SQLResultFull;
+
+class SQLiteDatabase : public Noncopyable {
+ friend class SQLiteTransaction;
+public:
+ SQLiteDatabase();
+ ~SQLiteDatabase();
+
+ bool open(const String& filename);
+ bool isOpen() const { return m_db; }
+ void close();
+
+ bool executeCommand(const String&);
+ bool returnsAtLeastOneResult(const String&);
+
+ bool tableExists(const String&);
+ void clearAllTables();
+ void runVacuumCommand();
+
+ bool transactionInProgress() const { return m_transactionInProgress; }
+
+ int64_t lastInsertRowID();
+ int lastChanges();
+
+ void setBusyTimeout(int ms);
+ void setBusyHandler(int(*)(void*, int));
+
+ void setFullsync(bool);
+
+ // Gets/sets the maximum size in bytes
+ // Depending on per-database attributes, the size will only be settable in units that are the page size of the database, which is established at creation
+ // These chunks will never be anything other than 512, 1024, 2048, 4096, 8192, 16384, or 32768 bytes in size.
+ // setMaximumSize() will round the size down to the next smallest chunk if the passed size doesn't align.
+ int64_t maximumSize();
+ void setMaximumSize(int64_t);
+
+ // The SQLite SYNCHRONOUS pragma can be either FULL, NORMAL, or OFF
+ // FULL - Any writing calls to the DB block until the data is actually on the disk surface
+ // NORMAL - SQLite pauses at some critical moments when writing, but much less than FULL
+ // OFF - Calls return immediately after the data has been passed to disk
+ enum SynchronousPragma { SyncOff = 0, SyncNormal = 1, SyncFull = 2 };
+ void setSynchronous(SynchronousPragma);
+
+ int lastError();
+ const char* lastErrorMsg();
+
+ sqlite3* sqlite3Handle() const {
+ ASSERT(currentThread() == m_openingThread);
+ return m_db;
+ }
+
+ void setAuthorizer(PassRefPtr<SQLiteAuthorizer>);
+
+ // (un)locks the database like a mutex
+ void lock();
+ void unlock();
+
+private:
+ static int authorizerFunction(void*, int, const char*, const char*, const char*, const char*);
+
+ void enableAuthorizer(bool enable);
+
+ int pageSize();
+
+ sqlite3* m_db;
+ int m_lastError;
+ int m_pageSize;
+
+ bool m_transactionInProgress;
+
+ Mutex m_authorizerLock;
+ RefPtr<SQLiteAuthorizer> m_authorizer;
+
+ Mutex m_lockingMutex;
+ ThreadIdentifier m_openingThread;
+
+}; // class SQLiteDatabase
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/sql/SQLiteStatement.cpp b/WebCore/platform/sql/SQLiteStatement.cpp
new file mode 100644
index 0000000..ac96034
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteStatement.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SQLiteStatement.h"
+
+#include "Logging.h"
+#include "SQLValue.h"
+#include <sqlite3.h>
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+#if SQLITE_VERSION_NUMBER < 3003009
+
+// FIXME: This overload helps us compile with older versions of SQLite 3, but things like quotas will not work.
+static inline int sqlite3_prepare16_v2(sqlite3* db, const void* zSql, int nBytes, sqlite3_stmt** ppStmt, const void** pzTail)
+{
+ return sqlite3_prepare16(db, zSql, nBytes, ppStmt, pzTail);
+}
+
+#endif
+
+SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
+ : m_database(db)
+ , m_query(sql)
+ , m_statement(0)
+#ifndef NDEBUG
+ , m_isPrepared(false)
+#endif
+{
+}
+
+SQLiteStatement::~SQLiteStatement()
+{
+ finalize();
+}
+
+int SQLiteStatement::prepare()
+{
+ ASSERT(!m_isPrepared);
+ const void* tail;
+ LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
+ int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.charactersWithNullTermination(), -1, &m_statement, &tail);
+ if (error != SQLITE_OK)
+ LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
+#ifndef NDEBUG
+ m_isPrepared = error == SQLITE_OK;
+#endif
+ return error;
+}
+
+int SQLiteStatement::step()
+{
+ ASSERT(m_isPrepared);
+ if (!m_statement)
+ return SQLITE_OK;
+ LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
+ int error = sqlite3_step(m_statement);
+ if (error != SQLITE_DONE && error != SQLITE_ROW) {
+ LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
+ error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
+ }
+ return error;
+}
+
+int SQLiteStatement::finalize()
+{
+#ifndef NDEBUG
+ m_isPrepared = false;
+#endif
+ if (!m_statement)
+ return SQLITE_OK;
+ LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
+ int result = sqlite3_finalize(m_statement);
+ m_statement = 0;
+ return result;
+}
+
+int SQLiteStatement::reset()
+{
+ ASSERT(m_isPrepared);
+ if (!m_statement)
+ return SQLITE_OK;
+ LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data());
+ return sqlite3_reset(m_statement);
+}
+
+bool SQLiteStatement::executeCommand()
+{
+ if (!m_statement && prepare() != SQLITE_OK)
+ return false;
+ ASSERT(m_isPrepared);
+ if (step() != SQLITE_DONE) {
+ finalize();
+ return false;
+ }
+ finalize();
+ return true;
+}
+
+bool SQLiteStatement::returnsAtLeastOneResult()
+{
+ if (!m_statement && prepare() != SQLITE_OK)
+ return false;
+ ASSERT(m_isPrepared);
+ if (step() != SQLITE_ROW) {
+ finalize();
+ return false;
+ }
+ finalize();
+ return true;
+
+}
+
+int SQLiteStatement::bindBlob(int index, const void* blob, int size)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+ ASSERT(blob);
+ ASSERT(size >= 0);
+
+ if (!m_statement)
+ return SQLITE_ERROR;
+
+ return sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
+}
+
+int SQLiteStatement::bindText(int index, const String& text)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+
+ // String::characters() returns 0 for the empty string, which SQLite
+ // treats as a null, so we supply a non-null pointer for that case.
+ UChar anyCharacter = 0;
+ const UChar* characters;
+ if (text.isEmpty() && !text.isNull())
+ characters = &anyCharacter;
+ else
+ characters = text.characters();
+
+ return sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
+}
+
+
+int SQLiteStatement::bindInt64(int index, int64_t integer)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+
+ return sqlite3_bind_int64(m_statement, index, integer);
+}
+
+int SQLiteStatement::bindDouble(int index, double number)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+
+ return sqlite3_bind_double(m_statement, index, number);
+}
+
+int SQLiteStatement::bindNull(int index)
+{
+ ASSERT(m_isPrepared);
+ ASSERT(index > 0);
+ ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
+
+ return sqlite3_bind_null(m_statement, index);
+}
+
+int SQLiteStatement::bindValue(int index, const SQLValue& value)
+{
+ switch (value.type()) {
+ case SQLValue::StringValue:
+ return bindText(index, value.string());
+ case SQLValue::NumberValue:
+ return bindDouble(index, value.number());
+ case SQLValue::NullValue:
+ return bindNull(index);
+ }
+
+ ASSERT_NOT_REACHED();
+ return SQLITE_ERROR;
+}
+
+unsigned SQLiteStatement::bindParameterCount() const
+{
+ ASSERT(m_isPrepared);
+ if (!m_statement)
+ return 0;
+ return sqlite3_bind_parameter_count(m_statement);
+}
+
+int SQLiteStatement::columnCount()
+{
+ ASSERT(m_isPrepared);
+ if (!m_statement)
+ return 0;
+ return sqlite3_data_count(m_statement);
+}
+
+String SQLiteStatement::getColumnName(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return String();
+ if (columnCount() <= col)
+ return String();
+ return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
+}
+
+SQLValue SQLiteStatement::getColumnValue(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return SQLValue();
+ if (columnCount() <= col)
+ return SQLValue();
+
+ // SQLite is typed per value. optional column types are
+ // "(mostly) ignored"
+ sqlite3_value* value = sqlite3_column_value(m_statement, col);
+ switch (sqlite3_value_type(value)) {
+ case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use FLOAT -case
+ case SQLITE_FLOAT:
+ return SQLValue(sqlite3_value_double(value));
+ case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT -case
+ case SQLITE_TEXT:
+ return SQLValue(String(reinterpret_cast<const UChar*>(sqlite3_value_text16(value))));
+ case SQLITE_NULL:
+ return SQLValue();
+ default:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return SQLValue();
+}
+
+String SQLiteStatement::getColumnText(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return String();
+ if (columnCount() <= col)
+ return String();
+ return String(reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col)));
+}
+
+double SQLiteStatement::getColumnDouble(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return 0.0;
+ if (columnCount() <= col)
+ return 0.0;
+ return sqlite3_column_double(m_statement, col);
+}
+
+int SQLiteStatement::getColumnInt(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return 0;
+ if (columnCount() <= col)
+ return 0;
+ return sqlite3_column_int(m_statement, col);
+}
+
+int64_t SQLiteStatement::getColumnInt64(int col)
+{
+ ASSERT(col >= 0);
+ if (!m_statement)
+ if (prepareAndStep() != SQLITE_ROW)
+ return 0;
+ if (columnCount() <= col)
+ return 0;
+ return sqlite3_column_int64(m_statement, col);
+}
+
+void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
+{
+ ASSERT(col >= 0);
+
+ if (!m_statement && prepareAndStep() != SQLITE_ROW) {
+ result.clear();
+ return;
+ }
+
+ if (columnCount() <= col) {
+ result.clear();
+ return;
+ }
+
+ const void* blob = sqlite3_column_blob(m_statement, col);
+ if (!blob) {
+ result.clear();
+ return;
+ }
+
+ int size = sqlite3_column_bytes(m_statement, col);
+ result.resize((size_t)size);
+ for (int i = 0; i < size; ++i)
+ result[i] = ((const unsigned char*)blob)[i];
+}
+
+const void* SQLiteStatement::getColumnBlob(int col, int& size)
+{
+ ASSERT(col >= 0);
+
+ size = 0;
+
+ if (finalize() != SQLITE_OK)
+ LOG(SQLDatabase, "Finalize failed");
+ if (prepare() != SQLITE_OK) {
+ LOG(SQLDatabase, "Prepare failed");
+ return 0;
+ }
+ if (step() != SQLITE_ROW) {
+ LOG(SQLDatabase, "Step wasn't a row");
+ return 0;
+ }
+
+ if (columnCount() <= col)
+ return 0;
+
+ const void* blob = sqlite3_column_blob(m_statement, col);
+ if (!blob)
+ return 0;
+
+ size = sqlite3_column_bytes(m_statement, col);
+ return blob;
+}
+
+bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
+{
+ ASSERT(col >= 0);
+
+ v.clear();
+
+ if (m_statement)
+ finalize();
+ if (prepare() != SQLITE_OK)
+ return false;
+
+ while (step() == SQLITE_ROW)
+ v.append(getColumnText(col));
+ bool result = true;
+ if (m_database.lastError() != SQLITE_DONE) {
+ result = false;
+ LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
+ }
+ finalize();
+ return result;
+}
+
+bool SQLiteStatement::returnIntResults(int col, Vector<int>& v)
+{
+ v.clear();
+
+ if (m_statement)
+ finalize();
+ if (prepare() != SQLITE_OK)
+ return false;
+
+ while (step() == SQLITE_ROW)
+ v.append(getColumnInt(col));
+ bool result = true;
+ if (m_database.lastError() != SQLITE_DONE) {
+ result = false;
+ LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
+ }
+ finalize();
+ return result;
+}
+
+bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v)
+{
+ v.clear();
+
+ if (m_statement)
+ finalize();
+ if (prepare() != SQLITE_OK)
+ return false;
+
+ while (step() == SQLITE_ROW)
+ v.append(getColumnInt64(col));
+ bool result = true;
+ if (m_database.lastError() != SQLITE_DONE) {
+ result = false;
+ LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
+ }
+ finalize();
+ return result;
+}
+
+bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v)
+{
+ v.clear();
+
+ if (m_statement)
+ finalize();
+ if (prepare() != SQLITE_OK)
+ return false;
+
+ while (step() == SQLITE_ROW)
+ v.append(getColumnDouble(col));
+ bool result = true;
+ if (m_database.lastError() != SQLITE_DONE) {
+ result = false;
+ LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
+ }
+ finalize();
+ return result;
+}
+
+bool SQLiteStatement::isExpired()
+{
+ return !m_statement || sqlite3_expired(m_statement);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/sql/SQLiteStatement.h b/WebCore/platform/sql/SQLiteStatement.h
new file mode 100644
index 0000000..5df4731
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteStatement.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SQLiteStatement_h
+#define SQLiteStatement_h
+
+#include "SQLiteDatabase.h"
+
+struct sqlite3_stmt;
+
+namespace WebCore {
+
+class SQLValue;
+
+class SQLiteStatement : public Noncopyable {
+public:
+ SQLiteStatement(SQLiteDatabase&, const String&);
+ ~SQLiteStatement();
+
+ int prepare();
+ int bindBlob(int index, const void* blob, int size);
+ int bindText(int index, const String&);
+ int bindInt64(int index, int64_t);
+ int bindDouble(int index, double);
+ int bindNull(int index);
+ int bindValue(int index, const SQLValue&);
+ unsigned bindParameterCount() const;
+
+ int step();
+ int finalize();
+ int reset();
+
+ int prepareAndStep() { if (int error = prepare()) return error; return step(); }
+
+ // prepares, steps, and finalizes the query.
+ // returns true if all 3 steps succeed with step() returning SQLITE_DONE
+ // returns false otherwise
+ bool executeCommand();
+
+ // prepares, steps, and finalizes.
+ // returns true is step() returns SQLITE_ROW
+ // returns false otherwise
+ bool returnsAtLeastOneResult();
+
+ bool isExpired();
+
+ // Returns -1 on last-step failing. Otherwise, returns number of rows
+ // returned in the last step()
+ int columnCount();
+
+ String getColumnName(int col);
+ SQLValue getColumnValue(int col);
+ String getColumnText(int col);
+ double getColumnDouble(int col);
+ int getColumnInt(int col);
+ int64_t getColumnInt64(int col);
+ const void* getColumnBlob(int col, int& size);
+ void getColumnBlobAsVector(int col, Vector<char>&);
+
+ bool returnTextResults(int col, Vector<String>&);
+ bool returnIntResults(int col, Vector<int>&);
+ bool returnInt64Results(int col, Vector<int64_t>&);
+ bool returnDoubleResults(int col, Vector<double>&);
+
+ SQLiteDatabase* database() { return &m_database; }
+
+private:
+ SQLiteDatabase& m_database;
+ String m_query;
+ sqlite3_stmt* m_statement;
+#ifndef NDEBUG
+ bool m_isPrepared;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // SQLiteStatement_h
diff --git a/WebCore/platform/sql/SQLiteTransaction.cpp b/WebCore/platform/sql/SQLiteTransaction.cpp
new file mode 100644
index 0000000..5018f5a
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteTransaction.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SQLiteTransaction.h"
+
+#include "SQLiteDatabase.h"
+
+namespace WebCore {
+
+SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db)
+ : m_db(db)
+ , m_inProgress(false)
+{
+}
+
+SQLiteTransaction::~SQLiteTransaction()
+{
+ if (m_inProgress)
+ rollback();
+}
+
+void SQLiteTransaction::begin()
+{
+ if (!m_inProgress) {
+ ASSERT(!m_db.m_transactionInProgress);
+ m_inProgress = m_db.executeCommand("BEGIN;");
+ m_db.m_transactionInProgress = true;
+ }
+}
+
+void SQLiteTransaction::commit()
+{
+ if (m_inProgress) {
+ ASSERT(m_db.m_transactionInProgress);
+ m_db.executeCommand("COMMIT;");
+ m_inProgress = false;
+ m_db.m_transactionInProgress = false;
+ }
+}
+
+void SQLiteTransaction::rollback()
+{
+ if (m_inProgress) {
+ ASSERT(m_db.m_transactionInProgress);
+ m_db.executeCommand("ROLLBACK;");
+ m_inProgress = false;
+ m_db.m_transactionInProgress = false;
+ }
+}
+
+void SQLiteTransaction::stop()
+{
+ m_inProgress = false;
+ m_db.m_transactionInProgress = false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/sql/SQLiteTransaction.h b/WebCore/platform/sql/SQLiteTransaction.h
new file mode 100644
index 0000000..cf5a180
--- /dev/null
+++ b/WebCore/platform/sql/SQLiteTransaction.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SQLiteTransaction_h
+#define SQLiteTransaction_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class SQLiteDatabase;
+
+class SQLiteTransaction : public Noncopyable
+{
+public:
+ SQLiteTransaction(SQLiteDatabase& db);
+ ~SQLiteTransaction();
+
+ void begin();
+ void commit();
+ void rollback();
+ void stop();
+
+ bool inProgress() const { return m_inProgress; }
+private:
+ SQLiteDatabase& m_db;
+ bool m_inProgress;
+
+};
+
+} // namespace WebCore
+
+#endif // SQLiteTransation_H
+