Home | History | Annotate | Download | only in sqlite
      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 "modules/webdatabase/sqlite/SQLiteStatement.h"
     28 
     29 #include <sqlite3.h>
     30 #include "platform/Logging.h"
     31 #include "modules/webdatabase/sqlite/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 statement
     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     WTF_LOG(SQLDatabase, "SQL - prepare - %s", query.data());
     69 
     70     // Pass the length of the string including the null character to sqlite3_prepare_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(), lengthIncludingNullCharacter, &m_statement, &tail);
     76 
     77     if (error != SQLITE_OK)
     78         WTF_LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.data(), 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     WTF_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         WTF_LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
    107             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
    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     WTF_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     WTF_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 we need to make sure to map null WTFStrings to zero pointers.
    179     ASSERT(!String().charactersWithNullTermination().data());
    180     return bindBlob(index, text.charactersWithNullTermination().data(), text.length() * 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 we 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.charactersWithNullTermination().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_statement, 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_text16(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_statement, 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         WTF_LOG(SQLDatabase, "Finalize failed");
    427     if (prepare() != SQLITE_OK) {
    428         WTF_LOG(SQLDatabase, "Prepare failed");
    429         return 0;
    430     }
    431     if (step() != SQLITE_ROW) {
    432         WTF_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         WTF_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         WTF_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         WTF_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         WTF_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
    535