Chromium Code Reviews| 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; | 210 m_resultSet->setValid(); |
|
haraken
2014/03/25 07:55:30
In my understanding, setValid() should be always c
tkent
2014/03/25 08:40:32
Right. Done.
| |
| 211 db->reportExecuteStatementResult(0, -1, 0); // OK | 211 db->reportExecuteStatementResult(0, -1, 0); // OK |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 void SQLStatementBackend::setVersionMismatchedError(DatabaseBackend* database) | 215 void SQLStatementBackend::setVersionMismatchedError(DatabaseBackend* database) |
| 216 { | 216 { |
| 217 ASSERT(!m_error && !m_resultSet); | 217 ASSERT(!m_error && !m_resultSet->isValid()); |
| 218 database->reportExecuteStatementResult(7, SQLError::VERSION_ERR, 0); | 218 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"); | 219 m_error = SQLError::create(SQLError::VERSION_ERR, "current version of the da tabase and `oldVersion` argument do not match"); |
| 220 } | 220 } |
| 221 | 221 |
| 222 void SQLStatementBackend::setFailureDueToQuota(DatabaseBackend* database) | 222 void SQLStatementBackend::setFailureDueToQuota(DatabaseBackend* database) |
| 223 { | 223 { |
| 224 ASSERT(!m_error && !m_resultSet); | 224 ASSERT(!m_error && !m_resultSet->isValid()); |
| 225 database->reportExecuteStatementResult(8, SQLError::QUOTA_ERR, 0); | 225 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"); | 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"); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void SQLStatementBackend::clearFailureDueToQuota() | 229 void SQLStatementBackend::clearFailureDueToQuota() |
| 230 { | 230 { |
| 231 if (lastExecutionFailedDueToQuota()) | 231 if (lastExecutionFailedDueToQuota()) |
| 232 m_error = nullptr; | 232 m_error = nullptr; |
| 233 } | 233 } |
| 234 | 234 |
| 235 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const | 235 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const |
| 236 { | 236 { |
| 237 return m_error && m_error->code() == SQLError::QUOTA_ERR; | 237 return m_error && m_error->code() == SQLError::QUOTA_ERR; |
| 238 } | 238 } |
| 239 | 239 |
| 240 } // namespace WebCore | 240 } // namespace WebCore |
| OLD | NEW |