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