e6d825471b45e1aee00193117033339abf76a6ea
[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::columnCount()
136 {
137     if (m_statement)
138         return sqlite3_column_count(m_statement);
139     return 0;
140 }
141
142 String SQLStatement::getColumnName(int col)
143 {
144     if (m_statement)
145         return String(sqlite3_column_name(m_statement, col));
146     return "";
147 }
148
149 String SQLStatement::getColumnName16(int col)
150 {
151     if (m_statement)
152         return String((const UChar*)sqlite3_column_name16(m_statement, col));
153     return "";
154 }
155     
156 String SQLStatement::getColumnText(int col)
157 {
158     if (m_statement)
159         return String((const char*)sqlite3_column_text(m_statement, col));
160     return "";
161 }
162
163 String SQLStatement::getColumnText16(int col)
164 {
165     if (m_statement)
166         return String((const UChar*)sqlite3_column_text16(m_statement, col));
167     return "";
168 }
169     
170 double SQLStatement::getColumnDouble(int col)
171 {
172     if (m_statement)
173         return sqlite3_column_double(m_statement, col);
174     return 0.0;
175 }
176
177 int SQLStatement::getColumnInt(int col)
178 {
179     if (m_statement)
180         return sqlite3_column_int(m_statement, col);
181     return 0;
182 }
183
184 int64_t SQLStatement::getColumnInt64(int col)
185 {
186     if (m_statement)
187         return sqlite3_column_int64(m_statement, col);
188     return 0;
189 }
190     
191 const void* SQLStatement::getColumnBlob(int col, int& size)
192 {
193     if (!m_statement) {
194         size = 0;
195         return 0;
196     }
197     const void* blob = sqlite3_column_blob(m_statement, col);
198     if (blob) {
199         size = sqlite3_column_bytes(m_statement, col);
200     } else
201         size = 0;
202     return blob;
203 }
204
205 bool SQLStatement::returnTextResults(int col, Vector<String>& v)
206 {
207     bool result = true;
208     if (m_statement)
209         finalize();
210     prepare();
211         
212     v.clear();
213     while (step() == SQLITE_ROW) {
214         v.append(getColumnText(col));
215     }
216     if (lastError() != SQLITE_DONE) {
217         result = false;
218         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
219     }
220     finalize();
221     return result;
222 }
223
224 bool SQLStatement::returnTextResults16(int col, Vector<String>& v)
225 {
226     bool result = true;
227     if (m_statement)
228         finalize();
229     prepare();
230         
231     v.clear();
232     while (step() == SQLITE_ROW) {
233         v.append(getColumnText16(col));
234     }
235     if (lastError() != SQLITE_DONE) {
236         result = false;
237         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
238     }
239     finalize();
240     return result;
241 }
242
243 bool SQLStatement::returnIntResults(int col, Vector<int>& v)
244 {
245     bool result = true;
246     if (m_statement)
247         finalize();
248     prepare();
249         
250     v.clear();
251     while (step() == SQLITE_ROW) {
252         v.append(getColumnInt(col));
253     }
254     if (lastError() != SQLITE_DONE) {
255         result = false;
256         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
257     }
258     finalize();
259     return result;
260 }
261
262 bool SQLStatement::returnInt64Results(int col, Vector<int64_t>& v)
263 {
264     bool result = true;
265     if (m_statement)
266         finalize();
267     prepare();
268         
269     v.clear();
270     while (step() == SQLITE_ROW) {
271         v.append(getColumnInt64(col));
272     }
273     if (lastError() != SQLITE_DONE) {
274         result = false;
275         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
276     }
277     finalize();
278     return result;
279 }
280
281 bool SQLStatement::returnDoubleResults(int col, Vector<double>& v)
282 {
283     bool result = true;
284     if (m_statement)
285         finalize();
286     prepare();
287         
288     v.clear();
289     while (step() == SQLITE_ROW) {
290         v.append(getColumnDouble(col));
291     }
292     if (lastError() != SQLITE_DONE) {
293         result = false;
294         LOG(IconDatabase, "Error reading results from database query %s", m_query.ascii().data());
295     }
296     finalize();
297     return result;
298 }
299
300 }; //namespace WebCore
301