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 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 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#include <wtf/Variant.h>
34#include <wtf/text/StringView.h>
35
36// SQLite 3.6.16 makes sqlite3_prepare_v2 automatically retry preparing the statement
37// once if the database scheme has changed. We rely on this behavior.
38#if SQLITE_VERSION_NUMBER < 3006016
39#error SQLite version 3.6.16 or newer is required
40#endif
41
42namespace WebCore {
43
44SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
45 : m_database(db)
46 , m_query(sql)
47 , m_statement(0)
48#ifndef NDEBUG
49 , m_isPrepared(false)
50#endif
51{
52}
53
54SQLiteStatement::~SQLiteStatement()
55{
56 finalize();
57}
58
59int SQLiteStatement::prepare()
60{
61 ASSERT(!m_isPrepared);
62
63 LockHolder databaseLock(m_database.databaseMutex());
64
65 CString query = m_query.stripWhiteSpace().utf8();
66
67 LOG(SQLDatabase, "SQL - prepare - %s", query.data());
68
69 // Pass the length of the string including the null character to sqlite3_prepare_v2;
70 // this lets SQLite avoid an extra string copy.
71 size_t lengthIncludingNullCharacter = query.length() + 1;
72
73 const char* tail = nullptr;
74 int error = sqlite3_prepare_v2(m_database.sqlite3Handle(), query.data(), lengthIncludingNullCharacter, &m_statement, &tail);
75
76 if (error != SQLITE_OK)
77 LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.data(), sqlite3_errmsg(m_database.sqlite3Handle()));
78
79 if (tail && *tail)
80 error = SQLITE_ERROR;
81
82#ifndef NDEBUG
83 m_isPrepared = error == SQLITE_OK;
84#endif
85 return error;
86}
87
88int SQLiteStatement::step()
89{
90 LockHolder databaseLock(m_database.databaseMutex());
91
92 if (!m_statement)
93 return SQLITE_OK;
94
95 // The database needs to update its last changes count before each statement
96 // in order to compute properly the lastChanges() return value.
97 m_database.updateLastChangesCount();
98
99 LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
100 int error = sqlite3_step(m_statement);
101 if (error != SQLITE_DONE && error != SQLITE_ROW) {
102 LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
103 error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
104 }
105
106 return error;
107}
108
109int SQLiteStatement::finalize()
110{
111#ifndef NDEBUG
112 m_isPrepared = false;
113#endif
114 if (!m_statement)
115 return SQLITE_OK;
116 LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
117 int result = sqlite3_finalize(m_statement);
118 m_statement = 0;
119 return result;
120}
121
122int SQLiteStatement::reset()
123{
124 ASSERT(m_isPrepared);
125 if (!m_statement)
126 return SQLITE_OK;
127 LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data());
128 return sqlite3_reset(m_statement);
129}
130
131bool SQLiteStatement::executeCommand()
132{
133 if (!m_statement && prepare() != SQLITE_OK)
134 return false;
135 ASSERT(m_isPrepared);
136 if (step() != SQLITE_DONE) {
137 finalize();
138 return false;
139 }
140 finalize();
141 return true;
142}
143
144bool SQLiteStatement::returnsAtLeastOneResult()
145{
146 if (!m_statement && prepare() != SQLITE_OK)
147 return false;
148 ASSERT(m_isPrepared);
149 if (step() != SQLITE_ROW) {
150 finalize();
151 return false;
152 }
153 finalize();
154 return true;
155
156}
157
158int SQLiteStatement::bindBlob(int index, const void* blob, int size)
159{
160 ASSERT(m_isPrepared);
161 ASSERT(index > 0);
162 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
163 ASSERT(blob);
164 ASSERT(size >= 0);
165
166 if (!m_statement)
167 return SQLITE_ERROR;
168
169 return sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
170}
171
172int SQLiteStatement::bindBlob(int index, const String& text)
173{
174 // String::characters() returns 0 for the empty string, which SQLite
175 // treats as a null, so we supply a non-null pointer for that case.
176 auto upconvertedCharacters = StringView(text).upconvertedCharacters();
177 UChar anyCharacter = 0;
178 const UChar* characters;
179 if (text.isEmpty() && !text.isNull())
180 characters = &anyCharacter;
181 else
182 characters = upconvertedCharacters;
183
184 return bindBlob(index, characters, text.length() * sizeof(UChar));
185}
186
187int SQLiteStatement::bindText(int index, const String& text)
188{
189 ASSERT(m_isPrepared);
190 ASSERT(index > 0);
191 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
192
193 // String::characters() returns 0 for the empty string, which SQLite
194 // treats as a null, so we supply a non-null pointer for that case.
195 auto upconvertedCharacters = StringView(text).upconvertedCharacters();
196 UChar anyCharacter = 0;
197 const UChar* characters;
198 if (text.isEmpty() && !text.isNull())
199 characters = &anyCharacter;
200 else
201 characters = upconvertedCharacters;
202
203 return sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
204}
205
206int SQLiteStatement::bindInt(int index, int integer)
207{
208 ASSERT(m_isPrepared);
209 ASSERT(index > 0);
210 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
211
212 return sqlite3_bind_int(m_statement, index, integer);
213}
214
215int SQLiteStatement::bindInt64(int index, int64_t integer)
216{
217 ASSERT(m_isPrepared);
218 ASSERT(index > 0);
219 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
220
221 return sqlite3_bind_int64(m_statement, index, integer);
222}
223
224int SQLiteStatement::bindDouble(int index, double number)
225{
226 ASSERT(m_isPrepared);
227 ASSERT(index > 0);
228 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
229
230 return sqlite3_bind_double(m_statement, index, number);
231}
232
233int SQLiteStatement::bindNull(int index)
234{
235 ASSERT(m_isPrepared);
236 ASSERT(index > 0);
237 ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
238
239 return sqlite3_bind_null(m_statement, index);
240}
241
242int SQLiteStatement::bindValue(int index, const SQLValue& value)
243{
244 return WTF::switchOn(value,
245 [&] (const std::nullptr_t&) { return bindNull(index); },
246 [&] (const String& string) { return bindText(index, string); },
247 [&] (double number) { return bindDouble(index, number); }
248 );
249}
250
251unsigned SQLiteStatement::bindParameterCount() const
252{
253 ASSERT(m_isPrepared);
254 if (!m_statement)
255 return 0;
256 return sqlite3_bind_parameter_count(m_statement);
257}
258
259int SQLiteStatement::columnCount()
260{
261 ASSERT(m_isPrepared);
262 if (!m_statement)
263 return 0;
264 return sqlite3_data_count(m_statement);
265}
266
267bool SQLiteStatement::isColumnNull(int col)
268{
269 ASSERT(col >= 0);
270 if (!m_statement)
271 if (prepareAndStep() != SQLITE_ROW)
272 return false;
273 if (columnCount() <= col)
274 return false;
275
276 return sqlite3_column_type(m_statement, col) == SQLITE_NULL;
277}
278
279bool SQLiteStatement::isColumnDeclaredAsBlob(int col)
280{
281 ASSERT(col >= 0);
282 if (!m_statement) {
283 if (prepare() != SQLITE_OK)
284 return false;
285 }
286 return equalLettersIgnoringASCIICase(StringView(sqlite3_column_decltype(m_statement, col)), "blob");
287}
288
289String SQLiteStatement::getColumnName(int col)
290{
291 ASSERT(col >= 0);
292 if (!m_statement)
293 if (prepareAndStep() != SQLITE_ROW)
294 return String();
295 if (columnCount() <= col)
296 return String();
297 return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
298}
299
300SQLValue SQLiteStatement::getColumnValue(int col)
301{
302 ASSERT(col >= 0);
303 if (!m_statement)
304 if (prepareAndStep() != SQLITE_ROW)
305 return nullptr;
306 if (columnCount() <= col)
307 return nullptr;
308
309 // SQLite is typed per value. optional column types are
310 // "(mostly) ignored"
311 sqlite3_value* value = sqlite3_column_value(m_statement, col);
312 switch (sqlite3_value_type(value)) {
313 case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use FLOAT -case
314 case SQLITE_FLOAT:
315 return sqlite3_value_double(value);
316 case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT -case
317 case SQLITE_TEXT: {
318 const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_text16(value));
319 return StringImpl::create8BitIfPossible(string);
320 }
321 case SQLITE_NULL:
322 return nullptr;
323 default:
324 break;
325 }
326
327 ASSERT_NOT_REACHED();
328 return nullptr;
329}
330
331String SQLiteStatement::getColumnText(int col)
332{
333 ASSERT(col >= 0);
334 if (!m_statement)
335 if (prepareAndStep() != SQLITE_ROW)
336 return String();
337 if (columnCount() <= col)
338 return String();
339 return String(reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col)), sqlite3_column_bytes16(m_statement, col) / sizeof(UChar));
340}
341
342double SQLiteStatement::getColumnDouble(int col)
343{
344 ASSERT(col >= 0);
345 if (!m_statement)
346 if (prepareAndStep() != SQLITE_ROW)
347 return 0.0;
348 if (columnCount() <= col)
349 return 0.0;
350 return sqlite3_column_double(m_statement, col);
351}
352
353int SQLiteStatement::getColumnInt(int col)
354{
355 ASSERT(col >= 0);
356 if (!m_statement)
357 if (prepareAndStep() != SQLITE_ROW)
358 return 0;
359 if (columnCount() <= col)
360 return 0;
361 return sqlite3_column_int(m_statement, col);
362}
363
364int64_t SQLiteStatement::getColumnInt64(int col)
365{
366 ASSERT(col >= 0);
367 if (!m_statement)
368 if (prepareAndStep() != SQLITE_ROW)
369 return 0;
370 if (columnCount() <= col)
371 return 0;
372 return sqlite3_column_int64(m_statement, col);
373}
374
375String SQLiteStatement::getColumnBlobAsString(int col)
376{
377 ASSERT(col >= 0);
378
379 if (!m_statement && prepareAndStep() != SQLITE_ROW)
380 return String();
381
382 if (columnCount() <= col)
383 return String();
384
385 const void* blob = sqlite3_column_blob(m_statement, col);
386 if (!blob)
387 return emptyString();
388
389 int size = sqlite3_column_bytes(m_statement, col);
390 if (size < 0)
391 return String();
392
393 ASSERT(!(size % sizeof(UChar)));
394 return String(static_cast<const UChar*>(blob), size / sizeof(UChar));
395}
396
397void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
398{
399 ASSERT(col >= 0);
400
401 if (!m_statement && prepareAndStep() != SQLITE_ROW) {
402 result.clear();
403 return;
404 }
405
406 if (columnCount() <= col) {
407 result.clear();
408 return;
409 }
410
411 const void* blob = sqlite3_column_blob(m_statement, col);
412 if (!blob) {
413 result.clear();
414 return;
415 }
416
417 int size = sqlite3_column_bytes(m_statement, col);
418 result.resize((size_t)size);
419 for (int i = 0; i < size; ++i)
420 result[i] = (static_cast<const unsigned char*>(blob))[i];
421}
422
423void SQLiteStatement::getColumnBlobAsVector(int col, Vector<uint8_t>& result)
424{
425 ASSERT(col >= 0);
426
427 if (!m_statement && prepareAndStep() != SQLITE_ROW) {
428 result.clear();
429 return;
430 }
431
432 if (columnCount() <= col) {
433 result.clear();
434 return;
435 }
436
437 const void* blob = sqlite3_column_blob(m_statement, col);
438 if (!blob) {
439 result.clear();
440 return;
441 }
442
443 int size = sqlite3_column_bytes(m_statement, col);
444 result.resize((size_t)size);
445 for (int i = 0; i < size; ++i)
446 result[i] = (static_cast<const uint8_t*>(blob))[i];
447}
448
449bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
450{
451 ASSERT(col >= 0);
452
453 v.clear();
454
455 if (m_statement)
456 finalize();
457 if (prepare() != SQLITE_OK)
458 return false;
459
460 while (step() == SQLITE_ROW)
461 v.append(getColumnText(col));
462 bool result = true;
463 if (m_database.lastError() != SQLITE_DONE) {
464 result = false;
465 LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
466 }
467 finalize();
468 return result;
469}
470
471bool SQLiteStatement::returnIntResults(int col, Vector<int>& v)
472{
473 v.clear();
474
475 if (m_statement)
476 finalize();
477 if (prepare() != SQLITE_OK)
478 return false;
479
480 while (step() == SQLITE_ROW)
481 v.append(getColumnInt(col));
482 bool result = true;
483 if (m_database.lastError() != SQLITE_DONE) {
484 result = false;
485 LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
486 }
487 finalize();
488 return result;
489}
490
491bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v)
492{
493 v.clear();
494
495 if (m_statement)
496 finalize();
497 if (prepare() != SQLITE_OK)
498 return false;
499
500 while (step() == SQLITE_ROW)
501 v.append(getColumnInt64(col));
502 bool result = true;
503 if (m_database.lastError() != SQLITE_DONE) {
504 result = false;
505 LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
506 }
507 finalize();
508 return result;
509}
510
511bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v)
512{
513 v.clear();
514
515 if (m_statement)
516 finalize();
517 if (prepare() != SQLITE_OK)
518 return false;
519
520 while (step() == SQLITE_ROW)
521 v.append(getColumnDouble(col));
522 bool result = true;
523 if (m_database.lastError() != SQLITE_DONE) {
524 result = false;
525 LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
526 }
527 finalize();
528 return result;
529}
530
531bool SQLiteStatement::isExpired()
532{
533 return !m_statement;
534}
535
536} // namespace WebCore
537