Reviewed by Levi
[WebKit-https.git] / WebCore / icon / SQLStatement.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 "SQLDatabase.h"
27
28 #include <wtf/Assertions.h>
29 #include "Logging.h"
30
31 namespace WebCore {
32
33 SQLStatement::SQLStatement(SQLDatabase& db, const String& sql)
34     : m_database(db)
35     , m_query(sql)
36     , m_statement(0)
37 {
38     m_query.append(UChar(0));
39 }
40
41 SQLStatement::~SQLStatement()
42 {
43     finalize();
44 }
45
46 int SQLStatement::prepare()
47 {    
48     const void* tail;
49     if (sqlite3_prepare16(m_database.m_db, m_query.characters(), -1, &m_statement, &tail) != SQLITE_OK) {
50         LOG(IconDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", lastError(), m_query.ascii().data(), sqlite3_errmsg(m_database.m_db));
51         m_statement = 0;
52     }
53     return lastError();
54 }
55     
56 int SQLStatement::step()
57 {
58     if (!isPrepared())
59         return SQLITE_ERROR;
60         
61     int error = sqlite3_step(m_statement);
62     if (error != SQLITE_DONE && error != SQLITE_ROW) {
63         LOG(IconDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s", 
64             error, m_query.ascii().data(), sqlite3_errmsg(m_database.m_db));
65     }
66     return error;
67 }
68     
69 int SQLStatement::finalize()
70 {
71     if (m_statement) {
72         int result = sqlite3_finalize(m_statement);
73         m_statement = 0;
74         return result;
75     }
76     return lastError();
77 }
78
79 int SQLStatement::reset()
80 {
81     if (m_statement) {
82         return sqlite3_reset(m_statement);
83     }
84     return SQLITE_ERROR;
85 }
86
87 bool SQLStatement::executeCommand()
88 {
89     if (!isPrepared())
90         if (prepare() != SQLITE_OK)
91             return false;
92     if (step() != SQLITE_DONE) {
93         finalize();
94         return false;
95     }
96     finalize();
97     return true;
98 }
99
100 bool SQLStatement::returnsAtLeastOneResult()
101 {
102     if (!isPrepared())
103         if (prepare() != SQLITE_OK)
104             return false;
105     if (step() != SQLITE_ROW) {
106         finalize();
107         return false;
108     }
109     finalize();
110     return true;
111
112 }
113
114 int SQLStatement::bindBlob(int index, const void* blob, int size, bool copy)
115 {
116     ASSERT(blob);
117     ASSERT(size > -1);
118     if (copy)
119         sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_TRANSIENT);
120     else
121         sqlite3_bind_blob(m_statement, index, blob, size, SQLITE_STATIC);
122     return lastError();
123 }
124
125 int SQLStatement::bindText(int index, const char* text, bool copy)
126 {
127     ASSERT(text);
128     if (copy)
129         sqlite3_bind_text(m_statement, index, text, strlen(text), SQLITE_TRANSIENT);
130     else
131         sqlite3_bind_text(m_statement, index, text, strlen(text), SQLITE_STATIC);
132     return lastError();
133 }
134
135 int SQLStatement::bindInt64(int index, int64_t integer)
136 {
137     return sqlite3_bind_int64(m_statement, index, integer);
138 }
139
140 int SQLStatement::columnCount()
141 {
142     if (m_statement)
143         return sqlite3_column_count(m_statement);
144     return 0;
145 }
146
147 String SQLStatement::getColumnName(int col)
148 {
149     if (!m_statement)
150         if (prepareAndStep() != SQLITE_ROW)
151             return "";
152     if (columnCount() <= col)
153         return "";
154         
155     return String(sqlite3_column_name(m_statement, col));
156 }
157
158 String SQLStatement::getColumnName16(int col)
159 {
160     if (!m_statement)
161         if (prepareAndStep() != SQLITE_ROW)
162             return "";
163     if (columnCount() <= col)
164         return "";
165     return String((const UChar*)sqlite3_column_name16(m_statement, col));
166 }
167     
168 String SQLStatement::getColumnText(int col)
169 {
170     if (!m_statement)
171         if (prepareAndStep() != SQLITE_ROW)
172             return "";
173     if (columnCount() <= col)
174         return "";
175     return String((const char*)sqlite3_column_text(m_statement, col));
176 }
177
178 String SQLStatement::getColumnText16(int col)
179 {
180     if (!m_statement)
181         if (prepareAndStep() != SQLITE_ROW)
182             return "";
183     if (columnCount() <= col)
184         return "";
185     return String((const UChar*)sqlite3_column_text16(m_statement, col));
186 }
187     
188 double SQLStatement::getColumnDouble(int col)
189 {
190     if (!m_statement)
191         if (prepareAndStep() != SQLITE_ROW)
192             return 0.0;
193     if (columnCount() <= col)
194         return 0.0;
195     return sqlite3_column_double(m_statement, col);
196 }
197
198 int SQLStatement::getColumnInt(int col)
199 {
200     if (!m_statement)
201         if (prepareAndStep() != SQLITE_ROW)
202             return 0;
203     if (columnCount() <= col)
204         return 0;
205     return sqlite3_column_int(m_statement, col);
206 }
207
208 int64_t SQLStatement::getColumnInt64(int col)
209 {
210     if (!m_statement)
211         if (prepareAndStep() != SQLITE_ROW)
212             return 0;
213     if (columnCount() <= col)
214         return 0;
215     return sqlite3_column_int64(m_statement, col);
216 }
217     
218 Vector<char> SQLStatement::getColumnBlobAsVector(int col)
219 {
220     if (!m_statement)
221         if (prepareAndStep() != SQLITE_ROW)
222             return Vector<char>();
223     if (columnCount() <= col)
224         return Vector<char>();
225  
226     const void* blob = sqlite3_column_blob(m_statement, col);
227     if (blob) {
228         int size = sqlite3_column_bytes(m_statement, col);
229         Vector<char> result((size_t)size);
230         for (int i = 0; i < size; ++i)
231             result[i] = ((const char*)blob)[i];
232         return result;
233     } 
234     return Vector<char>();
235 }
236
237 const void* SQLStatement::getColumnBlob(int col, int& size)
238 {
239     if (!m_statement)
240         if (prepareAndStep() != SQLITE_ROW) {
241             size = 0;
242             return 0;
243         }
244     if (columnCount() <= col) {
245         size = 0;
246         return 0;
247     }
248         
249     const void* blob = sqlite3_column_blob(m_statement, col);
250     if (blob) {
251         size = sqlite3_column_bytes(m_statement, col);
252         return blob;
253     } 
254     size = 0;
255     return 0;
256 }
257
258 bool SQLStatement::returnTextResults(int col, Vector<String>& v)
259 {
260     bool result = true;
261     if (m_statement)
262         finalize();
263     prepare();
264         
265     v.clear();
266     while (step() == SQLITE_ROW) {
267         v.append(getColumnText(col));
268     }
269     if (lastError() != SQLITE_DONE) {
270         result = false;
271         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
272     }
273     finalize();
274     return result;
275 }
276
277 bool SQLStatement::returnTextResults16(int col, Vector<String>& v)
278 {
279     bool result = true;
280     if (m_statement)
281         finalize();
282     prepare();
283         
284     v.clear();
285     while (step() == SQLITE_ROW) {
286         v.append(getColumnText16(col));
287     }
288     if (lastError() != SQLITE_DONE) {
289         result = false;
290         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
291     }
292     finalize();
293     return result;
294 }
295
296 bool SQLStatement::returnIntResults(int col, Vector<int>& v)
297 {
298     bool result = true;
299     if (m_statement)
300         finalize();
301     prepare();
302         
303     v.clear();
304     while (step() == SQLITE_ROW) {
305         v.append(getColumnInt(col));
306     }
307     if (lastError() != SQLITE_DONE) {
308         result = false;
309         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
310     }
311     finalize();
312     return result;
313 }
314
315 bool SQLStatement::returnInt64Results(int col, Vector<int64_t>& 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(getColumnInt64(col));
325     }
326     if (lastError() != SQLITE_DONE) {
327         result = false;
328         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
329     }
330     finalize();
331     return result;
332 }
333
334 bool SQLStatement::returnDoubleResults(int col, Vector<double>& 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(getColumnDouble(col));
344     }
345     if (lastError() != SQLITE_DONE) {
346         result = false;
347         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
348     }
349     finalize();
350     return result;
351 }
352
353 }; // namespace WebCore
354