Home | History | Annotate | Download | only in sql
      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 "SQLiteStatement.h"
     28 
     29 #include "Logging.h"
     30 #include "SQLValue.h"
     31 #include <sqlite3.h>
     32 #include <wtf/Assertions.h>
     33 
     34 namespace WebCore {
     35 
     36 #if SQLITE_VERSION_NUMBER < 3003009
     37 
     38 // FIXME: This overload helps us compile with older versions of SQLite 3, but things like quotas will not work.
     39 static inline int sqlite3_prepare16_v2(sqlite3* db, const void* zSql, int nBytes, sqlite3_stmt** ppStmt, const void** pzTail)
     40 {
     41     return sqlite3_prepare16(db, zSql, nBytes, ppStmt, pzTail);
     42 }
     43 
     44 #endif
     45 
     46 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
     47     : m_database(db)
     48     , m_query(sql)
     49     , m_statement(0)
     50 #ifndef NDEBUG
     51     , m_isPrepared(false)
     52 #endif
     53 {
     54 }
     55 
     56 SQLiteStatement::~SQLiteStatement()
     57 {
     58     finalize();
     59 }
     60 
     61 int SQLiteStatement::prepare()
     62 {
     63     ASSERT(!m_isPrepared);
     64     const void* tail;
     65     LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
     66     int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.charactersWithNullTermination(), -1, &m_statement, &tail);
     67     if (error != SQLITE_OK)
     68         LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
     69 #ifndef NDEBUG
     70     m_isPrepared = error == SQLITE_OK;
     71 #endif
     72     return error;
     73 }
     74 
     75 int SQLiteStatement::step()
     76 {
     77     ASSERT(m_isPrepared);
     78     if (!m_statement)
     79         return SQLITE_OK;
     80     LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
     81     int error = sqlite3_step(m_statement);
     82     if (error != SQLITE_DONE && error != SQLITE_ROW) {
     83         LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
     84             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
     85     }
     86     return error;
     87 }
     88 
     89 int SQLiteStatement::finalize()
     90 {
     91 #ifndef NDEBUG
     92     m_isPrepared = false;
     93 #endif
     94     if (!m_statement)
     95         return SQLITE_OK;
     96     LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
     97     int result = sqlite3_finalize(m_statement);
     98     m_statement = 0;
     99     return result;
    100 }
    101 
    102 int SQLiteStatement::reset()
    103 {
    104     ASSERT(m_isPrepared);
    105     if (!m_statement)
    106         return SQLITE_OK;
    107     LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data());
    108     return sqlite3_reset(m_statement);
    109 }
    110 
    111 bool SQLiteStatement::executeCommand()
    112 {
    113     if (!m_statement && prepare() != SQLITE_OK)
    114         return false;
    115     ASSERT(m_isPrepared);
    116     if (step() != SQLITE_DONE) {
    117         finalize();
    118         return false;
    119     }
    120     finalize();
    121     return true;
    122 }
    123 
    124 bool SQLiteStatement::returnsAtLeastOneResult()
    125 {
    126     if (!m_statement && prepare() != SQLITE_OK)
    127         return false;
    128     ASSERT(m_isPrepared);
    129     if (step() != SQLITE_ROW) {
    130         finalize();
    131         return false;
    132     }
    133     finalize();
    134     return true;
    135 
    136 }
    137 
    138 int SQLiteStatement::bindBlob(int index, const void* blob, int size)
    139 {
    140     ASSERT(m_isPrepared);
    141     ASSERT(index > 0);
    142     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    143     ASSERT(blob);
    144     ASSERT(size >= 0);
    145 
    146     if (!m_statement)
    147         return SQLITE_ERROR;
    148 
    149     return sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
    150 }
    151 
    152 int SQLiteStatement::bindText(int index, const String& text)
    153 {
    154     ASSERT(m_isPrepared);
    155     ASSERT(index > 0);
    156     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    157 
    158     // String::characters() returns 0 for the empty string, which SQLite
    159     // treats as a null, so we supply a non-null pointer for that case.
    160     UChar anyCharacter = 0;
    161     const UChar* characters;
    162     if (text.isEmpty() && !text.isNull())
    163         characters = &anyCharacter;
    164     else
    165         characters = text.characters();
    166 
    167     return sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
    168 }
    169 
    170 
    171 int SQLiteStatement::bindInt64(int index, int64_t integer)
    172 {
    173     ASSERT(m_isPrepared);
    174     ASSERT(index > 0);
    175     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    176 
    177     return sqlite3_bind_int64(m_statement, index, integer);
    178 }
    179 
    180 int SQLiteStatement::bindDouble(int index, double number)
    181 {
    182     ASSERT(m_isPrepared);
    183     ASSERT(index > 0);
    184     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    185 
    186     return sqlite3_bind_double(m_statement, index, number);
    187 }
    188 
    189 int SQLiteStatement::bindNull(int index)
    190 {
    191     ASSERT(m_isPrepared);
    192     ASSERT(index > 0);
    193     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    194 
    195     return sqlite3_bind_null(m_statement, index);
    196 }
    197 
    198 int SQLiteStatement::bindValue(int index, const SQLValue& value)
    199 {
    200     switch (value.type()) {
    201         case SQLValue::StringValue:
    202             return bindText(index, value.string());
    203         case SQLValue::NumberValue:
    204             return bindDouble(index, value.number());
    205         case SQLValue::NullValue:
    206             return bindNull(index);
    207     }
    208 
    209     ASSERT_NOT_REACHED();
    210     return SQLITE_ERROR;
    211 }
    212 
    213 unsigned SQLiteStatement::bindParameterCount() const
    214 {
    215     ASSERT(m_isPrepared);
    216     if (!m_statement)
    217         return 0;
    218     return sqlite3_bind_parameter_count(m_statement);
    219 }
    220 
    221 int SQLiteStatement::columnCount()
    222 {
    223     ASSERT(m_isPrepared);
    224     if (!m_statement)
    225         return 0;
    226     return sqlite3_data_count(m_statement);
    227 }
    228 
    229 String SQLiteStatement::getColumnName(int col)
    230 {
    231     ASSERT(col >= 0);
    232     if (!m_statement)
    233         if (prepareAndStep() != SQLITE_ROW)
    234             return String();
    235     if (columnCount() <= col)
    236         return String();
    237     return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
    238 }
    239 
    240 SQLValue SQLiteStatement::getColumnValue(int col)
    241 {
    242     ASSERT(col >= 0);
    243     if (!m_statement)
    244         if (prepareAndStep() != SQLITE_ROW)
    245             return SQLValue();
    246     if (columnCount() <= col)
    247         return SQLValue();
    248 
    249     // SQLite is typed per value. optional column types are
    250     // "(mostly) ignored"
    251     sqlite3_value* value = sqlite3_column_value(m_statement, col);
    252     switch (sqlite3_value_type(value)) {
    253         case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so use FLOAT -case
    254         case SQLITE_FLOAT:
    255             return SQLValue(sqlite3_value_double(value));
    256         case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use TEXT -case
    257         case SQLITE_TEXT:
    258             return SQLValue(String(reinterpret_cast<const UChar*>(sqlite3_value_text16(value))));
    259         case SQLITE_NULL:
    260             return SQLValue();
    261         default:
    262             break;
    263     }
    264     ASSERT_NOT_REACHED();
    265     return SQLValue();
    266 }
    267 
    268 String SQLiteStatement::getColumnText(int col)
    269 {
    270     ASSERT(col >= 0);
    271     if (!m_statement)
    272         if (prepareAndStep() != SQLITE_ROW)
    273             return String();
    274     if (columnCount() <= col)
    275         return String();
    276     return String(reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col)));
    277 }
    278 
    279 double SQLiteStatement::getColumnDouble(int col)
    280 {
    281     ASSERT(col >= 0);
    282     if (!m_statement)
    283         if (prepareAndStep() != SQLITE_ROW)
    284             return 0.0;
    285     if (columnCount() <= col)
    286         return 0.0;
    287     return sqlite3_column_double(m_statement, col);
    288 }
    289 
    290 int SQLiteStatement::getColumnInt(int col)
    291 {
    292     ASSERT(col >= 0);
    293     if (!m_statement)
    294         if (prepareAndStep() != SQLITE_ROW)
    295             return 0;
    296     if (columnCount() <= col)
    297         return 0;
    298     return sqlite3_column_int(m_statement, col);
    299 }
    300 
    301 int64_t SQLiteStatement::getColumnInt64(int col)
    302 {
    303     ASSERT(col >= 0);
    304     if (!m_statement)
    305         if (prepareAndStep() != SQLITE_ROW)
    306             return 0;
    307     if (columnCount() <= col)
    308         return 0;
    309     return sqlite3_column_int64(m_statement, col);
    310 }
    311 
    312 void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
    313 {
    314     ASSERT(col >= 0);
    315 
    316     if (!m_statement && prepareAndStep() != SQLITE_ROW) {
    317         result.clear();
    318         return;
    319     }
    320 
    321     if (columnCount() <= col) {
    322         result.clear();
    323         return;
    324     }
    325 
    326     const void* blob = sqlite3_column_blob(m_statement, col);
    327     if (!blob) {
    328         result.clear();
    329         return;
    330     }
    331 
    332     int size = sqlite3_column_bytes(m_statement, col);
    333     result.resize((size_t)size);
    334     for (int i = 0; i < size; ++i)
    335         result[i] = ((const unsigned char*)blob)[i];
    336 }
    337 
    338 const void* SQLiteStatement::getColumnBlob(int col, int& size)
    339 {
    340     ASSERT(col >= 0);
    341 
    342     size = 0;
    343 
    344     if (finalize() != SQLITE_OK)
    345         LOG(SQLDatabase, "Finalize failed");
    346     if (prepare() != SQLITE_OK) {
    347         LOG(SQLDatabase, "Prepare failed");
    348         return 0;
    349     }
    350     if (step() != SQLITE_ROW) {
    351         LOG(SQLDatabase, "Step wasn't a row");
    352         return 0;
    353     }
    354 
    355     if (columnCount() <= col)
    356         return 0;
    357 
    358     const void* blob = sqlite3_column_blob(m_statement, col);
    359     if (!blob)
    360         return 0;
    361 
    362     size = sqlite3_column_bytes(m_statement, col);
    363     return blob;
    364 }
    365 
    366 bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
    367 {
    368     ASSERT(col >= 0);
    369 
    370     v.clear();
    371 
    372     if (m_statement)
    373         finalize();
    374     if (prepare() != SQLITE_OK)
    375         return false;
    376 
    377     while (step() == SQLITE_ROW)
    378         v.append(getColumnText(col));
    379     bool result = true;
    380     if (m_database.lastError() != SQLITE_DONE) {
    381         result = false;
    382         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
    383     }
    384     finalize();
    385     return result;
    386 }
    387 
    388 bool SQLiteStatement::returnIntResults(int col, Vector<int>& v)
    389 {
    390     v.clear();
    391 
    392     if (m_statement)
    393         finalize();
    394     if (prepare() != SQLITE_OK)
    395         return false;
    396 
    397     while (step() == SQLITE_ROW)
    398         v.append(getColumnInt(col));
    399     bool result = true;
    400     if (m_database.lastError() != SQLITE_DONE) {
    401         result = false;
    402         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
    403     }
    404     finalize();
    405     return result;
    406 }
    407 
    408 bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v)
    409 {
    410     v.clear();
    411 
    412     if (m_statement)
    413         finalize();
    414     if (prepare() != SQLITE_OK)
    415         return false;
    416 
    417     while (step() == SQLITE_ROW)
    418         v.append(getColumnInt64(col));
    419     bool result = true;
    420     if (m_database.lastError() != SQLITE_DONE) {
    421         result = false;
    422         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
    423     }
    424     finalize();
    425     return result;
    426 }
    427 
    428 bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v)
    429 {
    430     v.clear();
    431 
    432     if (m_statement)
    433         finalize();
    434     if (prepare() != SQLITE_OK)
    435         return false;
    436 
    437     while (step() == SQLITE_ROW)
    438         v.append(getColumnDouble(col));
    439     bool result = true;
    440     if (m_database.lastError() != SQLITE_DONE) {
    441         result = false;
    442         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
    443     }
    444     finalize();
    445     return result;
    446 }
    447 
    448 bool SQLiteStatement::isExpired()
    449 {
    450     return !m_statement || sqlite3_expired(m_statement);
    451 }
    452 
    453 } // namespace WebCore
    454