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