| 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 24 matching lines...) Expand all  Loading... | 
| 35 #include "modules/webdatabase/sqlite/SQLiteDatabase.h" | 35 #include "modules/webdatabase/sqlite/SQLiteDatabase.h" | 
| 36 #include "modules/webdatabase/sqlite/SQLiteStatement.h" | 36 #include "modules/webdatabase/sqlite/SQLiteStatement.h" | 
| 37 #include "wtf/text/CString.h" | 37 #include "wtf/text/CString.h" | 
| 38 | 38 | 
| 39 // The Life-Cycle of a SQLStatement i.e. Who's keeping the SQLStatement alive? | 39 // The Life-Cycle of a SQLStatement i.e. Who's keeping the SQLStatement alive? | 
| 40 // ========================================================================== | 40 // ========================================================================== | 
| 41 // The RefPtr chain goes something like this: | 41 // The RefPtr chain goes something like this: | 
| 42 // | 42 // | 
| 43 //     At birth (in SQLTransactionBackend::executeSQL()): | 43 //     At birth (in SQLTransactionBackend::executeSQL()): | 
| 44 //     ================================================= | 44 //     ================================================= | 
| 45 //     SQLTransactionBackend           // HeapDeque<Member<SQLStatementBackend>>
      m_statementQueue points to ... | 45 //     SQLTransactionBackend | 
| 46 //     --> SQLStatementBackend         // Member<SQLStatement> m_frontend points
      to ... | 46 //         // HeapDeque<Member<SQLStatementBackend>> m_statementQueue | 
| 47 //         --> SQLStatement | 47 //         // points to ... | 
|  | 48 //     --> SQLStatementBackend | 
|  | 49 //         // Member<SQLStatement> m_frontend points to ... | 
|  | 50 //     --> SQLStatement | 
| 48 // | 51 // | 
| 49 //     After grabbing the statement for execution (in SQLTransactionBackend::get
     NextStatement()): | 52 //     After grabbing the statement for execution (in | 
| 50 //     =========================================================================
     ================ | 53 //     SQLTransactionBackend::getNextStatement()): | 
| 51 //     SQLTransactionBackend           // Member<SQLStatementBackend> m_currentS
     tatementBackend points to ... | 54 //     ====================================================================== | 
| 52 //     --> SQLStatementBackend         // Member<SQLStatement> m_frontend points
      to ... | 55 //     SQLTransactionBackend | 
| 53 //         --> SQLStatement | 56 //         // Member<SQLStatementBackend> m_currentStatementBackend | 
|  | 57 //         // points to ... | 
|  | 58 //     --> SQLStatementBackend | 
|  | 59 //         // Member<SQLStatement> m_frontend points to ... | 
|  | 60 //     --> SQLStatement | 
| 54 // | 61 // | 
| 55 //     Then we execute the statement in SQLTransactionBackend::runCurrentStateme
     ntAndGetNextState(). | 62 //     Then we execute the statement in | 
| 56 //     And we callback to the script in SQLTransaction::deliverStatementCallback
     () if | 63 //     SQLTransactionBackend::runCurrentStatementAndGetNextState(). | 
| 57 //     necessary. | 64 //     And we callback to the script in | 
| 58 //     - Inside SQLTransaction::deliverStatementCallback(), we operate on a raw 
     SQLStatement*. | 65 //     SQLTransaction::deliverStatementCallback() if necessary. | 
| 59 //       This pointer is valid because it is owned by SQLTransactionBackend's | 66 //     - Inside SQLTransaction::deliverStatementCallback(), we operate on a raw | 
|  | 67 //       SQLStatement*.  This pointer is valid because it is owned by | 
|  | 68 //       SQLTransactionBackend's | 
| 60 //       SQLTransactionBackend::m_currentStatementBackend. | 69 //       SQLTransactionBackend::m_currentStatementBackend. | 
| 61 // | 70 // | 
| 62 //     After we're done executing the statement (in SQLTransactionBackend::getNe
     xtStatement()): | 71 //     After we're done executing the statement (in | 
| 63 //     =========================================================================
     ============== | 72 //     SQLTransactionBackend::getNextStatement()): | 
|  | 73 //     ====================================================================== | 
| 64 //     When we're done executing, we'll grab the next statement. But before we | 74 //     When we're done executing, we'll grab the next statement. But before we | 
| 65 //     do that, getNextStatement() nullify SQLTransactionBackend::m_currentState
     mentBackend. | 75 //     do that, getNextStatement() nullify | 
| 66 //     This will trigger the deletion of the SQLStatementBackend and SQLStatemen
     t. | 76 //     SQLTransactionBackend::m_currentStatementBackend. | 
|  | 77 //     This will trigger the deletion of the SQLStatementBackend and | 
|  | 78 //     SQLStatement. | 
| 67 // | 79 // | 
| 68 //     Note: unlike with SQLTransaction, there is no JS representation of SQLSta
     tement. | 80 //     Note: unlike with SQLTransaction, there is no JS representation of | 
| 69 //     Hence, there is no GC dependency at play here. | 81 //     SQLStatement.  Hence, there is no GC dependency at play here. | 
| 70 | 82 | 
| 71 namespace blink { | 83 namespace blink { | 
| 72 | 84 | 
| 73 SQLStatementBackend* SQLStatementBackend::create( | 85 SQLStatementBackend* SQLStatementBackend::create( | 
| 74     SQLStatement* frontend, | 86     SQLStatement* frontend, | 
| 75     const String& statement, | 87     const String& statement, | 
| 76     const Vector<SQLValue>& arguments, | 88     const Vector<SQLValue>& arguments, | 
| 77     int permissions) { | 89     int permissions) { | 
| 78   return new SQLStatementBackend(frontend, statement, arguments, permissions); | 90   return new SQLStatementBackend(frontend, statement, arguments, permissions); | 
| 79 } | 91 } | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 107   return m_error.get(); | 119   return m_error.get(); | 
| 108 } | 120 } | 
| 109 | 121 | 
| 110 SQLResultSet* SQLStatementBackend::sqlResultSet() const { | 122 SQLResultSet* SQLStatementBackend::sqlResultSet() const { | 
| 111   return m_resultSet->isValid() ? m_resultSet.get() : 0; | 123   return m_resultSet->isValid() ? m_resultSet.get() : 0; | 
| 112 } | 124 } | 
| 113 | 125 | 
| 114 bool SQLStatementBackend::execute(Database* db) { | 126 bool SQLStatementBackend::execute(Database* db) { | 
| 115   ASSERT(!m_resultSet->isValid()); | 127   ASSERT(!m_resultSet->isValid()); | 
| 116 | 128 | 
| 117   // If we're re-running this statement after a quota violation, we need to clea
     r that error now | 129   // If we're re-running this statement after a quota violation, we need to | 
|  | 130   // clear that error now | 
| 118   clearFailureDueToQuota(); | 131   clearFailureDueToQuota(); | 
| 119 | 132 | 
| 120   // This transaction might have been marked bad while it was being set up on th
     e main thread, | 133   // This transaction might have been marked bad while it was being set up on | 
| 121   // so if there is still an error, return false. | 134   // the main thread, so if there is still an error, return false. | 
| 122   if (m_error) | 135   if (m_error) | 
| 123     return false; | 136     return false; | 
| 124 | 137 | 
| 125   db->setAuthorizerPermissions(m_permissions); | 138   db->setAuthorizerPermissions(m_permissions); | 
| 126 | 139 | 
| 127   SQLiteDatabase* database = &db->sqliteDatabase(); | 140   SQLiteDatabase* database = &db->sqliteDatabase(); | 
| 128 | 141 | 
| 129   SQLiteStatement statement(*database, m_statement); | 142   SQLiteStatement statement(*database, m_statement); | 
| 130   int result = statement.prepare(); | 143   int result = statement.prepare(); | 
| 131 | 144 | 
| 132   if (result != SQLResultOk) { | 145   if (result != SQLResultOk) { | 
| 133     STORAGE_DVLOG(1) << "Unable to verify correctness of statement " | 146     STORAGE_DVLOG(1) << "Unable to verify correctness of statement " | 
| 134                      << m_statement << " - error " << result << " (" | 147                      << m_statement << " - error " << result << " (" | 
| 135                      << database->lastErrorMsg() << ")"; | 148                      << database->lastErrorMsg() << ")"; | 
| 136     if (result == SQLResultInterrupt) | 149     if (result == SQLResultInterrupt) | 
| 137       m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 150       m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 
| 138                                      "could not prepare statement", result, | 151                                      "could not prepare statement", result, | 
| 139                                      "interrupted"); | 152                                      "interrupted"); | 
| 140     else | 153     else | 
| 141       m_error = SQLErrorData::create(SQLError::kSyntaxErr, | 154       m_error = SQLErrorData::create(SQLError::kSyntaxErr, | 
| 142                                      "could not prepare statement", result, | 155                                      "could not prepare statement", result, | 
| 143                                      database->lastErrorMsg()); | 156                                      database->lastErrorMsg()); | 
| 144     db->reportExecuteStatementResult(1, m_error->code(), result); | 157     db->reportExecuteStatementResult(1, m_error->code(), result); | 
| 145     return false; | 158     return false; | 
| 146   } | 159   } | 
| 147 | 160 | 
| 148   // FIXME: If the statement uses the ?### syntax supported by sqlite, the bind 
     parameter count is very likely off from the number of question marks. | 161   // FIXME: If the statement uses the ?### syntax supported by sqlite, the bind | 
| 149   // If this is the case, they might be trying to do something fishy or maliciou
     s | 162   // parameter count is very likely off from the number of question marks.  If | 
|  | 163   // this is the case, they might be trying to do something fishy or malicious | 
| 150   if (statement.bindParameterCount() != m_arguments.size()) { | 164   if (statement.bindParameterCount() != m_arguments.size()) { | 
| 151     STORAGE_DVLOG(1) | 165     STORAGE_DVLOG(1) | 
| 152         << "Bind parameter count doesn't match number of question marks"; | 166         << "Bind parameter count doesn't match number of question marks"; | 
| 153     m_error = SQLErrorData::create( | 167     m_error = SQLErrorData::create( | 
| 154         SQLError::kSyntaxErr, | 168         SQLError::kSyntaxErr, | 
| 155         "number of '?'s in statement string does not match argument count"); | 169         "number of '?'s in statement string does not match argument count"); | 
| 156     db->reportExecuteStatementResult(2, m_error->code(), 0); | 170     db->reportExecuteStatementResult(2, m_error->code(), 0); | 
| 157     return false; | 171     return false; | 
| 158   } | 172   } | 
| 159 | 173 | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 196       m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 210       m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 
| 197                                      "could not iterate results", result, | 211                                      "could not iterate results", result, | 
| 198                                      database->lastErrorMsg()); | 212                                      database->lastErrorMsg()); | 
| 199       return false; | 213       return false; | 
| 200     } | 214     } | 
| 201   } else if (result == SQLResultDone) { | 215   } else if (result == SQLResultDone) { | 
| 202     // Didn't find anything, or was an insert | 216     // Didn't find anything, or was an insert | 
| 203     if (db->lastActionWasInsert()) | 217     if (db->lastActionWasInsert()) | 
| 204       m_resultSet->setInsertId(database->lastInsertRowID()); | 218       m_resultSet->setInsertId(database->lastInsertRowID()); | 
| 205   } else if (result == SQLResultFull) { | 219   } else if (result == SQLResultFull) { | 
| 206     // Return the Quota error - the delegate will be asked for more space and th
     is statement might be re-run | 220     // Return the Quota error - the delegate will be asked for more space and | 
|  | 221     // this statement might be re-run. | 
| 207     setFailureDueToQuota(db); | 222     setFailureDueToQuota(db); | 
| 208     return false; | 223     return false; | 
| 209   } else if (result == SQLResultConstraint) { | 224   } else if (result == SQLResultConstraint) { | 
| 210     db->reportExecuteStatementResult(6, SQLError::kConstraintErr, result); | 225     db->reportExecuteStatementResult(6, SQLError::kConstraintErr, result); | 
| 211     m_error = SQLErrorData::create( | 226     m_error = SQLErrorData::create( | 
| 212         SQLError::kConstraintErr, | 227         SQLError::kConstraintErr, | 
| 213         "could not execute statement due to a constaint failure", result, | 228         "could not execute statement due to a constaint failure", result, | 
| 214         database->lastErrorMsg()); | 229         database->lastErrorMsg()); | 
| 215     return false; | 230     return false; | 
| 216   } else { | 231   } else { | 
| 217     db->reportExecuteStatementResult(5, SQLError::kDatabaseErr, result); | 232     db->reportExecuteStatementResult(5, SQLError::kDatabaseErr, result); | 
| 218     m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 233     m_error = SQLErrorData::create(SQLError::kDatabaseErr, | 
| 219                                    "could not execute statement", result, | 234                                    "could not execute statement", result, | 
| 220                                    database->lastErrorMsg()); | 235                                    database->lastErrorMsg()); | 
| 221     return false; | 236     return false; | 
| 222   } | 237   } | 
| 223 | 238 | 
| 224   // FIXME: If the spec allows triggers, and we want to be "accurate" in a diffe
     rent way, we'd use | 239   // FIXME: If the spec allows triggers, and we want to be "accurate" in a | 
| 225   // sqlite3_total_changes() here instead of sqlite3_changed, because that inclu
     des rows modified from within a trigger | 240   // different way, we'd use sqlite3_total_changes() here instead of | 
| 226   // For now, this seems sufficient | 241   // sqlite3_changed, because that includes rows modified from within a trigger. | 
|  | 242   // For now, this seems sufficient. | 
| 227   m_resultSet->setRowsAffected(database->lastChanges()); | 243   m_resultSet->setRowsAffected(database->lastChanges()); | 
| 228 | 244 | 
| 229   db->reportExecuteStatementResult(0, -1, 0);  // OK | 245   db->reportExecuteStatementResult(0, -1, 0);  // OK | 
| 230   return true; | 246   return true; | 
| 231 } | 247 } | 
| 232 | 248 | 
| 233 void SQLStatementBackend::setVersionMismatchedError(Database* database) { | 249 void SQLStatementBackend::setVersionMismatchedError(Database* database) { | 
| 234   ASSERT(!m_error && !m_resultSet->isValid()); | 250   ASSERT(!m_error && !m_resultSet->isValid()); | 
| 235   database->reportExecuteStatementResult(7, SQLError::kVersionErr, 0); | 251   database->reportExecuteStatementResult(7, SQLError::kVersionErr, 0); | 
| 236   m_error = SQLErrorData::create( | 252   m_error = SQLErrorData::create( | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 250 void SQLStatementBackend::clearFailureDueToQuota() { | 266 void SQLStatementBackend::clearFailureDueToQuota() { | 
| 251   if (lastExecutionFailedDueToQuota()) | 267   if (lastExecutionFailedDueToQuota()) | 
| 252     m_error = nullptr; | 268     m_error = nullptr; | 
| 253 } | 269 } | 
| 254 | 270 | 
| 255 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const { | 271 bool SQLStatementBackend::lastExecutionFailedDueToQuota() const { | 
| 256   return m_error && m_error->code() == SQLError::kQuotaErr; | 272   return m_error && m_error->code() == SQLError::kQuotaErr; | 
| 257 } | 273 } | 
| 258 | 274 | 
| 259 }  // namespace blink | 275 }  // namespace blink | 
| OLD | NEW | 
|---|