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 blink {
     42 
     43 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
     44     : m_database(db)
     45     , m_query(sql)
     46     , m_statement(0)
     47 #if ENABLE(ASSERT)
     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     CString query = m_query.stripWhiteSpace().utf8();
     63 
     64     ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
     65 
     66     WTF_LOG(SQLDatabase, "SQL - prepare - %s", query.data());
     67 
     68     // Pass the length of the string including the null character to sqlite3_prepare_v2;
     69     // this lets SQLite avoid an extra string copy.
     70     size_t lengthIncludingNullCharacter = query.length() + 1;
     71 
     72     const char* tail = 0;
     73     int error = sqlite3_prepare_v2(m_database.sqlite3Handle(), query.data(), lengthIncludingNullCharacter, &m_statement, &tail);
     74 
     75     if (error != SQLITE_OK)
     76         WTF_LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.data(), sqlite3_errmsg(m_database.sqlite3Handle()));
     77     else if (tail && *tail)
     78         error = SQLITE_ERROR;
     79 
     80 #if ENABLE(ASSERT)
     81     m_isPrepared = error == SQLITE_OK;
     82 #endif
     83     return error;
     84 }
     85 
     86 int SQLiteStatement::step()
     87 {
     88     ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
     89     //ASSERT(m_isPrepared);
     90 
     91     if (!m_statement)
     92         return SQLITE_OK;
     93 
     94     // The database needs to update its last changes count before each statement
     95     // in order to compute properly the lastChanges() return value.
     96     m_database.updateLastChangesCount();
     97 
     98     WTF_LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
     99     int error = sqlite3_step(m_statement);
    100     if (error != SQLITE_DONE && error != SQLITE_ROW) {
    101         WTF_LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
    102             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
    103     }
    104 
    105     return error;
    106 }
    107 
    108 int SQLiteStatement::finalize()
    109 {
    110 #if ENABLE(ASSERT)
    111     m_isPrepared = false;
    112 #endif
    113     if (!m_statement)
    114         return SQLITE_OK;
    115     WTF_LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
    116     int result = sqlite3_finalize(m_statement);
    117     m_statement = 0;
    118     return result;
    119 }
    120 
    121 bool SQLiteStatement::executeCommand()
    122 {
    123     if (!m_statement && prepare() != SQLITE_OK)
    124         return false;
    125     ASSERT(m_isPrepared);
    126     if (step() != SQLITE_DONE) {
    127         finalize();
    128         return false;
    129     }
    130     finalize();
    131     return true;
    132 }
    133 
    134 int SQLiteStatement::bindText(int index, const String& text)
    135 {
    136     ASSERT(m_isPrepared);
    137     ASSERT(index > 0);
    138     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    139 
    140     // SQLite treats uses zero pointers to represent null strings, which means we need to make sure to map null WTFStrings to zero pointers.
    141     ASSERT(!String().charactersWithNullTermination().data());
    142     return sqlite3_bind_text16(m_statement, index, text.charactersWithNullTermination().data(), sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
    143 }
    144 
    145 int SQLiteStatement::bindDouble(int index, double number)
    146 {
    147     ASSERT(m_isPrepared);
    148     ASSERT(index > 0);
    149     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    150 
    151     return sqlite3_bind_double(m_statement, index, number);
    152 }
    153 
    154 int SQLiteStatement::bindNull(int index)
    155 {
    156     ASSERT(m_isPrepared);
    157     ASSERT(index > 0);
    158     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
    159 
    160     return sqlite3_bind_null(m_statement, index);
    161 }
    162 
    163 int SQLiteStatement::bindValue(int index, const SQLValue& value)
    164 {
    165     switch (value.type()) {
    166         case SQLValue::StringValue:
    167             return bindText(index, value.string());
    168         case SQLValue::NumberValue:
    169             return bindDouble(index, value.number());
    170         case SQLValue::NullValue:
    171             return bindNull(index);
    172     }
    173 
    174     ASSERT_NOT_REACHED();
    175     return SQLITE_ERROR;
    176 }
    177 
    178 unsigned SQLiteStatement::bindParameterCount() const
    179 {
    180     ASSERT(m_isPrepared);
    181     if (!m_statement)
    182         return 0;
    183     return sqlite3_bind_parameter_count(m_statement);
    184 }
    185 
    186 int SQLiteStatement::columnCount()
    187 {
    188     ASSERT(m_isPrepared);
    189     if (!m_statement)
    190         return 0;
    191     return sqlite3_data_count(m_statement);
    192 }
    193 
    194 String SQLiteStatement::getColumnName(int col)
    195 {
    196     ASSERT(col >= 0);
    197     if (!m_statement)
    198         if (prepareAndStep() != SQLITE_ROW)
    199             return String();
    200     if (columnCount() <= col)
    201         return String();
    202     return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
    203 }
    204 
    205 SQLValue SQLiteStatement::getColumnValue(int col)
    206 {
    207     ASSERT(col >= 0);
    208     if (!m_statement)
    209         if (prepareAndStep() != SQLITE_ROW)
    210             return SQLValue();
    211     if (columnCount() <= col)
    212         return SQLValue();
    213 
    214     // SQLite is typed per value. optional column types are
    215     // "(mostly) ignored"
    216     sqlite3_value* value = sqlite3_column_value(m_statement, col);
    217     switch (sqlite3_value_type(value)) {
    218         case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so use FLOAT -case
    219         case SQLITE_FLOAT:
    220             return SQLValue(sqlite3_value_double(value));
    221         case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use TEXT -case
    222         case SQLITE_TEXT: {
    223             const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_text16(value));
    224             unsigned length = WTF::lengthOfNullTerminatedString(string);
    225             return SQLValue(StringImpl::create8BitIfPossible(string, length));
    226         }
    227         case SQLITE_NULL:
    228             return SQLValue();
    229         default:
    230             break;
    231     }
    232     ASSERT_NOT_REACHED();
    233     return SQLValue();
    234 }
    235 
    236 String SQLiteStatement::getColumnText(int col)
    237 {
    238     ASSERT(col >= 0);
    239     if (!m_statement)
    240         if (prepareAndStep() != SQLITE_ROW)
    241             return String();
    242     if (columnCount() <= col)
    243         return String();
    244     const UChar* string = reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col));
    245     return StringImpl::create8BitIfPossible(string, sqlite3_column_bytes16(m_statement, col) / sizeof(UChar));
    246 }
    247 
    248 int SQLiteStatement::getColumnInt(int col)
    249 {
    250     ASSERT(col >= 0);
    251     if (!m_statement)
    252         if (prepareAndStep() != SQLITE_ROW)
    253             return 0;
    254     if (columnCount() <= col)
    255         return 0;
    256     return sqlite3_column_int(m_statement, col);
    257 }
    258 
    259 int64_t SQLiteStatement::getColumnInt64(int col)
    260 {
    261     ASSERT(col >= 0);
    262     if (!m_statement)
    263         if (prepareAndStep() != SQLITE_ROW)
    264             return 0;
    265     if (columnCount() <= col)
    266         return 0;
    267     return sqlite3_column_int64(m_statement, col);
    268 }
    269 
    270 } // namespace blink
    271