• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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