Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / webdatabase / sqlite / SQLiteStatement.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple 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 "modules/webdatabase/sqlite/SQLiteStatement.h"
28
29 #include <sqlite3.h>
30 #include "platform/Logging.h"
31 #include "modules/webdatabase/sqlite/SQLValue.h"
32 #include "wtf/Assertions.h"
33 #include "wtf/text/CString.h"
34
35 // SQLite 3.6.16 makes sqlite3_prepare_v2 automatically retry preparing the statement
36 // once if the database scheme has changed. We rely on this behavior.
37 #if SQLITE_VERSION_NUMBER < 3006016
38 #error SQLite version 3.6.16 or newer is required
39 #endif
40
41 namespace blink {
42
43 SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, const String& sql)
44     : m_database(db)
45     , m_query(sql)
46     , m_statement(0)
47 #if ENABLE(ASSERT)
48     , m_isPrepared(false)
49 #endif
50 {
51 }
52
53 SQLiteStatement::~SQLiteStatement()
54 {
55     finalize();
56 }
57
58 int SQLiteStatement::prepare()
59 {
60     ASSERT(!m_isPrepared);
61
62     CString query = m_query.stripWhiteSpace().utf8();
63
64     ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
65
66     WTF_LOG(SQLDatabase, "SQL - prepare - %s", query.data());
67
68     // Pass the length of the string including the null character to sqlite3_prepare_v2;
69     // this lets SQLite avoid an extra string copy.
70     size_t lengthIncludingNullCharacter = query.length() + 1;
71
72     const char* tail = 0;
73     int error = sqlite3_prepare_v2(m_database.sqlite3Handle(), query.data(), lengthIncludingNullCharacter, &m_statement, &tail);
74
75     if (error != SQLITE_OK)
76         WTF_LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.data(), sqlite3_errmsg(m_database.sqlite3Handle()));
77     else if (tail && *tail)
78         error = SQLITE_ERROR;
79
80 #if ENABLE(ASSERT)
81     m_isPrepared = error == SQLITE_OK;
82 #endif
83     return error;
84 }
85
86 int SQLiteStatement::step()
87 {
88     ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
89     //ASSERT(m_isPrepared);
90
91     if (!m_statement)
92         return SQLITE_OK;
93
94     // The database needs to update its last changes count before each statement
95     // in order to compute properly the lastChanges() return value.
96     m_database.updateLastChangesCount();
97
98     WTF_LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
99     int error = sqlite3_step(m_statement);
100     if (error != SQLITE_DONE && error != SQLITE_ROW) {
101         WTF_LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
102             error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
103     }
104
105     return error;
106 }
107
108 int SQLiteStatement::finalize()
109 {
110 #if ENABLE(ASSERT)
111     m_isPrepared = false;
112 #endif
113     if (!m_statement)
114         return SQLITE_OK;
115     WTF_LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data());
116     int result = sqlite3_finalize(m_statement);
117     m_statement = 0;
118     return result;
119 }
120
121 bool SQLiteStatement::executeCommand()
122 {
123     if (!m_statement && prepare() != SQLITE_OK)
124         return false;
125     ASSERT(m_isPrepared);
126     if (step() != SQLITE_DONE) {
127         finalize();
128         return false;
129     }
130     finalize();
131     return true;
132 }
133
134 int SQLiteStatement::bindText(int index, const String& text)
135 {
136     ASSERT(m_isPrepared);
137     ASSERT(index > 0);
138     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
139
140     // SQLite treats uses zero pointers to represent null strings, which means we need to make sure to map null WTFStrings to zero pointers.
141     ASSERT(!String().charactersWithNullTermination().data());
142     return sqlite3_bind_text16(m_statement, index, text.charactersWithNullTermination().data(), sizeof(UChar) * text.length(), SQLITE_TRANSIENT);
143 }
144
145 int SQLiteStatement::bindDouble(int index, double number)
146 {
147     ASSERT(m_isPrepared);
148     ASSERT(index > 0);
149     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
150
151     return sqlite3_bind_double(m_statement, index, number);
152 }
153
154 int SQLiteStatement::bindNull(int index)
155 {
156     ASSERT(m_isPrepared);
157     ASSERT(index > 0);
158     ASSERT(static_cast<unsigned>(index) <= bindParameterCount());
159
160     return sqlite3_bind_null(m_statement, index);
161 }
162
163 int SQLiteStatement::bindValue(int index, const SQLValue& value)
164 {
165     switch (value.type()) {
166         case SQLValue::StringValue:
167             return bindText(index, value.string());
168         case SQLValue::NumberValue:
169             return bindDouble(index, value.number());
170         case SQLValue::NullValue:
171             return bindNull(index);
172     }
173
174     ASSERT_NOT_REACHED();
175     return SQLITE_ERROR;
176 }
177
178 unsigned SQLiteStatement::bindParameterCount() const
179 {
180     ASSERT(m_isPrepared);
181     if (!m_statement)
182         return 0;
183     return sqlite3_bind_parameter_count(m_statement);
184 }
185
186 int SQLiteStatement::columnCount()
187 {
188     ASSERT(m_isPrepared);
189     if (!m_statement)
190         return 0;
191     return sqlite3_data_count(m_statement);
192 }
193
194 String SQLiteStatement::getColumnName(int col)
195 {
196     ASSERT(col >= 0);
197     if (!m_statement)
198         if (prepareAndStep() != SQLITE_ROW)
199             return String();
200     if (columnCount() <= col)
201         return String();
202     return String(reinterpret_cast<const UChar*>(sqlite3_column_name16(m_statement, col)));
203 }
204
205 SQLValue SQLiteStatement::getColumnValue(int col)
206 {
207     ASSERT(col >= 0);
208     if (!m_statement)
209         if (prepareAndStep() != SQLITE_ROW)
210             return SQLValue();
211     if (columnCount() <= col)
212         return SQLValue();
213
214     // SQLite is typed per value. optional column types are
215     // "(mostly) ignored"
216     sqlite3_value* value = sqlite3_column_value(m_statement, col);
217     switch (sqlite3_value_type(value)) {
218         case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so use FLOAT -case
219         case SQLITE_FLOAT:
220             return SQLValue(sqlite3_value_double(value));
221         case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use TEXT -case
222         case SQLITE_TEXT: {
223             const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_text16(value));
224             unsigned length = WTF::lengthOfNullTerminatedString(string);
225             return SQLValue(StringImpl::create8BitIfPossible(string, length));
226         }
227         case SQLITE_NULL:
228             return SQLValue();
229         default:
230             break;
231     }
232     ASSERT_NOT_REACHED();
233     return SQLValue();
234 }
235
236 String SQLiteStatement::getColumnText(int col)
237 {
238     ASSERT(col >= 0);
239     if (!m_statement)
240         if (prepareAndStep() != SQLITE_ROW)
241             return String();
242     if (columnCount() <= col)
243         return String();
244     const UChar* string = reinterpret_cast<const UChar*>(sqlite3_column_text16(m_statement, col));
245     return StringImpl::create8BitIfPossible(string, sqlite3_column_bytes16(m_statement, col) / sizeof(UChar));
246 }
247
248 int SQLiteStatement::getColumnInt(int col)
249 {
250     ASSERT(col >= 0);
251     if (!m_statement)
252         if (prepareAndStep() != SQLITE_ROW)
253             return 0;
254     if (columnCount() <= col)
255         return 0;
256     return sqlite3_column_int(m_statement, col);
257 }
258
259 int64_t SQLiteStatement::getColumnInt64(int col)
260 {
261     ASSERT(col >= 0);
262     if (!m_statement)
263         if (prepareAndStep() != SQLITE_ROW)
264             return 0;
265     if (columnCount() <= col)
266         return 0;
267     return sqlite3_column_int64(m_statement, col);
268 }
269
270 } // namespace blink