~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/Modules/webdatabase/SQLStatementSync.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007 Apple Inc. All rights reserved.
 
3
 * Copyright (C) 2010 Google Inc. All rights reserved.
 
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
 *
 
9
 * 1.  Redistributions of source code must retain the above copyright
 
10
 *     notice, this list of conditions and the following disclaimer.
 
11
 * 2.  Redistributions in binary form must reproduce the above copyright
 
12
 *     notice, this list of conditions and the following disclaimer in the
 
13
 *     documentation and/or other materials provided with the distribution.
 
14
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 
15
 *     its contributors may be used to endorse or promote products derived
 
16
 *     from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#include "config.h"
 
31
#include "SQLStatementSync.h"
 
32
 
 
33
#if ENABLE(SQL_DATABASE)
 
34
 
 
35
#include "DatabaseSync.h"
 
36
#include "SQLException.h"
 
37
#include "SQLResultSet.h"
 
38
#include "SQLValue.h"
 
39
#include "SQLiteDatabase.h"
 
40
#include "SQLiteStatement.h"
 
41
#include <wtf/PassRefPtr.h>
 
42
#include <wtf/RefPtr.h>
 
43
 
 
44
namespace WebCore {
 
45
 
 
46
SQLStatementSync::SQLStatementSync(const String& statement, const Vector<SQLValue>& arguments, int permissions)
 
47
    : m_statement(statement)
 
48
    , m_arguments(arguments)
 
49
    , m_permissions(permissions)
 
50
{
 
51
    ASSERT(!m_statement.isEmpty());
 
52
}
 
53
 
 
54
PassRefPtr<SQLResultSet> SQLStatementSync::execute(DatabaseSync* db, ExceptionCode& ec)
 
55
{
 
56
    db->setAuthorizerPermissions(m_permissions);
 
57
 
 
58
    SQLiteDatabase* database = &db->sqliteDatabase();
 
59
 
 
60
    SQLiteStatement statement(*database, m_statement);
 
61
    int result = statement.prepare();
 
62
    if (result != SQLResultOk) {
 
63
        ec = (result == SQLResultInterrupt ? SQLException::DATABASE_ERR : SQLException::SYNTAX_ERR);
 
64
        db->setLastErrorMessage("could not prepare statement", result, database->lastErrorMsg());
 
65
        return 0;
 
66
    }
 
67
 
 
68
    if (statement.bindParameterCount() != m_arguments.size()) {
 
69
        ec = (db->isInterrupted()? SQLException::DATABASE_ERR : SQLException::SYNTAX_ERR);
 
70
        db->setLastErrorMessage("number of '?'s in statement string does not match argument count");
 
71
        return 0;
 
72
    }
 
73
 
 
74
    for (unsigned i = 0; i < m_arguments.size(); ++i) {
 
75
        result = statement.bindValue(i + 1, m_arguments[i]);
 
76
        if (result == SQLResultFull) {
 
77
            ec = SQLException::QUOTA_ERR;
 
78
            db->setLastErrorMessage("there was not enough remaining storage space");
 
79
            return 0;
 
80
        }
 
81
 
 
82
        if (result != SQLResultOk) {
 
83
            ec = SQLException::DATABASE_ERR;
 
84
            db->setLastErrorMessage("could not bind value", result, database->lastErrorMsg());
 
85
            return 0;
 
86
        }
 
87
    }
 
88
 
 
89
    RefPtr<SQLResultSet> resultSet = SQLResultSet::create();
 
90
 
 
91
    // Step so we can fetch the column names.
 
92
    result = statement.step();
 
93
    if (result == SQLResultRow) {
 
94
        int columnCount = statement.columnCount();
 
95
        SQLResultSetRowList* rows = resultSet->rows();
 
96
 
 
97
        for (int i = 0; i < columnCount; i++)
 
98
            rows->addColumn(statement.getColumnName(i));
 
99
 
 
100
        do {
 
101
            for (int i = 0; i < columnCount; i++)
 
102
                rows->addResult(statement.getColumnValue(i));
 
103
 
 
104
            result = statement.step();
 
105
        } while (result == SQLResultRow);
 
106
 
 
107
        if (result != SQLResultDone) {
 
108
            ec = SQLException::DATABASE_ERR;
 
109
            db->setLastErrorMessage("could not iterate results", result, database->lastErrorMsg());
 
110
            return 0;
 
111
        }
 
112
    } else if (result == SQLResultDone) {
 
113
        // Didn't find anything, or was an insert.
 
114
        if (db->lastActionWasInsert())
 
115
            resultSet->setInsertId(database->lastInsertRowID());
 
116
    } else if (result == SQLResultFull) {
 
117
        // Quota error, the delegate will be asked for more space and this statement might be re-run.
 
118
        ec = SQLException::QUOTA_ERR;
 
119
        db->setLastErrorMessage("there was not enough remaining storage space");
 
120
        return 0;
 
121
    } else if (result == SQLResultConstraint) {
 
122
        ec = SQLException::CONSTRAINT_ERR;
 
123
        db->setLastErrorMessage("statement failed due to a constraint failure");
 
124
        return 0;
 
125
    } else {
 
126
        ec = SQLException::DATABASE_ERR;
 
127
        db->setLastErrorMessage("could not execute statement", result, database->lastErrorMsg());
 
128
        return 0;
 
129
    }
 
130
 
 
131
    resultSet->setRowsAffected(database->lastChanges());
 
132
    return resultSet.release();
 
133
}
 
134
 
 
135
} // namespace WebCore
 
136
 
 
137
#endif // ENABLE(SQL_DATABASE)