kexi

sqlitepreparedstatement.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "sqlitepreparedstatement.h"
00021 
00022 #include <kdebug.h>
00023 #include <assert.h>
00024 
00025 using namespace KexiDB;
00026 
00027 SQLitePreparedStatement::SQLitePreparedStatement(StatementType type, ConnectionInternal& conn, 
00028     FieldList& fields)
00029  : KexiDB::PreparedStatement(type, conn, fields)
00030  , SQLiteConnectionInternal(conn.connection)
00031  , prepared_st_handle(0)
00032  , m_resetRequired(false)
00033 {
00034     data_owned = false;
00035     data = dynamic_cast<KexiDB::SQLiteConnectionInternal&>(conn).data; //copy
00036 
00037     temp_st = generateStatementString();
00038 #ifdef SQLITE2
00039 
00040 #else
00041     if (!temp_st.isEmpty()) {
00042         res = sqlite3_prepare(
00043             data, /* Database handle */
00044             temp_st, //const char *zSql,       /* SQL statement, UTF-8 encoded */
00045             temp_st.length(), //int nBytes,             /* Length of zSql in bytes. */
00046             &prepared_st_handle, //sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
00047             0 //const char **pzTail     /* OUT: Pointer to unused portion of zSql */
00048         );
00049         if (SQLITE_OK != res) {
00051         }
00052     }
00053 #endif
00054 }
00055 
00056 SQLitePreparedStatement::~SQLitePreparedStatement()
00057 {
00058 #ifdef SQLITE2
00059 
00060 #else
00061     sqlite3_finalize(prepared_st_handle);
00062     prepared_st_handle = 0;
00063 #endif
00064 }
00065 
00066 bool SQLitePreparedStatement::execute()
00067 {
00068 #ifdef SQLITE2
00069 
00070 #else
00071     if (!prepared_st_handle)
00072         return false;
00073     if (m_resetRequired) {
00074         res = sqlite3_reset(prepared_st_handle);
00075         if (SQLITE_OK != res) {
00077             return false;
00078         }
00079         m_resetRequired = false;
00080     }
00081 
00082     int arg=1; //arg index counted from 1
00083     KexiDB::Field *field;
00084 
00085     Field::List _dummy;
00086     Field::ListIterator itFields(_dummy);
00087     //for INSERT, we're iterating over inserting values
00088     //for SELECT, we're iterating over WHERE conditions
00089     if (m_type == SelectStatement)
00090         itFields = *m_whereFields;
00091     else if (m_type == InsertStatement)
00092         itFields = m_fields->fieldsIterator();
00093     else
00094         assert(0); //impl. error
00095 
00096     for (QValueListConstIterator<QVariant> it = m_args.constBegin(); 
00097         (field = itFields.current()); ++it, ++itFields, arg++)
00098     {
00099         if (it==m_args.constEnd() || (*it).isNull()) {//no value to bind or the value is null: bind NULL
00100             res = sqlite3_bind_null(prepared_st_handle, arg);
00101             if (SQLITE_OK != res) {
00103                 return false;
00104             }
00105             continue;
00106         }
00107         if (field->isTextType()) {
00109             QCString utf8String((*it).toString().utf8());
00110             res = sqlite3_bind_text(prepared_st_handle, arg, 
00111                 (const char*)utf8String, utf8String.length(), SQLITE_TRANSIENT /*??*/);
00112             if (SQLITE_OK != res) {
00114                 return false;
00115             }
00116         }
00117         else switch (field->type()) {
00118         case KexiDB::Field::Byte:
00119         case KexiDB::Field::ShortInteger:
00120         case KexiDB::Field::Integer:
00121         {
00123             bool ok;
00124             const int value = (*it).toInt(&ok);
00125             if (ok) {
00126                 res = sqlite3_bind_int(prepared_st_handle, arg, value);
00127                 if (SQLITE_OK != res) {
00129                     return false;
00130                 }
00131             }
00132             else {
00133                 res = sqlite3_bind_null(prepared_st_handle, arg);
00134                 if (SQLITE_OK != res) {
00136                     return false;
00137                 }
00138             }
00139             break;
00140         }
00141         case KexiDB::Field::Float:
00142         case KexiDB::Field::Double:
00143             res = sqlite3_bind_double(prepared_st_handle, arg, (*it).toDouble());
00144             if (SQLITE_OK != res) {
00146                 return false;
00147             }
00148             break;
00149         case KexiDB::Field::BigInteger:
00150         {
00152             bool ok;
00153             Q_LLONG value = (*it).toLongLong(&ok);
00154             if (ok) {
00155                 res = sqlite3_bind_int64(prepared_st_handle, arg, value);
00156                 if (SQLITE_OK != res) {
00158                     return false;
00159                 }
00160             }
00161             else {
00162                 res = sqlite3_bind_null(prepared_st_handle, arg);
00163                 if (SQLITE_OK != res) {
00165                     return false;
00166                 }
00167             }
00168             break;
00169         }
00170         case KexiDB::Field::Boolean:
00171             res = sqlite3_bind_text(prepared_st_handle, arg, 
00172                 QString::number((*it).toBool() ? 1 : 0).latin1(), 
00173                 1, SQLITE_TRANSIENT /*??*/);
00174             if (SQLITE_OK != res) {
00176                 return false;
00177             }
00178             break;
00179         case KexiDB::Field::Time:
00180             res = sqlite3_bind_text(prepared_st_handle, arg, 
00181                 (*it).toTime().toString(Qt::ISODate).latin1(), 
00182                 sizeof("HH:MM:SS"), SQLITE_TRANSIENT /*??*/);
00183             if (SQLITE_OK != res) {
00185                 return false;
00186             }
00187             break;
00188         case KexiDB::Field::Date:
00189             res = sqlite3_bind_text(prepared_st_handle, arg, 
00190                 (*it).toDate().toString(Qt::ISODate).latin1(), 
00191                 sizeof("YYYY-MM-DD"), SQLITE_TRANSIENT /*??*/);
00192             if (SQLITE_OK != res) {
00194                 return false;
00195             }
00196             break;
00197         case KexiDB::Field::DateTime:
00198             res = sqlite3_bind_text(prepared_st_handle, arg, 
00199                 (*it).toDateTime().toString(Qt::ISODate).latin1(), 
00200                 sizeof("YYYY-MM-DDTHH:MM:SS"), SQLITE_TRANSIENT /*??*/);
00201             if (SQLITE_OK != res) {
00203                 return false;
00204             }
00205             break;
00206         case KexiDB::Field::BLOB:
00207         {
00208             const QByteArray byteArray((*it).toByteArray());
00209             res = sqlite3_bind_blob(prepared_st_handle, arg, 
00210                 (const char*)byteArray, byteArray.size(), SQLITE_TRANSIENT /*??*/);
00211             if (SQLITE_OK != res) {
00213                 return false;
00214             }
00215             break;
00216         }
00217         default:
00218             KexiDBWarn << "PreparedStatement::execute(): unsupported field type: " 
00219                 << field->type() << " - NULL value bound to column #" << arg << endl;
00220             res = sqlite3_bind_null(prepared_st_handle, arg);
00221             if (SQLITE_OK != res) {
00223                 return false;
00224             }
00225         } //switch
00226     }
00227 
00228     //real execution
00229     res = sqlite3_step(prepared_st_handle);
00230     m_resetRequired = true;
00231     if (m_type == InsertStatement && res == SQLITE_DONE) {
00232         return true;
00233     }
00234     if (m_type == SelectStatement) {
00235         //fetch result
00236 
00237         //todo
00238     }
00239 #endif
00240     return false;
00241 }
00242 
KDE Home | KDE Accessibility Home | Description of Access Keys