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
SQLiteStatement(SQLiteDatabase & db,const String & sql)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
~SQLiteStatement()53 SQLiteStatement::~SQLiteStatement()
54 {
55 finalize();
56 }
57
prepare()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
step()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
finalize()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
reset()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
executeCommand()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
returnsAtLeastOneResult()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
bindBlob(int index,const void * blob,int size)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
bindBlob(int index,const String & text)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
bindText(int index,const String & text)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
bindInt(int index,int integer)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
bindInt64(int index,int64_t integer)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
bindDouble(int index,double number)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
bindNull(int index)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
bindValue(int index,const SQLValue & value)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
bindParameterCount() const245 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
columnCount()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
isColumnNull(int col)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
isColumnDeclaredAsBlob(int col)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
getColumnName(int col)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
getColumnValue(int col)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
getColumnText(int col)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
getColumnDouble(int col)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
getColumnInt(int col)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
getColumnInt64(int col)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
getColumnBlobAsString(int col)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
getColumnBlobAsVector(int col,Vector<char> & result)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
getColumnBlob(int col,int & size)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
returnTextResults(int col,Vector<String> & v)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
returnIntResults(int col,Vector<int> & v)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
returnInt64Results(int col,Vector<int64_t> & v)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
returnDoubleResults(int col,Vector<double> & v)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
isExpired()529 bool SQLiteStatement::isExpired()
530 {
531 return !m_statement || sqlite3_expired(m_statement);
532 }
533
534 } // namespace WebCore
535