KDb

SqlitePreparedStatement.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005-2012 Jarosław Staniek <staniek@kde.org>
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#include "KDbPreparedStatement.h"
22#include "sqlite_debug.h"
23
24SqlitePreparedStatement::SqlitePreparedStatement(SqliteConnectionInternal* conn)
26 , SqliteConnectionInternal(conn->connection)
27{
28 data_owned = false;
29 data = conn->data; //copy
30}
31
32SqlitePreparedStatement::~SqlitePreparedStatement()
33{
34}
35
37{
38 m_sqlResult = connection->prepareSql(sql);
39 m_result = connection->result();
40 return m_sqlResult && !m_result.isError();
41}
42
43bool SqlitePreparedStatement::bindValue(KDbField *field, const QVariant& value, int par)
44{
45 if (value.isNull()) {
46 //no value to bind or the value is null: bind NULL
47 int res = sqlite3_bind_null(sqlResult()->prepared_st, par);
48 if (res != SQLITE_OK) {
49 m_result.setServerErrorCode(res);
50 storeResult(&m_result);
51 return false;
52 }
53 return true;
54 }
55 if (field->isTextType()) {
56 //! @todo optimize: make a static copy so SQLITE_STATIC can be used
57 const QByteArray utf8String(value.toString().toUtf8());
58 int res = sqlite3_bind_text(sqlResult()->prepared_st, par,
59 utf8String.constData(), utf8String.length(), SQLITE_TRANSIENT /*??*/);
60 if (res != SQLITE_OK) {
61 m_result.setServerErrorCode(res);
62 storeResult(&m_result);
63 return false;
64 }
65 return true;
66 }
67
68 switch (field->type()) {
69 case KDbField::Byte:
71 case KDbField::Integer: {
72 //! @todo what about unsigned > INT_MAX ?
73 bool ok;
74 const int intValue = value.toInt(&ok);
75 if (ok) {
76 int res = sqlite3_bind_int(sqlResult()->prepared_st, par, intValue);
77 if (res != SQLITE_OK) {
78 m_result.setServerErrorCode(res);
79 storeResult(&m_result);
80 return false;
81 }
82 } else {
83 int res = sqlite3_bind_null(sqlResult()->prepared_st, par);
84 if (res != SQLITE_OK) {
85 m_result.setServerErrorCode(res);
86 storeResult(&m_result);
87 return false;
88 }
89 }
90 break;
91 }
92 case KDbField::Float:
93 case KDbField::Double: {
94 int res = sqlite3_bind_double(sqlResult()->prepared_st, par, value.toDouble());
95 if (res != SQLITE_OK) {
96 m_result.setServerErrorCode(res);
97 storeResult(&m_result);
98 return false;
99 }
100 break;
101 }
103 //! @todo what about unsigned > LLONG_MAX ?
104 bool ok;
105 const qint64 int64Value = value.toLongLong(&ok);
106 if (ok) {
107 int res = sqlite3_bind_int64(sqlResult()->prepared_st, par, int64Value);
108 if (res != SQLITE_OK) {
109 m_result.setServerErrorCode(res);
110 storeResult(&m_result);
111 return false;
112 }
113 } else {
114 int res = sqlite3_bind_null(sqlResult()->prepared_st, par);
115 if (res != SQLITE_OK) {
116 m_result.setServerErrorCode(res);
117 storeResult(&m_result);
118 return false;
119 }
120 }
121 break;
122 }
123 case KDbField::Boolean: {
124 int res = sqlite3_bind_text(sqlResult()->prepared_st, par, value.toBool() ? "1" : "0",
125 1, SQLITE_TRANSIENT /*??*/);
126 if (res != SQLITE_OK) {
127 m_result.setServerErrorCode(res);
128 storeResult(&m_result);
129 return false;
130 }
131 break;
132 }
133 case KDbField::Time: {
134 int res = sqlite3_bind_text(sqlResult()->prepared_st, par,
135 qPrintable(KDbUtils::toISODateStringWithMs(value.toTime())),
136 QLatin1String("HH:MM:SS").size(), SQLITE_TRANSIENT /*??*/);
137 if (res != SQLITE_OK) {
138 m_result.setServerErrorCode(res);
139 storeResult(&m_result);
140 return false;
141 }
142 break;
143 }
144 case KDbField::Date: {
145 int res = sqlite3_bind_text(sqlResult()->prepared_st, par,
146 qPrintable(value.toDate().toString(Qt::ISODate)),
147 QLatin1String("YYYY-MM-DD").size(), SQLITE_TRANSIENT /*??*/);
148 if (res != SQLITE_OK) {
149 m_result.setServerErrorCode(res);
150 storeResult(&m_result);
151 return false;
152 }
153 break;
154 }
155 case KDbField::DateTime: {
156 int res = sqlite3_bind_text(sqlResult()->prepared_st, par,
157 qPrintable(KDbUtils::toISODateStringWithMs(value.toDateTime())),
158 QLatin1String("YYYY-MM-DDTHH:MM:SS").size(), SQLITE_TRANSIENT /*??*/);
159 if (res != SQLITE_OK) {
160 m_result.setServerErrorCode(res);
161 storeResult(&m_result);
162 return false;
163 }
164 break;
165 }
166 case KDbField::BLOB: {
167 const QByteArray byteArray(value.toByteArray());
168 int res = sqlite3_bind_blob(sqlResult()->prepared_st, par,
169 byteArray.constData(), byteArray.size(), SQLITE_TRANSIENT /*??*/);
170 if (res != SQLITE_OK) {
171 m_result.setServerErrorCode(res);
172 storeResult(&m_result);
173 return false;
174 }
175 break;
176 }
177 default: {
178 sqliteWarning() << "unsupported field type:"
179 << field->type() << "- NULL value bound to column #" << par;
180 int res = sqlite3_bind_null(sqlResult()->prepared_st, par);
181 if (res != SQLITE_OK) {
182 m_result.setServerErrorCode(res);
183 storeResult(&m_result);
184 return false;
185 }
186 }
187 } //switch
188 return true;
189}
190
193 const KDbField::List& selectFieldList,
194 KDbFieldList* insertFieldList,
195 const KDbPreparedStatementParameters& parameters)
196{
197 Q_UNUSED(insertFieldList);
198 if (!sqlResult()->prepared_st) {
200 }
201
202 int par = 1; // par.index counted from 1
203 KDbField::ListIterator itFields(selectFieldList.constBegin());
204 for (QList<QVariant>::ConstIterator it = parameters.constBegin();
205 itFields != selectFieldList.constEnd();
206 it += (it == parameters.constEnd() ? 0 : 1), ++itFields, par++)
207 {
208 if (!bindValue(*itFields, it == parameters.constEnd() ? QVariant() : *it, par))
210 }
211
212 //real execution
213 const int res = sqlite3_step(sqlResult()->prepared_st);
215 const bool ok = res == SQLITE_DONE;
216 if (ok) {
217 m_result = KDbResult();
218 } else {
219 m_result.setServerErrorCode(res);
220 storeResult(&m_result);
221 sqliteWarning() << m_result << QString::fromLatin1(sqlite3_sql(sqlResult()->prepared_st));
222 }
223 (void)sqlite3_reset(sqlResult()->prepared_st);
224 return m_sqlResult;
225 }
226 else if (type == KDbPreparedStatement::SelectStatement) {
227 //! @todo fetch result
228 const bool ok = res == SQLITE_ROW;
229 storeResult(&m_result);
230 if (ok) {
231 m_result = KDbResult();
232 } else {
233 m_result.setServerErrorCode(res);
234 storeResult(&m_result);
235 sqliteWarning() << m_result << QString::fromLatin1(sqlite3_sql(sqlResult()->prepared_st));
236 }
237 (void)sqlite3_reset(sqlResult()->prepared_st);
238 return m_sqlResult;
239 }
241}
Specialized string for escaping.
Meta-data for a field.
Definition KDbField.h:72
bool isTextType() const
Definition KDbField.h:353
QList< KDbField * >::ConstIterator ListIterator
iterator for list of fields
Definition KDbField.h:79
@ Integer
Definition KDbField.h:90
@ Boolean
Definition KDbField.h:92
@ ShortInteger
Definition KDbField.h:89
@ BigInteger
Definition KDbField.h:91
Type type() const
Definition KDbField.cpp:379
Prepared statement interface for backend-dependent implementations.
Type
Defines type of the prepared statement.
@ InsertStatement
INSERT statement will be prepared end executed.
@ SelectStatement
SELECT statement will be prepared end executed.
bool isError() const
Definition KDbResult.cpp:64
void setServerErrorCode(int errorCode)
Sets an implementation-specific error code of server-side operation.
Definition KDbResult.cpp:74
QSharedPointer< KDbSqlResult > execute(KDbPreparedStatement::Type type, const KDbField::List &selectFieldList, KDbFieldList *insertFieldList, const KDbPreparedStatementParameters &parameters) override
For implementation, executes the prepared statement Type of statement is specified by the type parame...
bool prepare(const KDbEscapedString &sql) override
bool bindValue(KDbField *field, const QVariant &value, int arg)
const char * constData() const const
qsizetype length() const const
qsizetype size() const const
QString toString(QStringView format, QCalendar cal) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
QString fromLatin1(QByteArrayView str)
QByteArray toUtf8() const const
bool isNull() const const
bool toBool() const const
QByteArray toByteArray() const const
QDate toDate() const const
QDateTime toDateTime() const const
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
qlonglong toLongLong(bool *ok) const const
QString toString() const const
QTime toTime() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:11:01 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.