e5bde172732d34a1c50febf83f3b16cd450214f9
[WebKit-https.git] / WebCore / platform / sql / SQLiteStatement.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, 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 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
37     : m_database(db)
38     , m_query(sql)
39     , m_statement(0)
40 {
41     m_query.append(UChar(0));
42 }
43
44 SQLiteStatement::~SQLiteStatement()
45 {
46     finalize();
47 }
48
49 int SQLiteStatement::prepare()
50 {    
51     const void* tail;
52     LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
53 #if SQLITE_VERSION_NUMBER > 3003000 
54     if (sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.characters(), -1, &m_statement, &tail) != SQLITE_OK) {
55 #else
56     if (sqlite3_prepare16(m_database.sqlite3Handle(), m_query.characters(), -1, &m_statement, &tail) != SQLITE_OK) {
57 #endif
58         LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", lastError(), m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
59         m_statement = 0;
60     }
61     return lastError();
62 }
63     
64 int SQLiteStatement::step()
65 {
66     if (!isPrepared())
67         return SQLITE_ERROR;
68     LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
69     int error = sqlite3_step(m_statement);
70     if (error != SQLITE_DONE && error != SQLITE_ROW) {
71         LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s", 
72             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
73     }
74     return error;
75 }
76     
77 int SQLiteStatement::finalize()
78 {
79     if (m_statement) {
80         LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
81         int result = sqlite3_finalize(m_statement);
82         m_statement = 0;
83         return result;
84     }
85     return lastError();
86 }
87
88 int SQLiteStatement::reset() 
89 {
90     if (m_statement) {
91         LOG(SQLDatabase, "SQL - reset - %s", m_query.ascii().data());
92         return sqlite3_reset(m_statement);
93     }
94     return SQLITE_ERROR;
95 }
96
97 bool SQLiteStatement::executeCommand()
98 {
99     if (!isPrepared())
100         if (prepare() != SQLITE_OK)
101             return false;
102     if (step() != SQLITE_DONE) {
103         finalize();
104         return false;
105     }
106     finalize();
107     return true;
108 }
109
110 bool SQLiteStatement::returnsAtLeastOneResult()
111 {
112     if (!isPrepared())
113         if (prepare() != SQLITE_OK)
114             return false;
115     if (step() != SQLITE_ROW) {
116         finalize();
117         return false;
118     }
119     finalize();
120     return true;
121
122 }
123
124 int SQLiteStatement::bindBlob(int index, const void* blob, int size)
125 {
126     ASSERT(blob);
127     ASSERT(size > -1);
128
129     sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
130
131     return lastError();
132 }
133
134 int SQLiteStatement::bindText(int index, const String& text)
135 {
136     static const UChar emptyString[1] = { 0 };
137     const UChar* characters;
138     
139     // String::characters() returns 0 for the empty string
140     // which SQLite treats as a null string so we translate it to a
141     // "real" empty string here.
142     if (!text.isNull() && text.isEmpty())
143         characters = emptyString;
144     else
145         characters = text.characters();
146     
147     sqlite3_bind_text16(m_statement, index, characters, sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
148     return lastError();
149 }
150
151
152 int SQLiteStatement::bindInt64(int index, int64_t integer)
153 {
154     return sqlite3_bind_int64(m_statement, index, integer);
155 }
156
157 int SQLiteStatement::bindDouble(int index, double number)
158 {
159     return sqlite3_bind_double(m_statement, index, number);
160 }
161
162 int SQLiteStatement::bindNull(int index)
163 {
164     return sqlite3_bind_null(m_statement, index);
165 }
166
167 int SQLiteStatement::bindValue(int index, const SQLValue& value)
168 {
169     switch (value.type()) {
170         case SQLValue::StringValue:
171             return bindText(index, value.string());
172         case SQLValue::NumberValue:
173             return bindDouble(index, value.number());
174         case SQLValue::NullValue:
175             return bindNull(index);
176         default:
177             ASSERT_NOT_REACHED();
178             // To keep the compiler happy
179             return SQLITE_ERROR;
180     }
181 }
182
183 unsigned SQLiteStatement::bindParameterCount() const
184 {
185     ASSERT(isPrepared());
186     return sqlite3_bind_parameter_count(m_statement);
187 }
188
189 int SQLiteStatement::columnCount()
190 {
191     if (m_statement)
192         return sqlite3_data_count(m_statement);
193     return 0;
194 }
195
196 String SQLiteStatement::getColumnName(int col)
197 {
198     if (!m_statement)
199         if (prepareAndStep() != SQLITE_ROW)
200             return String();
201     if (columnCount() <= col)
202         return String();
203         
204     return String(sqlite3_column_name(m_statement, col));
205 }
206
207 String SQLiteStatement::getColumnName16(int col)
208 {
209     if (!m_statement)
210         if (prepareAndStep() != SQLITE_ROW)
211             return String();
212     if (columnCount() <= col)
213         return String();
214     return String((const UChar*)sqlite3_column_name16(m_statement, col));
215 }
216     
217 String SQLiteStatement::getColumnText(int col)
218 {
219     if (!m_statement)
220         if (prepareAndStep() != SQLITE_ROW)
221             return String();
222     if (columnCount() <= col)
223         return String();
224     return String((const char*)sqlite3_column_text(m_statement, col));
225 }
226
227 String SQLiteStatement::getColumnText16(int col)
228 {
229     if (!m_statement)
230         if (prepareAndStep() != SQLITE_ROW)
231             return String();
232     if (columnCount() <= col)
233         return String();
234     return String((const UChar*)sqlite3_column_text16(m_statement, col));
235 }
236     
237 double SQLiteStatement::getColumnDouble(int col)
238 {
239     if (!m_statement)
240         if (prepareAndStep() != SQLITE_ROW)
241             return 0.0;
242     if (columnCount() <= col)
243         return 0.0;
244     return sqlite3_column_double(m_statement, col);
245 }
246
247 int SQLiteStatement::getColumnInt(int col)
248 {
249     if (!m_statement)
250         if (prepareAndStep() != SQLITE_ROW)
251             return 0;
252     if (columnCount() <= col)
253         return 0;
254     return sqlite3_column_int(m_statement, col);
255 }
256
257 int64_t SQLiteStatement::getColumnInt64(int col)
258 {
259     if (!m_statement)
260         if (prepareAndStep() != SQLITE_ROW)
261             return 0;
262     if (columnCount() <= col)
263         return 0;
264     return sqlite3_column_int64(m_statement, col);
265 }
266     
267 void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
268 {
269     if (!m_statement && prepareAndStep() != SQLITE_ROW) {
270         result.clear();
271         return;
272     }
273
274     if (columnCount() <= col) {
275         result.clear();
276         return;
277     }
278
279  
280     const void* blob = sqlite3_column_blob(m_statement, col);
281     if (!blob) {
282         result.clear();
283         return;
284     }
285         
286     int size = sqlite3_column_bytes(m_statement, col);
287     result.resize((size_t)size);
288     for (int i = 0; i < size; ++i)
289         result[i] = ((const unsigned char*)blob)[i];
290 }
291
292 const void* SQLiteStatement::getColumnBlob(int col, int& size)
293 {
294     if (finalize() != SQLITE_OK)
295         LOG(SQLDatabase, "Finalize failed");
296     if (prepare() != SQLITE_OK)
297         LOG(SQLDatabase, "Prepare failed");
298     if (step() != SQLITE_ROW)
299         {LOG(SQLDatabase, "Step wasn't a row");size=0;return 0;}
300
301     if (columnCount() <= col) {
302         size = 0;
303         return 0;
304     }
305         
306     const void* blob = sqlite3_column_blob(m_statement, col);
307     if (blob) {
308         size = sqlite3_column_bytes(m_statement, col);
309         return blob;
310     } 
311     size = 0;
312     return 0;
313 }
314
315 bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
316 {
317     bool result = true;
318     if (m_statement)
319         finalize();
320     prepare();
321         
322     v.clear();
323     while (step() == SQLITE_ROW) {
324         v.append(getColumnText(col));
325     }
326     if (lastError() != SQLITE_DONE) {
327         result = false;
328         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
329     }
330     finalize();
331     return result;
332 }
333
334 bool SQLiteStatement::returnTextResults16(int col, Vector<String>& v)
335 {
336     bool result = true;
337     if (m_statement)
338         finalize();
339     prepare();
340         
341     v.clear();
342     while (step() == SQLITE_ROW) {
343         v.append(getColumnText16(col));
344     }
345     if (lastError() != SQLITE_DONE) {
346         result = false;
347         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
348     }
349     finalize();
350     return result;
351 }
352
353 bool SQLiteStatement::returnIntResults(int col, Vector<int>& v)
354 {
355     bool result = true;
356     if (m_statement)
357         finalize();
358     prepare();
359         
360     v.clear();
361     while (step() == SQLITE_ROW) {
362         v.append(getColumnInt(col));
363     }
364     if (lastError() != SQLITE_DONE) {
365         result = false;
366         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
367     }
368     finalize();
369     return result;
370 }
371
372 bool SQLiteStatement::returnInt64Results(int col, Vector<int64_t>& v)
373 {
374     bool result = true;
375     if (m_statement)
376         finalize();
377     prepare();
378         
379     v.clear();
380     while (step() == SQLITE_ROW) {
381         v.append(getColumnInt64(col));
382     }
383     if (lastError() != SQLITE_DONE) {
384         result = false;
385         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
386     }
387     finalize();
388     return result;
389 }
390
391 bool SQLiteStatement::returnDoubleResults(int col, Vector<double>& v)
392 {
393     bool result = true;
394     if (m_statement)
395         finalize();
396     prepare();
397         
398     v.clear();
399     while (step() == SQLITE_ROW) {
400         v.append(getColumnDouble(col));
401     }
402     if (lastError() != SQLITE_DONE) {
403         result = false;
404         LOG(SQLDatabase, "Error reading results from database query %s", m_query.ascii().data());
405     }
406     finalize();
407     return result;
408 }
409
410 bool SQLiteStatement::isExpired()
411 {
412     return m_statement ? sqlite3_expired(m_statement) : true;
413 }
414
415 } // namespace WebCore