• 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 "SQLiteStatement.h"
28 
29 #include "Logging.h"
30 #include "SQLValue.h"
31 #include <sqlite3.h>
32 #include <wtf/Assertions.h>
33 
34 namespace WebCore {
35 
36 #if SQLITE_VERSION_NUMBER < 3003009
37 
38 // FIXME: This overload helps us compile with older versions of SQLite 3, but things like quotas will not work.
sqlite3_prepare16_v2(sqlite3 * db,const void * zSql,int nBytes,sqlite3_stmt ** ppStmt,const void ** pzTail)39 static inline int sqlite3_prepare16_v2(sqlite3* db, const void* zSql, int nBytes, sqlite3_stmt** ppStmt, const void** pzTail)
40 {
41     return sqlite3_prepare16(db, zSql, nBytes, ppStmt, pzTail);
42 }
43 
44 #endif
45 
SQLiteStatement(SQLiteDatabase & db,const String & sql)46 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
47     : m_database(db)
48     , m_query(sql)
49     , m_statement(0)
50 #ifndef NDEBUG
51     , m_isPrepared(false)
52 #endif
53 {
54 }
55 
~SQLiteStatement()56 SQLiteStatement::~SQLiteStatement()
57 {
58     finalize();
59 }
60 
prepare()61 int SQLiteStatement::prepare()
62 {
63     ASSERT(!m_isPrepared);
64     const void* tail;
65     LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
66     int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.charactersWithNullTermination(), -1, &m_statement, &tail);
67     if (error != SQLITE_OK)
68         LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
69 #ifndef NDEBUG
70     m_isPrepared = error == SQLITE_OK;
71 #endif
72     return error;
73 }
74 
step()75 int SQLiteStatement::step()
76 {
77     ASSERT(m_isPrepared);
78     if (!m_statement)
79         return SQLITE_OK;
80     LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
81     int error = sqlite3_step(m_statement);
82     if (error != SQLITE_DONE && error != SQLITE_ROW) {
83         LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
84             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
85     }
86     return error;
87 }
88 
finalize()89 int SQLiteStatement::finalize()
90 {
91 #ifndef NDEBUG
92     m_isPrepared = false;
93 #endif
94     if (!m_statement)
95         return SQLITE_OK;
96     LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
97     int result = sqlite3_finalize(m_statement);
98     m_statement = 0;
99     return result;
100 }
101 
reset()102 int SQLiteStatement::reset()
103 {
104     ASSERT(m_isPrepared);
105     if (!m_statement)
106         return SQLITE_OK;
107     LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data());
108     return sqlite3_reset(m_statement);
109 }
110 
executeCommand()111 bool SQLiteStatement::executeCommand()
112 {
113     if (!m_statement && prepare() != SQLITE_OK)
114         return false;
115     ASSERT(m_isPrepared);
116     if (step() != SQLITE_DONE) {
117         finalize();
118         return false;
119     }
120     finalize();
121     return true;
122 }
123 
returnsAtLeastOneResult()124 bool SQLiteStatement::returnsAtLeastOneResult()
125 {
126     if (!m_statement && prepare() != SQLITE_OK)
127         return false;
128     ASSERT(m_isPrepared);
129     if (step() != SQLITE_ROW) {
130         finalize();
131         return false;
132     }
133     finalize();
134     return true;
135 
136 }
137 
bindBlob(int index,const void * blob,int size)138 int SQLiteStatement::bindBlob(int index, const void* blob, int size)
139 {
140     ASSERT(m_isPrepared);
141     ASSERT(index > 0);
142     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
143     ASSERT(blob);
144     ASSERT(size >= 0);
145 
146     if (!m_statement)
147         return SQLITE_ERROR;
148 
149     return sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
150 }
151 
bindText(int index,const String & text)152 int SQLiteStatement::bindText(int index, const String& text)
153 {
154     ASSERT(m_isPrepared);
155     ASSERT(index > 0);
156     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
157 
158     // String::characters() returns 0 for the empty string, which SQLite
159     // treats as a null, so we supply a non-null pointer for that case.
160     UChar anyCharacter = 0;
161     const UChar* characters;
162     if (text.isEmpty() && !text.isNull())
163         characters = &anyCharacter;
164     else
165         characters = text.characters();
166 
167     return sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
168 }
169 
170 
bindInt64(int index,int64_t integer)171 int SQLiteStatement::bindInt64(int index, int64_t integer)
172 {
173     ASSERT(m_isPrepared);
174     ASSERT(index > 0);
175     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
176 
177     return sqlite3_bind_int64(m_statement, index, integer);
178 }
179 
bindDouble(int index,double number)180 int SQLiteStatement::bindDouble(int index, double number)
181 {
182     ASSERT(m_isPrepared);
183     ASSERT(index > 0);
184     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
185 
186     return sqlite3_bind_double(m_statement, index, number);
187 }
188 
bindNull(int index)189 int SQLiteStatement::bindNull(int index)
190 {
191     ASSERT(m_isPrepared);
192     ASSERT(index > 0);
193     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
194 
195     return sqlite3_bind_null(m_statement, index);
196 }
197 
bindValue(int index,const SQLValue & value)198 int SQLiteStatement::bindValue(int index, const SQLValue& value)
199 {
200     switch (value.type()) {
201         case SQLValue::StringValue:
202             return bindText(index, value.string());
203         case SQLValue::NumberValue:
204             return bindDouble(index, value.number());
205         case SQLValue::NullValue:
206             return bindNull(index);
207     }
208 
209     ASSERT_NOT_REACHED();
210     return SQLITE_ERROR;
211 }
212 
bindParameterCount() const213 unsigned SQLiteStatement::bindParameterCount() const
214 {
215     ASSERT(m_isPrepared);
216     if (!m_statement)
217         return 0;
218     return sqlite3_bind_parameter_count(m_statement);
219 }
220 
columnCount()221 int SQLiteStatement::columnCount()
222 {
223     ASSERT(m_isPrepared);
224     if (!m_statement)
225         return 0;
226     return sqlite3_data_count(m_statement);
227 }
228 
getColumnName(int col)229 String SQLiteStatement::getColumnName(int col)
230 {
231     ASSERT(col >= 0);
232     if (!m_statement)
233         if (prepareAndStep() != SQLITE_ROW)
234             return String();
235     if (columnCount() <= col)
236         return String();
237     return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
238 }
239 
getColumnValue(int col)240 SQLValue SQLiteStatement::getColumnValue(int col)
241 {
242     ASSERT(col >= 0);
243     if (!m_statement)
244         if (prepareAndStep() != SQLITE_ROW)
245             return SQLValue();
246     if (columnCount() <= col)
247         return SQLValue();
248 
249     // SQLite is typed per value. optional column types are
250     // "(mostly) ignored"
251     sqlite3_value* value = sqlite3_column_value(m_statement, col);
252     switch (sqlite3_value_type(value)) {
253         case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so use FLOAT -case
254         case SQLITE_FLOAT:
255             return SQLValue(sqlite3_value_double(value));
256         case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use TEXT -case
257         case SQLITE_TEXT:
258             return SQLValue(String(reinterpret_cast<const UChar*>(sqlite3_value_text16(value))));
259         case SQLITE_NULL:
260             return SQLValue();
261         default:
262             break;
263     }
264     ASSERT_NOT_REACHED();
265     return SQLValue();
266 }
267 
getColumnText(int col)268 String SQLiteStatement::getColumnText(int col)
269 {
270     ASSERT(col >= 0);
271     if (!m_statement)
272         if (prepareAndStep() != SQLITE_ROW)
273             return String();
274     if (columnCount() <= col)
275         return String();
276     return String(reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col)));
277 }
278 
getColumnDouble(int col)279 double SQLiteStatement::getColumnDouble(int col)
280 {
281     ASSERT(col >= 0);
282     if (!m_statement)
283         if (prepareAndStep() != SQLITE_ROW)
284             return 0.0;
285     if (columnCount() <= col)
286         return 0.0;
287     return sqlite3_column_double(m_statement, col);
288 }
289 
getColumnInt(int col)290 int SQLiteStatement::getColumnInt(int col)
291 {
292     ASSERT(col >= 0);
293     if (!m_statement)
294         if (prepareAndStep() != SQLITE_ROW)
295             return 0;
296     if (columnCount() <= col)
297         return 0;
298     return sqlite3_column_int(m_statement, col);
299 }
300 
getColumnInt64(int col)301 int64_t SQLiteStatement::getColumnInt64(int col)
302 {
303     ASSERT(col >= 0);
304     if (!m_statement)
305         if (prepareAndStep() != SQLITE_ROW)
306             return 0;
307     if (columnCount() <= col)
308         return 0;
309     return sqlite3_column_int64(m_statement, col);
310 }
311 
getColumnBlobAsVector(int col,Vector<char> & result)312 void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
313 {
314     ASSERT(col >= 0);
315 
316     if (!m_statement && prepareAndStep() != SQLITE_ROW) {
317         result.clear();
318         return;
319     }
320 
321     if (columnCount() <= col) {
322         result.clear();
323         return;
324     }
325 
326     const void* blob = sqlite3_column_blob(m_statement, col);
327     if (!blob) {
328         result.clear();
329         return;
330     }
331 
332     int size = sqlite3_column_bytes(m_statement, col);
333     result.resize((size_t)size);
334     for (int i = 0; i < size; ++i)
335         result[i] = ((const unsigned char*)blob)[i];
336 }
337 
getColumnBlob(int col,int & size)338 const void* SQLiteStatement::getColumnBlob(int col, int& size)
339 {
340     ASSERT(col >= 0);
341 
342     size = 0;
343 
344     if (finalize() != SQLITE_OK)
345         LOG(SQLDatabase, "Finalize failed");
346     if (prepare() != SQLITE_OK) {
347         LOG(SQLDatabase, "Prepare failed");
348         return 0;
349     }
350     if (step() != SQLITE_ROW) {
351         LOG(SQLDatabase, "Step wasn't a row");
352         return 0;
353     }
354 
355     if (columnCount() <= col)
356         return 0;
357 
358     const void* blob = sqlite3_column_blob(m_statement, col);
359     if (!blob)
360         return 0;
361 
362     size = sqlite3_column_bytes(m_statement, col);
363     return blob;
364 }
365 
returnTextResults(int col,Vector<String> & v)366 bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
367 {
368     ASSERT(col >= 0);
369 
370     v.clear();
371 
372     if (m_statement)
373         finalize();
374     if (prepare() != SQLITE_OK)
375         return false;
376 
377     while (step() == SQLITE_ROW)
378         v.append(getColumnText(col));
379     bool result = true;
380     if (m_database.lastError() != SQLITE_DONE) {
381         result = false;
382         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
383     }
384     finalize();
385     return result;
386 }
387 
returnIntResults(int col,Vector<int> & v)388 bool SQLiteStatement::returnIntResults(int col, Vector<int>& v)
389 {
390     v.clear();
391 
392     if (m_statement)
393         finalize();
394     if (prepare() != SQLITE_OK)
395         return false;
396 
397     while (step() == SQLITE_ROW)
398         v.append(getColumnInt(col));
399     bool result = true;
400     if (m_database.lastError() != SQLITE_DONE) {
401         result = false;
402         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
403     }
404     finalize();
405     return result;
406 }
407 
returnInt64Results(int col,Vector<int64_t> & v)408 bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v)
409 {
410     v.clear();
411 
412     if (m_statement)
413         finalize();
414     if (prepare() != SQLITE_OK)
415         return false;
416 
417     while (step() == SQLITE_ROW)
418         v.append(getColumnInt64(col));
419     bool result = true;
420     if (m_database.lastError() != SQLITE_DONE) {
421         result = false;
422         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
423     }
424     finalize();
425     return result;
426 }
427 
returnDoubleResults(int col,Vector<double> & v)428 bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v)
429 {
430     v.clear();
431 
432     if (m_statement)
433         finalize();
434     if (prepare() != SQLITE_OK)
435         return false;
436 
437     while (step() == SQLITE_ROW)
438         v.append(getColumnDouble(col));
439     bool result = true;
440     if (m_database.lastError() != SQLITE_DONE) {
441         result = false;
442         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
443     }
444     finalize();
445     return result;
446 }
447 
isExpired()448 bool SQLiteStatement::isExpired()
449 {
450     return !m_statement || sqlite3_expired(m_statement);
451 }
452 
453 } // namespace WebCore
454