sqlite/sqlitepreparedstatement.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "sqlitepreparedstatement.h"
21
22#include <kdebug.h>
23#include <assert.h>
24
25using namespace KexiDB;
26
28 FieldList& fields)
29 : KexiDB::PreparedStatement(type, conn, fields)
30 , SQLiteConnectionInternal(conn.connection)
31 , prepared_st_handle(0)
32 , m_resetRequired(false)
33{
34 data_owned = false;
35 data = dynamic_cast<KexiDB::SQLiteConnectionInternal&>(conn).data; //copy
36
37 temp_st = generateStatementString();
38#ifdef SQLITE2
40#else
41 if (!temp_st.isEmpty()) {
42 res = sqlite3_prepare(
43 data, /* Database handle */
44 temp_st, //const char *zSql, /* SQL statement, UTF-8 encoded */
45 temp_st.length(), //int nBytes, /* Length of zSql in bytes. */
46 &prepared_st_handle, //sqlite3_stmt **ppStmt, /* OUT: Statement handle */
47 0 //const char **pzTail /* OUT: Pointer to unused portion of zSql */
48 );
49 if (SQLITE_OK != res) {
51 }
52 }
53#endif
54}
55
56SQLitePreparedStatement::~SQLitePreparedStatement()
57{
58#ifdef SQLITE2
60#else
61 sqlite3_finalize(prepared_st_handle);
62 prepared_st_handle = 0;
63#endif
64}
65
67{
68#ifdef SQLITE2
70#else
71 if (!prepared_st_handle)
72 return false;
73 if (m_resetRequired) {
74 res = sqlite3_reset(prepared_st_handle);
75 if (SQLITE_OK != res) {
77 return false;
78 }
79 m_resetRequired = false;
80 }
81
82 int arg=1; //arg index counted from 1
83 KexiDB::Field *field;
84
87 //for INSERT, we're iterating over inserting values
88 //for SELECT, we're iterating over WHERE conditions
89 if (m_type == SelectStatement)
90 itFields = *m_whereFields;
91 else if (m_type == InsertStatement)
92 itFields = m_fields->fieldsIterator();
93 else
94 assert(0); //impl. error
95
96 for (TQValueListConstIterator<TQVariant> it = m_args.constBegin();
97 (field = itFields.current()); ++it, ++itFields, arg++)
98 {
99 if (it==m_args.constEnd() || (*it).isNull()) {//no value to bind or the value is null: bind NULL
100 res = sqlite3_bind_null(prepared_st_handle, arg);
101 if (SQLITE_OK != res) {
103 return false;
104 }
105 continue;
106 }
107 if (field->isTextType()) {
109 TQCString utf8String((*it).toString().utf8());
110 res = sqlite3_bind_text(prepared_st_handle, arg,
111 (const char*)utf8String, utf8String.length(), SQLITE_TRANSIENT /*??*/);
112 if (SQLITE_OK != res) {
114 return false;
115 }
116 }
117 else switch (field->type()) {
121 {
123 bool ok;
124 const int value = (*it).toInt(&ok);
125 if (ok) {
126 res = sqlite3_bind_int(prepared_st_handle, arg, value);
127 if (SQLITE_OK != res) {
129 return false;
130 }
131 }
132 else {
133 res = sqlite3_bind_null(prepared_st_handle, arg);
134 if (SQLITE_OK != res) {
136 return false;
137 }
138 }
139 break;
140 }
143 res = sqlite3_bind_double(prepared_st_handle, arg, (*it).toDouble());
144 if (SQLITE_OK != res) {
146 return false;
147 }
148 break;
150 {
152 bool ok;
153 TQ_LLONG value = (*it).toLongLong(&ok);
154 if (ok) {
155 res = sqlite3_bind_int64(prepared_st_handle, arg, value);
156 if (SQLITE_OK != res) {
158 return false;
159 }
160 }
161 else {
162 res = sqlite3_bind_null(prepared_st_handle, arg);
163 if (SQLITE_OK != res) {
165 return false;
166 }
167 }
168 break;
169 }
171 res = sqlite3_bind_text(prepared_st_handle, arg,
172 TQString::number((*it).toBool() ? 1 : 0).latin1(),
173 1, SQLITE_TRANSIENT /*??*/);
174 if (SQLITE_OK != res) {
176 return false;
177 }
178 break;
179 case KexiDB::Field::Time:
180 res = sqlite3_bind_text(prepared_st_handle, arg,
181 TQString((*it).toTime().toString(TQt::ISODate)).latin1(),
182 sizeof("HH:MM:SS"), SQLITE_TRANSIENT /*??*/);
183 if (SQLITE_OK != res) {
185 return false;
186 }
187 break;
188 case KexiDB::Field::Date:
189 res = sqlite3_bind_text(prepared_st_handle, arg,
190 TQString((*it).toDate().toString(TQt::ISODate)).latin1(),
191 sizeof("YYYY-MM-DD"), SQLITE_TRANSIENT /*??*/);
192 if (SQLITE_OK != res) {
194 return false;
195 }
196 break;
197 case KexiDB::Field::DateTime:
198 res = sqlite3_bind_text(prepared_st_handle, arg,
199 (*it).toDateTime().toString(TQt::ISODate).latin1(),
200 sizeof("YYYY-MM-DDTHH:MM:SS"), SQLITE_TRANSIENT /*??*/);
201 if (SQLITE_OK != res) {
203 return false;
204 }
205 break;
207 {
208 const TQByteArray byteArray((*it).toByteArray());
209 res = sqlite3_bind_blob(prepared_st_handle, arg,
210 (const char*)byteArray, byteArray.size(), SQLITE_TRANSIENT /*??*/);
211 if (SQLITE_OK != res) {
213 return false;
214 }
215 break;
216 }
217 default:
218 KexiDBWarn << "PreparedStatement::execute(): unsupported field type: "
219 << field->type() << " - NULL value bound to column #" << arg << endl;
220 res = sqlite3_bind_null(prepared_st_handle, arg);
221 if (SQLITE_OK != res) {
223 return false;
224 }
225 } //switch
226 }
227
228 //real execution
229 res = sqlite3_step(prepared_st_handle);
230 m_resetRequired = true;
231 if (m_type == InsertStatement && res == SQLITE_DONE) {
232 return true;
233 }
234 if (m_type == SelectStatement) {
235 //fetch result
236
237 //todo
238 }
239#endif
240 return false;
241}
242
Meta-data for a field.
Definition field.h:73
Type type() const
Definition field.cpp:134
@ ShortInteger
Definition field.h:86
TQPtrList< Field > List
list of fields
Definition field.h:75
TQPtrListIterator< Field > ListIterator
iterator for list of fields
Definition field.h:77
bool isTextType() const
Definition field.h:280
Prepared database command for optimizing sequences of multiple database actions.
StatementType
Defines type of the prepared statement.
@ InsertStatement
INSERT statement will be prepared end executed.
@ SelectStatement
SELECT statement will be prepared end executed.
SQLitePreparedStatement(StatementType type, ConnectionInternal &conn, FieldList &fields)
High-level database connectivity library with database backend drivers.
static bool _dummy
Definition driver_p.cpp:34