1967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch/*
2967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) 2007 Apple Inc. All rights reserved.
3967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) 2010 Google Inc. All rights reserved.
4967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *
5967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Redistribution and use in source and binary forms, with or without
6967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * modification, are permitted provided that the following conditions
7967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * are met:
8967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *
9967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * 1.  Redistributions of source code must retain the above copyright
10967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *     notice, this list of conditions and the following disclaimer.
11967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
12967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *     notice, this list of conditions and the following disclaimer in the
13967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *     documentation and/or other materials provided with the distribution.
14967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *     its contributors may be used to endorse or promote products derived
16967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *     from this software without specific prior written permission.
17967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch *
18967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch */
29967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
30967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "config.h"
31967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLStatementSync.h"
32967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
33967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(DATABASE)
34967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
35967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "DatabaseSync.h"
36967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLException.h"
37967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLResultSet.h"
38967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLValue.h"
39967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLiteDatabase.h"
40967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "SQLiteStatement.h"
41967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include <wtf/PassRefPtr.h>
42967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include <wtf/RefPtr.h>
43967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
44967717af5423377c967781471ee106e2bb4e11c8Ben Murdochnamespace WebCore {
45967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
46f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSQLStatementSync::SQLStatementSync(const String& statement, const Vector<SQLValue>& arguments, int permissions)
47967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    : m_statement(statement)
48967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    , m_arguments(arguments)
49f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_permissions(permissions)
50967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
51967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(!m_statement.isEmpty());
52967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
53967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
54967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<SQLResultSet> SQLStatementSync::execute(DatabaseSync* db, ExceptionCode& ec)
55967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    db->setAuthorizerPermissions(m_permissions);
57967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
58967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    SQLiteDatabase* database = &db->sqliteDatabase();
59967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
60967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    SQLiteStatement statement(*database, m_statement);
61967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    int result = statement.prepare();
62967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (result != SQLResultOk) {
63db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        ec = (result == SQLResultInterrupt ? SQLException::DATABASE_ERR : SQLException::SYNTAX_ERR);
64967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
65967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
66967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
67967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (statement.bindParameterCount() != m_arguments.size()) {
68db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        ec = (db->isInterrupted()? SQLException::DATABASE_ERR : SQLException::SYNTAX_ERR);
69967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
70967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
71967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
72967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    for (unsigned i = 0; i < m_arguments.size(); ++i) {
73967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        result = statement.bindValue(i + 1, m_arguments[i]);
74967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (result == SQLResultFull) {
75967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            ec = SQLException::QUOTA_ERR;
76967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            return 0;
77967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        }
78967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
79967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (result != SQLResultOk) {
80967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            ec = SQLException::DATABASE_ERR;
81967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            return 0;
82967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        }
83967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
84967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
85967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    RefPtr<SQLResultSet> resultSet = SQLResultSet::create();
86967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
87967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // Step so we can fetch the column names.
88967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    result = statement.step();
89967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (result == SQLResultRow) {
90967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        int columnCount = statement.columnCount();
91967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        SQLResultSetRowList* rows = resultSet->rows();
92967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
93967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        for (int i = 0; i < columnCount; i++)
94967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            rows->addColumn(statement.getColumnName(i));
95967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
96967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        do {
97967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            for (int i = 0; i < columnCount; i++)
98967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch                rows->addResult(statement.getColumnValue(i));
99967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
100967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            result = statement.step();
101967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        } while (result == SQLResultRow);
102967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
103967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (result != SQLResultDone) {
104967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            ec = SQLException::DATABASE_ERR;
105967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            return 0;
106967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        }
107967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    } else if (result == SQLResultDone) {
108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // Didn't find anything, or was an insert.
109967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (db->lastActionWasInsert())
110967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            resultSet->setInsertId(database->lastInsertRowID());
111967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    } else if (result == SQLResultFull) {
112967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // Quota error, the delegate will be asked for more space and this statement might be re-run.
113967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ec = SQLException::QUOTA_ERR;
114967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
115967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    } else {
116967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ec = SQLException::DATABASE_ERR;
117967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
118967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
119967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
120967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    resultSet->setRowsAffected(database->lastChanges());
121967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return resultSet.release();
122967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
123967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
124967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} // namespace WebCore
125967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
126967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif // ENABLE(DATABASE)
127