| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 /* |  | 
| 2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |  | 
| 3  * |  | 
| 4  * Redistribution and use in source and binary forms, with or without |  | 
| 5  * modification, are permitted provided that the following conditions |  | 
| 6  * are met: |  | 
| 7  * 1. Redistributions of source code must retain the above copyright |  | 
| 8  *    notice, this list of conditions and the following disclaimer. |  | 
| 9  * 2. Redistributions in binary form must reproduce the above copyright |  | 
| 10  *    notice, this list of conditions and the following disclaimer in the |  | 
| 11  *    documentation and/or other materials provided with the distribution. |  | 
| 12  * |  | 
| 13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |  | 
| 14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | 
| 15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |  | 
| 16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR |  | 
| 17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |  | 
| 18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |  | 
| 19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |  | 
| 20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |  | 
| 21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | 
| 22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | 
| 23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | 
| 24  */ |  | 
| 25 |  | 
| 26 #include "config.h" |  | 
| 27 #include "core/platform/sql/SQLiteStatement.h" |  | 
| 28 |  | 
| 29 #include <sqlite3.h> |  | 
| 30 #include "platform/Logging.h" |  | 
| 31 #include "core/platform/sql/SQLValue.h" |  | 
| 32 #include "wtf/Assertions.h" |  | 
| 33 #include "wtf/text/CString.h" |  | 
| 34 |  | 
| 35 // SQLite 3.6.16 makes sqlite3_prepare_v2 automatically retry preparing the stat
     ement |  | 
| 36 // once if the database scheme has changed. We rely on this behavior. |  | 
| 37 #if SQLITE_VERSION_NUMBER < 3006016 |  | 
| 38 #error SQLite version 3.6.16 or newer is required |  | 
| 39 #endif |  | 
| 40 |  | 
| 41 namespace WebCore { |  | 
| 42 |  | 
| 43 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql) |  | 
| 44     : m_database(db) |  | 
| 45     , m_query(sql) |  | 
| 46     , m_statement(0) |  | 
| 47 #ifndef NDEBUG |  | 
| 48     , m_isPrepared(false) |  | 
| 49 #endif |  | 
| 50 { |  | 
| 51 } |  | 
| 52 |  | 
| 53 SQLiteStatement::~SQLiteStatement() |  | 
| 54 { |  | 
| 55     finalize(); |  | 
| 56 } |  | 
| 57 |  | 
| 58 int SQLiteStatement::prepare() |  | 
| 59 { |  | 
| 60     ASSERT(!m_isPrepared); |  | 
| 61 |  | 
| 62     MutexLocker databaseLock(m_database.databaseMutex()); |  | 
| 63     if (m_database.isInterrupted()) |  | 
| 64         return SQLITE_INTERRUPT; |  | 
| 65 |  | 
| 66     CString query = m_query.stripWhiteSpace().utf8(); |  | 
| 67 |  | 
| 68     LOG(SQLDatabase, "SQL - prepare - %s", query.data()); |  | 
| 69 |  | 
| 70     // Pass the length of the string including the null character to sqlite3_pre
     pare_v2; |  | 
| 71     // this lets SQLite avoid an extra string copy. |  | 
| 72     size_t lengthIncludingNullCharacter = query.length() + 1; |  | 
| 73 |  | 
| 74     const char* tail; |  | 
| 75     int error = sqlite3_prepare_v2(m_database.sqlite3Handle(), query.data(), len
     gthIncludingNullCharacter, &m_statement, &tail); |  | 
| 76 |  | 
| 77     if (error != SQLITE_OK) |  | 
| 78         LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.d
     ata(), sqlite3_errmsg(m_database.sqlite3Handle())); |  | 
| 79 |  | 
| 80     if (tail && *tail) |  | 
| 81         error = SQLITE_ERROR; |  | 
| 82 |  | 
| 83 #ifndef NDEBUG |  | 
| 84     m_isPrepared = error == SQLITE_OK; |  | 
| 85 #endif |  | 
| 86     return error; |  | 
| 87 } |  | 
| 88 |  | 
| 89 int SQLiteStatement::step() |  | 
| 90 { |  | 
| 91     MutexLocker databaseLock(m_database.databaseMutex()); |  | 
| 92     if (m_database.isInterrupted()) |  | 
| 93         return SQLITE_INTERRUPT; |  | 
| 94     //ASSERT(m_isPrepared); |  | 
| 95 |  | 
| 96     if (!m_statement) |  | 
| 97         return SQLITE_OK; |  | 
| 98 |  | 
| 99     // The database needs to update its last changes count before each statement |  | 
| 100     // in order to compute properly the lastChanges() return value. |  | 
| 101     m_database.updateLastChangesCount(); |  | 
| 102 |  | 
| 103     LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data()); |  | 
| 104     int error = sqlite3_step(m_statement); |  | 
| 105     if (error != SQLITE_DONE && error != SQLITE_ROW) { |  | 
| 106         LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s", |  | 
| 107             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Hand
     le())); |  | 
| 108     } |  | 
| 109 |  | 
| 110     return error; |  | 
| 111 } |  | 
| 112 |  | 
| 113 int SQLiteStatement::finalize() |  | 
| 114 { |  | 
| 115 #ifndef NDEBUG |  | 
| 116     m_isPrepared = false; |  | 
| 117 #endif |  | 
| 118     if (!m_statement) |  | 
| 119         return SQLITE_OK; |  | 
| 120     LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data()); |  | 
| 121     int result = sqlite3_finalize(m_statement); |  | 
| 122     m_statement = 0; |  | 
| 123     return result; |  | 
| 124 } |  | 
| 125 |  | 
| 126 int SQLiteStatement::reset() |  | 
| 127 { |  | 
| 128     ASSERT(m_isPrepared); |  | 
| 129     if (!m_statement) |  | 
| 130         return SQLITE_OK; |  | 
| 131     LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data()); |  | 
| 132     return sqlite3_reset(m_statement); |  | 
| 133 } |  | 
| 134 |  | 
| 135 bool SQLiteStatement::executeCommand() |  | 
| 136 { |  | 
| 137     if (!m_statement && prepare() != SQLITE_OK) |  | 
| 138         return false; |  | 
| 139     ASSERT(m_isPrepared); |  | 
| 140     if (step() != SQLITE_DONE) { |  | 
| 141         finalize(); |  | 
| 142         return false; |  | 
| 143     } |  | 
| 144     finalize(); |  | 
| 145     return true; |  | 
| 146 } |  | 
| 147 |  | 
| 148 bool SQLiteStatement::returnsAtLeastOneResult() |  | 
| 149 { |  | 
| 150     if (!m_statement && prepare() != SQLITE_OK) |  | 
| 151         return false; |  | 
| 152     ASSERT(m_isPrepared); |  | 
| 153     if (step() != SQLITE_ROW) { |  | 
| 154         finalize(); |  | 
| 155         return false; |  | 
| 156     } |  | 
| 157     finalize(); |  | 
| 158     return true; |  | 
| 159 |  | 
| 160 } |  | 
| 161 |  | 
| 162 int SQLiteStatement::bindBlob(int index, const void* blob, int size) |  | 
| 163 { |  | 
| 164     ASSERT(m_isPrepared); |  | 
| 165     ASSERT(index > 0); |  | 
| 166     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 167     ASSERT(blob); |  | 
| 168     ASSERT(size >= 0); |  | 
| 169 |  | 
| 170     if (!m_statement) |  | 
| 171         return SQLITE_ERROR; |  | 
| 172 |  | 
| 173     return sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT); |  | 
| 174 } |  | 
| 175 |  | 
| 176 int SQLiteStatement::bindBlob(int index, const String& text) |  | 
| 177 { |  | 
| 178     // SQLite treats uses zero pointers to represent null strings, which means w
     e need to make sure to map null WTFStrings to zero pointers. |  | 
| 179     ASSERT(!String().charactersWithNullTermination().data()); |  | 
| 180     return bindBlob(index, text.charactersWithNullTermination().data(), text.len
     gth() * sizeof(UChar)); |  | 
| 181 } |  | 
| 182 |  | 
| 183 int SQLiteStatement::bindText(int index, const String& text) |  | 
| 184 { |  | 
| 185     ASSERT(m_isPrepared); |  | 
| 186     ASSERT(index > 0); |  | 
| 187     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 188 |  | 
| 189     // SQLite treats uses zero pointers to represent null strings, which means w
     e need to make sure to map null WTFStrings to zero pointers. |  | 
| 190     ASSERT(!String().charactersWithNullTermination().data()); |  | 
| 191     return sqlite3_bind_text16(m_statement, index, text.charactersWithNullTermin
     ation().data(), sizeof(UChar) * text.length(), SQLITE_TRANSIENT); |  | 
| 192 } |  | 
| 193 |  | 
| 194 int SQLiteStatement::bindInt(int index, int integer) |  | 
| 195 { |  | 
| 196     ASSERT(m_isPrepared); |  | 
| 197     ASSERT(index > 0); |  | 
| 198     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 199 |  | 
| 200     return sqlite3_bind_int(m_statement, index, integer); |  | 
| 201 } |  | 
| 202 |  | 
| 203 int SQLiteStatement::bindInt64(int index, int64_t integer) |  | 
| 204 { |  | 
| 205     ASSERT(m_isPrepared); |  | 
| 206     ASSERT(index > 0); |  | 
| 207     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 208 |  | 
| 209     return sqlite3_bind_int64(m_statement, index, integer); |  | 
| 210 } |  | 
| 211 |  | 
| 212 int SQLiteStatement::bindDouble(int index, double number) |  | 
| 213 { |  | 
| 214     ASSERT(m_isPrepared); |  | 
| 215     ASSERT(index > 0); |  | 
| 216     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 217 |  | 
| 218     return sqlite3_bind_double(m_statement, index, number); |  | 
| 219 } |  | 
| 220 |  | 
| 221 int SQLiteStatement::bindNull(int index) |  | 
| 222 { |  | 
| 223     ASSERT(m_isPrepared); |  | 
| 224     ASSERT(index > 0); |  | 
| 225     ASSERT(static_cast<unsigned>(index) <= bindParameterCount()); |  | 
| 226 |  | 
| 227     return sqlite3_bind_null(m_statement, index); |  | 
| 228 } |  | 
| 229 |  | 
| 230 int SQLiteStatement::bindValue(int index, const SQLValue& value) |  | 
| 231 { |  | 
| 232     switch (value.type()) { |  | 
| 233         case SQLValue::StringValue: |  | 
| 234             return bindText(index, value.string()); |  | 
| 235         case SQLValue::NumberValue: |  | 
| 236             return bindDouble(index, value.number()); |  | 
| 237         case SQLValue::NullValue: |  | 
| 238             return bindNull(index); |  | 
| 239     } |  | 
| 240 |  | 
| 241     ASSERT_NOT_REACHED(); |  | 
| 242     return SQLITE_ERROR; |  | 
| 243 } |  | 
| 244 |  | 
| 245 unsigned SQLiteStatement::bindParameterCount() const |  | 
| 246 { |  | 
| 247     ASSERT(m_isPrepared); |  | 
| 248     if (!m_statement) |  | 
| 249         return 0; |  | 
| 250     return sqlite3_bind_parameter_count(m_statement); |  | 
| 251 } |  | 
| 252 |  | 
| 253 int SQLiteStatement::columnCount() |  | 
| 254 { |  | 
| 255     ASSERT(m_isPrepared); |  | 
| 256     if (!m_statement) |  | 
| 257         return 0; |  | 
| 258     return sqlite3_data_count(m_statement); |  | 
| 259 } |  | 
| 260 |  | 
| 261 bool SQLiteStatement::isColumnNull(int col) |  | 
| 262 { |  | 
| 263     ASSERT(col >= 0); |  | 
| 264     if (!m_statement) |  | 
| 265         if (prepareAndStep() != SQLITE_ROW) |  | 
| 266             return false; |  | 
| 267     if (columnCount() <= col) |  | 
| 268         return false; |  | 
| 269 |  | 
| 270     return sqlite3_column_type(m_statement, col) == SQLITE_NULL; |  | 
| 271 } |  | 
| 272 |  | 
| 273 bool SQLiteStatement::isColumnDeclaredAsBlob(int col) |  | 
| 274 { |  | 
| 275     ASSERT(col >= 0); |  | 
| 276     if (!m_statement) { |  | 
| 277         if (prepare() != SQLITE_OK) |  | 
| 278             return false; |  | 
| 279     } |  | 
| 280 |  | 
| 281     return equalIgnoringCase(String("BLOB"), String(reinterpret_cast<const UChar
     *>(sqlite3_column_decltype16(m_statement, col)))); |  | 
| 282 } |  | 
| 283 |  | 
| 284 String SQLiteStatement::getColumnName(int col) |  | 
| 285 { |  | 
| 286     ASSERT(col >= 0); |  | 
| 287     if (!m_statement) |  | 
| 288         if (prepareAndStep() != SQLITE_ROW) |  | 
| 289             return String(); |  | 
| 290     if (columnCount() <= col) |  | 
| 291         return String(); |  | 
| 292     return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_stateme
     nt, col))); |  | 
| 293 } |  | 
| 294 |  | 
| 295 SQLValue SQLiteStatement::getColumnValue(int col) |  | 
| 296 { |  | 
| 297     ASSERT(col >= 0); |  | 
| 298     if (!m_statement) |  | 
| 299         if (prepareAndStep() != SQLITE_ROW) |  | 
| 300             return SQLValue(); |  | 
| 301     if (columnCount() <= col) |  | 
| 302         return SQLValue(); |  | 
| 303 |  | 
| 304     // SQLite is typed per value. optional column types are |  | 
| 305     // "(mostly) ignored" |  | 
| 306     sqlite3_value* value = sqlite3_column_value(m_statement, col); |  | 
| 307     switch (sqlite3_value_type(value)) { |  | 
| 308         case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so 
     use FLOAT -case |  | 
| 309         case SQLITE_FLOAT: |  | 
| 310             return SQLValue(sqlite3_value_double(value)); |  | 
| 311         case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use
      TEXT -case |  | 
| 312         case SQLITE_TEXT: { |  | 
| 313             const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_t
     ext16(value)); |  | 
| 314             unsigned length = WTF::lengthOfNullTerminatedString(string); |  | 
| 315             return SQLValue(StringImpl::create8BitIfPossible(string, length)); |  | 
| 316         } |  | 
| 317         case SQLITE_NULL: |  | 
| 318             return SQLValue(); |  | 
| 319         default: |  | 
| 320             break; |  | 
| 321     } |  | 
| 322     ASSERT_NOT_REACHED(); |  | 
| 323     return SQLValue(); |  | 
| 324 } |  | 
| 325 |  | 
| 326 String SQLiteStatement::getColumnText(int col) |  | 
| 327 { |  | 
| 328     ASSERT(col >= 0); |  | 
| 329     if (!m_statement) |  | 
| 330         if (prepareAndStep() != SQLITE_ROW) |  | 
| 331             return String(); |  | 
| 332     if (columnCount() <= col) |  | 
| 333         return String(); |  | 
| 334     const UChar* string = reinterpret_cast<const UChar*>(sqlite3_column_text16(m
     _statement, col)); |  | 
| 335     return StringImpl::create8BitIfPossible(string, sqlite3_column_bytes16(m_sta
     tement, col) / sizeof(UChar)); |  | 
| 336 } |  | 
| 337 |  | 
| 338 double SQLiteStatement::getColumnDouble(int col) |  | 
| 339 { |  | 
| 340     ASSERT(col >= 0); |  | 
| 341     if (!m_statement) |  | 
| 342         if (prepareAndStep() != SQLITE_ROW) |  | 
| 343             return 0.0; |  | 
| 344     if (columnCount() <= col) |  | 
| 345         return 0.0; |  | 
| 346     return sqlite3_column_double(m_statement, col); |  | 
| 347 } |  | 
| 348 |  | 
| 349 int SQLiteStatement::getColumnInt(int col) |  | 
| 350 { |  | 
| 351     ASSERT(col >= 0); |  | 
| 352     if (!m_statement) |  | 
| 353         if (prepareAndStep() != SQLITE_ROW) |  | 
| 354             return 0; |  | 
| 355     if (columnCount() <= col) |  | 
| 356         return 0; |  | 
| 357     return sqlite3_column_int(m_statement, col); |  | 
| 358 } |  | 
| 359 |  | 
| 360 int64_t SQLiteStatement::getColumnInt64(int col) |  | 
| 361 { |  | 
| 362     ASSERT(col >= 0); |  | 
| 363     if (!m_statement) |  | 
| 364         if (prepareAndStep() != SQLITE_ROW) |  | 
| 365             return 0; |  | 
| 366     if (columnCount() <= col) |  | 
| 367         return 0; |  | 
| 368     return sqlite3_column_int64(m_statement, col); |  | 
| 369 } |  | 
| 370 |  | 
| 371 String SQLiteStatement::getColumnBlobAsString(int col) |  | 
| 372 { |  | 
| 373     ASSERT(col >= 0); |  | 
| 374 |  | 
| 375     if (!m_statement && prepareAndStep() != SQLITE_ROW) |  | 
| 376         return String(); |  | 
| 377 |  | 
| 378     if (columnCount() <= col) |  | 
| 379         return String(); |  | 
| 380 |  | 
| 381     const void* blob = sqlite3_column_blob(m_statement, col); |  | 
| 382     if (!blob) |  | 
| 383         return String(); |  | 
| 384 |  | 
| 385     int size = sqlite3_column_bytes(m_statement, col); |  | 
| 386     if (size < 0) |  | 
| 387         return String(); |  | 
| 388 |  | 
| 389     ASSERT(!(size % sizeof(UChar))); |  | 
| 390     return String(static_cast<const UChar*>(blob), size / sizeof(UChar)); |  | 
| 391 } |  | 
| 392 |  | 
| 393 void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result) |  | 
| 394 { |  | 
| 395     ASSERT(col >= 0); |  | 
| 396 |  | 
| 397     if (!m_statement && prepareAndStep() != SQLITE_ROW) { |  | 
| 398         result.clear(); |  | 
| 399         return; |  | 
| 400     } |  | 
| 401 |  | 
| 402     if (columnCount() <= col) { |  | 
| 403         result.clear(); |  | 
| 404         return; |  | 
| 405     } |  | 
| 406 |  | 
| 407     const void* blob = sqlite3_column_blob(m_statement, col); |  | 
| 408     if (!blob) { |  | 
| 409         result.clear(); |  | 
| 410         return; |  | 
| 411     } |  | 
| 412 |  | 
| 413     int size = sqlite3_column_bytes(m_statement, col); |  | 
| 414     result.resize((size_t)size); |  | 
| 415     for (int i = 0; i < size; ++i) |  | 
| 416         result[i] = (static_cast<const unsigned char*>(blob))[i]; |  | 
| 417 } |  | 
| 418 |  | 
| 419 const void* SQLiteStatement::getColumnBlob(int col, int& size) |  | 
| 420 { |  | 
| 421     ASSERT(col >= 0); |  | 
| 422 |  | 
| 423     size = 0; |  | 
| 424 |  | 
| 425     if (finalize() != SQLITE_OK) |  | 
| 426         LOG(SQLDatabase, "Finalize failed"); |  | 
| 427     if (prepare() != SQLITE_OK) { |  | 
| 428         LOG(SQLDatabase, "Prepare failed"); |  | 
| 429         return 0; |  | 
| 430     } |  | 
| 431     if (step() != SQLITE_ROW) { |  | 
| 432         LOG(SQLDatabase, "Step wasn't a row"); |  | 
| 433         return 0; |  | 
| 434     } |  | 
| 435 |  | 
| 436     if (columnCount() <= col) |  | 
| 437         return 0; |  | 
| 438 |  | 
| 439     const void* blob = sqlite3_column_blob(m_statement, col); |  | 
| 440     if (!blob) |  | 
| 441         return 0; |  | 
| 442 |  | 
| 443     size = sqlite3_column_bytes(m_statement, col); |  | 
| 444     return blob; |  | 
| 445 } |  | 
| 446 |  | 
| 447 bool SQLiteStatement::returnTextResults(int col, Vector<String>& v) |  | 
| 448 { |  | 
| 449     ASSERT(col >= 0); |  | 
| 450 |  | 
| 451     v.clear(); |  | 
| 452 |  | 
| 453     if (m_statement) |  | 
| 454         finalize(); |  | 
| 455     if (prepare() != SQLITE_OK) |  | 
| 456         return false; |  | 
| 457 |  | 
| 458     while (step() == SQLITE_ROW) |  | 
| 459         v.append(getColumnText(col)); |  | 
| 460     bool result = true; |  | 
| 461     if (m_database.lastError() != SQLITE_DONE) { |  | 
| 462         result = false; |  | 
| 463         LOG(SQLDatabase, "Error reading results from database query %s", m_query
     .ascii().data()); |  | 
| 464     } |  | 
| 465     finalize(); |  | 
| 466     return result; |  | 
| 467 } |  | 
| 468 |  | 
| 469 bool SQLiteStatement::returnIntResults(int col, Vector<int>& v) |  | 
| 470 { |  | 
| 471     v.clear(); |  | 
| 472 |  | 
| 473     if (m_statement) |  | 
| 474         finalize(); |  | 
| 475     if (prepare() != SQLITE_OK) |  | 
| 476         return false; |  | 
| 477 |  | 
| 478     while (step() == SQLITE_ROW) |  | 
| 479         v.append(getColumnInt(col)); |  | 
| 480     bool result = true; |  | 
| 481     if (m_database.lastError() != SQLITE_DONE) { |  | 
| 482         result = false; |  | 
| 483         LOG(SQLDatabase, "Error reading results from database query %s", m_query
     .ascii().data()); |  | 
| 484     } |  | 
| 485     finalize(); |  | 
| 486     return result; |  | 
| 487 } |  | 
| 488 |  | 
| 489 bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v) |  | 
| 490 { |  | 
| 491     v.clear(); |  | 
| 492 |  | 
| 493     if (m_statement) |  | 
| 494         finalize(); |  | 
| 495     if (prepare() != SQLITE_OK) |  | 
| 496         return false; |  | 
| 497 |  | 
| 498     while (step() == SQLITE_ROW) |  | 
| 499         v.append(getColumnInt64(col)); |  | 
| 500     bool result = true; |  | 
| 501     if (m_database.lastError() != SQLITE_DONE) { |  | 
| 502         result = false; |  | 
| 503         LOG(SQLDatabase, "Error reading results from database query %s", m_query
     .ascii().data()); |  | 
| 504     } |  | 
| 505     finalize(); |  | 
| 506     return result; |  | 
| 507 } |  | 
| 508 |  | 
| 509 bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v) |  | 
| 510 { |  | 
| 511     v.clear(); |  | 
| 512 |  | 
| 513     if (m_statement) |  | 
| 514         finalize(); |  | 
| 515     if (prepare() != SQLITE_OK) |  | 
| 516         return false; |  | 
| 517 |  | 
| 518     while (step() == SQLITE_ROW) |  | 
| 519         v.append(getColumnDouble(col)); |  | 
| 520     bool result = true; |  | 
| 521     if (m_database.lastError() != SQLITE_DONE) { |  | 
| 522         result = false; |  | 
| 523         LOG(SQLDatabase, "Error reading results from database query %s", m_query
     .ascii().data()); |  | 
| 524     } |  | 
| 525     finalize(); |  | 
| 526     return result; |  | 
| 527 } |  | 
| 528 |  | 
| 529 bool SQLiteStatement::isExpired() |  | 
| 530 { |  | 
| 531     return !m_statement || sqlite3_expired(m_statement); |  | 
| 532 } |  | 
| 533 |  | 
| 534 } // namespace WebCore |  | 
| OLD | NEW | 
|---|