OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 return adoptRefWillBeNoop(new SQLStatementBackend(frontend, statement, argum
ents, permissions)); | 77 return adoptRefWillBeNoop(new SQLStatementBackend(frontend, statement, argum
ents, permissions)); |
78 } | 78 } |
79 | 79 |
80 SQLStatementBackend::SQLStatementBackend(PassOwnPtr<AbstractSQLStatement> fronte
nd, | 80 SQLStatementBackend::SQLStatementBackend(PassOwnPtr<AbstractSQLStatement> fronte
nd, |
81 const String& statement, const Vector<SQLValue>& arguments, int permissions) | 81 const String& statement, const Vector<SQLValue>& arguments, int permissions) |
82 : m_frontend(frontend) | 82 : m_frontend(frontend) |
83 , m_statement(statement.isolatedCopy()) | 83 , m_statement(statement.isolatedCopy()) |
84 , m_arguments(arguments) | 84 , m_arguments(arguments) |
85 , m_hasCallback(m_frontend->hasCallback()) | 85 , m_hasCallback(m_frontend->hasCallback()) |
86 , m_hasErrorCallback(m_frontend->hasErrorCallback()) | 86 , m_hasErrorCallback(m_frontend->hasErrorCallback()) |
| 87 , m_resultSet(SQLResultSet::create()) |
87 , m_permissions(permissions) | 88 , m_permissions(permissions) |
88 { | 89 { |
89 m_frontend->setBackend(this); | 90 m_frontend->setBackend(this); |
90 } | 91 } |
91 | 92 |
92 void SQLStatementBackend::trace(Visitor*) | 93 void SQLStatementBackend::trace(Visitor* visitor) |
93 { | 94 { |
| 95 visitor->trace(m_resultSet); |
94 } | 96 } |
95 | 97 |
96 AbstractSQLStatement* SQLStatementBackend::frontend() | 98 AbstractSQLStatement* SQLStatementBackend::frontend() |
97 { | 99 { |
98 return m_frontend.get(); | 100 return m_frontend.get(); |
99 } | 101 } |
100 | 102 |
101 PassRefPtr<SQLError> SQLStatementBackend::sqlError() const | 103 PassRefPtr<SQLError> SQLStatementBackend::sqlError() const |
102 { | 104 { |
103 return m_error; | 105 return m_error; |
104 } | 106 } |
105 | 107 |
106 PassRefPtr<SQLResultSet> SQLStatementBackend::sqlResultSet() const | 108 SQLResultSet* SQLStatementBackend::sqlResultSet() const |
107 { | 109 { |
108 return m_resultSet; | 110 return m_resultSet->isValid() ? m_resultSet.get() : 0; |
109 } | 111 } |
110 | 112 |
111 bool SQLStatementBackend::execute(DatabaseBackend* db) | 113 bool SQLStatementBackend::execute(DatabaseBackend* db) |
112 { | 114 { |
113 ASSERT(!m_resultSet); | 115 ASSERT(!m_resultSet->isValid()); |
114 | 116 |
115 // If we're re-running this statement after a quota violation, we need to cl
ear that error now | 117 // If we're re-running this statement after a quota violation, we need to cl
ear that error now |
116 clearFailureDueToQuota(); | 118 clearFailureDueToQuota(); |
117 | 119 |
118 // This transaction might have been marked bad while it was being set up on
the main thread, | 120 // This transaction might have been marked bad while it was being set up on
the main thread, |
119 // so if there is still an error, return false. | 121 // so if there is still an error, return false. |
120 if (m_error) | 122 if (m_error) |
121 return false; | 123 return false; |
122 | 124 |
123 db->setAuthorizerPermissions(m_permissions); | 125 db->setAuthorizerPermissions(m_permissions); |
(...skipping 30 matching lines...) Expand all Loading... |
154 } | 156 } |
155 | 157 |
156 if (result != SQLResultOk) { | 158 if (result != SQLResultOk) { |
157 WTF_LOG(StorageAPI, "Failed to bind value index %i to statement for
query '%s'", i + 1, m_statement.ascii().data()); | 159 WTF_LOG(StorageAPI, "Failed to bind value index %i to statement for
query '%s'", i + 1, m_statement.ascii().data()); |
158 db->reportExecuteStatementResult(3, SQLError::DATABASE_ERR, result); | 160 db->reportExecuteStatementResult(3, SQLError::DATABASE_ERR, result); |
159 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not bind v
alue", result, database->lastErrorMsg()); | 161 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not bind v
alue", result, database->lastErrorMsg()); |
160 return false; | 162 return false; |
161 } | 163 } |
162 } | 164 } |
163 | 165 |
164 RefPtr<SQLResultSet> resultSet = SQLResultSet::create(); | |
165 | |
166 // Step so we can fetch the column names. | 166 // Step so we can fetch the column names. |
167 result = statement.step(); | 167 result = statement.step(); |
168 if (result == SQLResultRow) { | 168 if (result == SQLResultRow) { |
169 int columnCount = statement.columnCount(); | 169 int columnCount = statement.columnCount(); |
170 SQLResultSetRowList* rows = resultSet->rows(); | 170 SQLResultSetRowList* rows = m_resultSet->rows(); |
171 | 171 |
172 for (int i = 0; i < columnCount; i++) | 172 for (int i = 0; i < columnCount; i++) |
173 rows->addColumn(statement.getColumnName(i)); | 173 rows->addColumn(statement.getColumnName(i)); |
174 | 174 |
175 do { | 175 do { |
176 for (int i = 0; i < columnCount; i++) | 176 for (int i = 0; i < columnCount; i++) |
177 rows->addResult(statement.getColumnValue(i)); | 177 rows->addResult(statement.getColumnValue(i)); |
178 | 178 |
179 result = statement.step(); | 179 result = statement.step(); |
180 } while (result == SQLResultRow); | 180 } while (result == SQLResultRow); |
181 | 181 |
182 if (result != SQLResultDone) { | 182 if (result != SQLResultDone) { |
183 db->reportExecuteStatementResult(4, SQLError::DATABASE_ERR, result); | 183 db->reportExecuteStatementResult(4, SQLError::DATABASE_ERR, result); |
184 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not iterat
e results", result, database->lastErrorMsg()); | 184 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not iterat
e results", result, database->lastErrorMsg()); |
185 return false; | 185 return false; |
186 } | 186 } |
187 } else if (result == SQLResultDone) { | 187 } else if (result == SQLResultDone) { |
188 // Didn't find anything, or was an insert | 188 // Didn't find anything, or was an insert |
189 if (db->lastActionWasInsert()) | 189 if (db->lastActionWasInsert()) |
190 resultSet->setInsertId(database->lastInsertRowID()); | 190 m_resultSet->setInsertId(database->lastInsertRowID()); |
191 } else if (result == SQLResultFull) { | 191 } else if (result == SQLResultFull) { |
192 // Return the Quota error - the delegate will be asked for more space an
d this statement might be re-run | 192 // Return the Quota error - the delegate will be asked for more space an
d this statement might be re-run |
193 setFailureDueToQuota(db); | 193 setFailureDueToQuota(db); |
194 return false; | 194 return false; |
195 } else if (result == SQLResultConstraint) { | 195 } else if (result == SQLResultConstraint) { |
196 db->reportExecuteStatementResult(6, SQLError::CONSTRAINT_ERR, result); | 196 db->reportExecuteStatementResult(6, SQLError::CONSTRAINT_ERR, result); |
197 m_error = SQLError::create(SQLError::CONSTRAINT_ERR, "could not execute
statement due to a constaint failure", result, database->lastErrorMsg()); | 197 m_error = SQLError::create(SQLError::CONSTRAINT_ERR, "could not execute
statement due to a constaint failure", result, database->lastErrorMsg()); |
198 return false; | 198 return false; |
199 } else { | 199 } else { |
200 db->reportExecuteStatementResult(5, SQLError::DATABASE_ERR, result); | 200 db->reportExecuteStatementResult(5, SQLError::DATABASE_ERR, result); |
201 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not execute st
atement", result, database->lastErrorMsg()); | 201 m_error = SQLError::create(SQLError::DATABASE_ERR, "could not execute st
atement", result, database->lastErrorMsg()); |
202 return false; | 202 return false; |
203 } | 203 } |
204 | 204 |
205 // FIXME: If the spec allows triggers, and we want to be "accurate" in a dif
ferent way, we'd use | 205 // FIXME: If the spec allows triggers, and we want to be "accurate" in a dif
ferent way, we'd use |
206 // sqlite3_total_changes() here instead of sqlite3_changed, because that inc
ludes rows modified from within a trigger | 206 // sqlite3_total_changes() here instead of sqlite3_changed, because that inc
ludes rows modified from within a trigger |
207 // For now, this seems sufficient | 207 // For now, this seems sufficient |
208 resultSet->setRowsAffected(database->lastChanges()); | 208 m_resultSet->setRowsAffected(database->lastChanges()); |
209 | 209 |
210 m_resultSet = resultSet; | |
211 db->reportExecuteStatementResult(0, -1, 0); // OK | 210 db->reportExecuteStatementResult(0, -1, 0); // OK |
212 return true; | 211 return true; |
213 } | 212 } |
214 | 213 |
215 void SQLStatementBackend::setVersionMismatchedError(DatabaseBackend* database) | 214 void SQLStatementBackend::setVersionMismatchedError(DatabaseBackend* database) |
216 { | 215 { |
217 ASSERT(!m_error && !m_resultSet); | 216 ASSERT(!m_error && !m_resultSet->isValid()); |
218 database->reportExecuteStatementResult(7, SQLError::VERSION_ERR, 0); | 217 database->reportExecuteStatementResult(7, SQLError::VERSION_ERR, 0); |
219 m_error = SQLError::create(SQLError::VERSION_ERR, "current version of the da
tabase and `oldVersion` argument do not match"); | 218 m_error = SQLError::create(SQLError::VERSION_ERR, "current version of the da
tabase and `oldVersion` argument do not match"); |
220 } | 219 } |
221 | 220 |
222 void SQLStatementBackend::setFailureDueToQuota(DatabaseBackend* database) | 221 void SQLStatementBackend::setFailureDueToQuota(DatabaseBackend* database) |
223 { | 222 { |
224 ASSERT(!m_error && !m_resultSet); | 223 ASSERT(!m_error && !m_resultSet->isValid()); |
225 database->reportExecuteStatementResult(8, SQLError::QUOTA_ERR, 0); | 224 database->reportExecuteStatementResult(8, SQLError::QUOTA_ERR, 0); |
226 m_error = SQLError::create(SQLError::QUOTA_ERR, "there was not enough remain
ing storage space, or the storage quota was reached and the user declined to all
ow more space"); | 225 m_error = SQLError::create(SQLError::QUOTA_ERR, "there was not enough remain
ing storage space, or the storage quota was reached and the user declined to all
ow more space"); |
227 } | 226 } |
228 | 227 |
229 void SQLStatementBackend::clearFailureDueToQuota() | 228 void SQLStatementBackend::clearFailureDueToQuota() |
230 { | 229 { |
231 if (lastExecutionFailedDueToQuota()) | 230 if (lastExecutionFailedDueToQuota()) |
232 m_error = nullptr; | 231 m_error = nullptr; |
233 } | 232 } |
234 | 233 |
235 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const | 234 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const |
236 { | 235 { |
237 return m_error && m_error->code() == SQLError::QUOTA_ERR; | 236 return m_error && m_error->code() == SQLError::QUOTA_ERR; |
238 } | 237 } |
239 | 238 |
240 } // namespace WebCore | 239 } // namespace WebCore |
OLD | NEW |