18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLStatement.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318ccf722629b08f2a06b2cadbdc3d0c9dc885e25dBen Murdoch#if ENABLE(DATABASE)
328ccf722629b08f2a06b2cadbdc3d0c9dc885e25dBen Murdoch
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Database.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Logging.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLError.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLiteDatabase.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLiteStatement.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLStatementCallback.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLStatementErrorCallback.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLTransaction.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SQLValue.h"
42f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/CString.h>
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
462bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassRefPtr<SQLStatement> SQLStatement::create(Database* database, const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> errorCallback, int permissions)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
482bde8e466a4451c7319e3a072d118917957d6554Steve Block    return adoptRef(new SQLStatement(database, statement, arguments, callback, errorCallback, permissions));
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
512bde8e466a4451c7319e3a072d118917957d6554Steve BlockSQLStatement::SQLStatement(Database* database, const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> errorCallback, int permissions)
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : m_statement(statement.crossThreadString())
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_arguments(arguments)
542bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_statementCallbackWrapper(callback, database->scriptExecutionContext())
552bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_statementErrorCallbackWrapper(errorCallback, database->scriptExecutionContext())
56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_permissions(permissions)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SQLStatement::execute(Database* db)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_resultSet);
63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we're re-running this statement after a quota violation, we need to clear that error now
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clearFailureDueToQuota();
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // This transaction might have been marked bad while it was being set up on the main thread,
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so if there is still an error, return false.
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_error)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    db->setAuthorizerPermissions(m_permissions);
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
74545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    SQLiteDatabase* database = &db->sqliteDatabase();
75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SQLiteStatement statement(*database, m_statement);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int result = statement.prepare();
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result != SQLResultOk) {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        LOG(StorageAPI, "Unable to verify correctness of statement %s - error %i (%s)", m_statement.ascii().data(), result, database->lastErrorMsg());
81db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        m_error = SQLError::create(result == SQLResultInterrupt ? SQLError::DATABASE_ERR : SQLError::SYNTAX_ERR, database->lastErrorMsg());
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME:  If the statement uses the ?### syntax supported by sqlite, the bind parameter count is very likely off from the number of question marks.
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If this is the case, they might be trying to do something fishy or malicious
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (statement.bindParameterCount() != m_arguments.size()) {
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        LOG(StorageAPI, "Bind parameter count doesn't match number of question marks");
89db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        m_error = SQLError::create(db->isInterrupted() ? SQLError::DATABASE_ERR : SQLError::SYNTAX_ERR, "number of '?'s in statement string does not match argument count");
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_arguments.size(); ++i) {
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = statement.bindValue(i + 1, m_arguments[i]);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result == SQLResultFull) {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setFailureDueToQuota();
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result != SQLResultOk) {
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG(StorageAPI, "Failed to bind value index %i to statement for query '%s'", i + 1, m_statement.ascii().data());
10206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            m_error = SQLError::create(SQLError::DATABASE_ERR, database->lastErrorMsg());
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<SQLResultSet> resultSet = SQLResultSet::create();
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Step so we can fetch the column names.
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = statement.step();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result == SQLResultRow) {
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int columnCount = statement.columnCount();
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SQLResultSetRowList* rows = resultSet->rows();
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < columnCount; i++)
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rows->addColumn(statement.getColumnName(i));
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < columnCount; i++)
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rows->addResult(statement.getColumnValue(i));
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = statement.step();
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (result == SQLResultRow);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result != SQLResultDone) {
12606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            m_error = SQLError::create(SQLError::DATABASE_ERR, database->lastErrorMsg());
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (result == SQLResultDone) {
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Didn't find anything, or was an insert
131545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (db->lastActionWasInsert())
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            resultSet->setInsertId(database->lastInsertRowID());
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (result == SQLResultFull) {
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Return the Quota error - the delegate will be asked for more space and this statement might be re-run
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setFailureDueToQuota();
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
13806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        m_error = SQLError::create(SQLError::DATABASE_ERR, database->lastErrorMsg());
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: If the spec allows triggers, and we want to be "accurate" in a different way, we'd use
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // sqlite3_total_changes() here instead of sqlite3_changed, because that includes rows modified from within a trigger
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // For now, this seems sufficient
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resultSet->setRowsAffected(database->lastChanges());
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_resultSet = resultSet;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SQLStatement::setDatabaseDeletedError()
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_error && !m_resultSet);
15406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_error = SQLError::create(SQLError::UNKNOWN_ERR, "unable to execute statement, because the user deleted the database");
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SQLStatement::setVersionMismatchedError()
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_error && !m_resultSet);
16006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_error = SQLError::create(SQLError::VERSION_ERR, "current version of the database and `oldVersion` argument do not match");
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SQLStatement::performCallback(SQLTransaction* transaction)
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(transaction);
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool callbackError = false;
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<SQLStatementCallback> callback = m_statementCallbackWrapper.unwrap();
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<SQLStatementErrorCallback> errorCallback = m_statementErrorCallbackWrapper.unwrap();
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Call the appropriate statement callback and track if it resulted in an error,
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // because then we need to jump to the transaction error callback.
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_error) {
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(errorCallback);
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block        callbackError = errorCallback->handleEvent(transaction, m_error.get());
1772bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (callback)
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block        callbackError = !callback->handleEvent(transaction, m_resultSet.get());
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return callbackError;
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SQLStatement::setFailureDueToQuota()
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_error && !m_resultSet);
18606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_error = SQLError::create(SQLError::QUOTA_ERR, "there was not enough remaining storage space, or the storage quota was reached and the user declined to allow more space");
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SQLStatement::clearFailureDueToQuota()
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastExecutionFailedDueToQuota())
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_error = 0;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SQLStatement::lastExecutionFailedDueToQuota() const
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
19706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return m_error && m_error->code() == SQLError::QUOTA_ERR;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
2018ccf722629b08f2a06b2cadbdc3d0c9dc885e25dBen Murdoch
2028ccf722629b08f2a06b2cadbdc3d0c9dc885e25dBen Murdoch#endif // ENABLE(DATABASE)
203