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