Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

osqlitedriver.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003 
00004               =.
00005             .=l.
00006            .>+-=
00007  _;:,     .>    :=|.         This program is free software; you can
00008 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00009 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00010 .="- .-=="i,     .._         License as published by the Free Software
00011  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00012      ._= =}       :          or (at your option) any later version.
00013     .%`+i>       _;_.
00014     .i_,=:_.      -<s.       This program is distributed in the hope that
00015      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00016     : ..    .:,     . . .    without even the implied warranty of
00017     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00018   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00019 ..}^=.=       =       ;      Library General Public License for more
00020 ++=   -.     .`     .:       details.
00021  :     =  ...= . :.=-
00022  -.   .:....=;==+<;          You should have received a copy of the GNU
00023   -_. . .   )=.  =           Library General Public License along with
00024     --        :-=`           this library; see the file COPYING.LIB.
00025                              If not, write to the Free Software Foundation,
00026                              Inc., 59 Temple Place - Suite 330,
00027                              Boston, MA 02111-1307, USA.
00028 
00029 */
00030 
00031 #include "osqlquery.h"
00032 #include "osqlitedriver.h"
00033 
00034 #include <opie2/odebug.h>
00035 
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 
00039 namespace Opie {
00040 namespace DB {
00041 namespace Internal {
00042 
00043 namespace {
00044     struct Query {
00045         OSQLError::ValueList errors;
00046         OSQLResultItem::ValueList items;
00047         OSQLiteDriver *driver;
00048     };
00049 }
00050 
00051 
00052 OSQLiteDriver::OSQLiteDriver( QLibrary *lib )
00053     : OSQLDriver( lib )
00054 {
00055     m_sqlite = 0l;
00056 }
00057 
00058 
00059 OSQLiteDriver::~OSQLiteDriver() {
00060     close();
00061 }
00062 
00063 
00064 QString OSQLiteDriver::id()const {
00065     return QString::fromLatin1("SQLite");
00066 }
00067 
00068 void OSQLiteDriver::setUserName( const QString& ) {}
00069 
00070 
00071 void OSQLiteDriver::setPassword( const QString& ) {}
00072 
00073 
00074 void OSQLiteDriver::setUrl( const QString& url ) {
00075     m_url = url;
00076 }
00077 
00078 
00079 void OSQLiteDriver::setOptions( const QStringList& ) {
00080 }
00081 
00082 /*
00083  * Functions to patch a regex search into sqlite
00084  */
00085 int sqliteRlikeCompare(const char *zPattern, const char *zString, sqregex *reg){
00086     int res;
00087     if (reg->regex_raw == NULL || (strcmp (zPattern, reg->regex_raw) != 0)){
00088         if (reg->regex_raw != NULL) {
00089             free(reg->regex_raw);
00090             regfree(&reg->regex_c);
00091         }
00092         reg->regex_raw = (char *)malloc(strlen(zPattern)+1);
00093         strncpy(reg->regex_raw, zPattern, strlen(zPattern)+1);
00094         res = regcomp(&reg->regex_c, zPattern, REG_EXTENDED);
00095         if ( res != 0 ) {
00096             printf("Regcomp failed with code %u on string %s\n",res,zPattern);
00097             free(reg->regex_raw);
00098             reg->regex_raw=NULL;
00099         return 0;
00100         }
00101     }
00102     res = (regexec(&reg->regex_c, zString, 0, NULL, 0)==0);
00103     return res;
00104 }
00105 
00106 void rlikeFunc( sqlite3_context* context, int count, sqlite3_value** values ){
00107     const unsigned char* argv0 = sqlite3_value_text( values[0] );
00108     const unsigned char* argv1 = sqlite3_value_text( values[1] ); 
00109     if( count < 2 || argv0 == 0 || argv1 == 0 ){
00110             qWarning( "One of arguments Null!!\n" );
00111             return;
00112     }
00113     sqlite3_result_int(context, sqliteRlikeCompare((const char*)argv0,
00114                                                       (const char*)argv1, 
00115                                                       (sqregex *) sqlite3_user_data( context ) ));
00116 }
00117 
00118 /*
00119  * try to open a db specified via setUrl
00120  * and options
00121  */
00122 bool OSQLiteDriver::open() {
00123     odebug << "OSQLiteDriver::open: about to open" << oendl;
00124 
00125     int error = sqlite3_open( m_url.utf8(),
00126                            &m_sqlite );
00127 
00128     /* failed to open */
00129     if ( error != SQLITE_OK ) {
00130         // FIXME set the last error
00131         owarn << "OSQLiteDriver::open: " << error << "" << oendl;
00132         sqlite3_close( m_sqlite );
00133         return false;
00134     }
00135     if ( sqlite3_create_function( m_sqlite, "rlike", 2, SQLITE_UTF8, &sqreg, rlikeFunc, NULL, NULL ) != SQLITE_OK ){
00136             odebug << "Unable to create user defined function!" << oendl;
00137             return false;
00138     }
00139 
00140     sqreg.regex_raw = NULL;
00141 
00142     return true;
00143 }
00144 
00145 
00146 /* close the db
00147  * sqlite closes them without
00148  * telling failure or success
00149  */
00150 bool OSQLiteDriver::close() {
00151         if ( m_sqlite ){
00152                 sqlite3_close( m_sqlite );
00153                 m_sqlite=0l;
00154         }
00155         if ( sqreg.regex_raw != NULL){
00156                 odebug << "Freeing regex on close" << oendl;
00157                 free( sqreg.regex_raw );
00158                 sqreg.regex_raw = NULL;
00159                 regfree( &sqreg.regex_c );
00160         }
00161         return true;
00162 }
00163 
00164 
00165 /* Query */
00166 OSQLResult OSQLiteDriver::query( OSQLQuery* qu) {
00167         if ( !m_sqlite ) {
00168                 // FIXME set error code
00169                 OSQLResult result( OSQLResult::Failure );
00170                 return result;
00171         }
00172         Query query;
00173         query.driver = this;
00174         char *err;
00175         /* SQLITE_OK 0 if return code > 0 == failure */
00176         if ( sqlite3_exec( m_sqlite, qu->query().utf8(), &call_back, &query, &err )  > SQLITE_OK ) {
00177                 owarn << "OSQLiteDriver::query: Error while executing " << err << "" << oendl;
00178                 free( err );
00179                 // FixMe Errors
00180         }
00181 
00182         OSQLResult result(OSQLResult::Success,
00183                           query.items,
00184                           query.errors );
00185         return result;
00186 }
00187 
00188 
00189 OSQLTable::ValueList OSQLiteDriver::tables() const {
00190     return OSQLTable::ValueList();
00191 }
00192 
00193 
00194 OSQLError OSQLiteDriver::lastError() {
00195     OSQLError error;
00196     return error;
00197 };
00198 
00199 
00200 /* handle a callback add the row to the global
00201  * OSQLResultItem
00202  */
00203 int OSQLiteDriver::handleCallBack( int, char**, char** ) {
00204     return 0;
00205 }
00206 
00207 
00208 /* callback_handler add the values to the list*/
00209 int OSQLiteDriver::call_back( void* voi, int argc,
00210                               char** argv, char** columns ) {
00211     Query* qu = (Query*)voi;
00212 
00213     //copy them over to a OSQLResultItem
00214     QMap<QString, QString> tableString;
00215     QMap<int, QString> tableInt;
00216     for (int i = 0; i < argc; i++ ) {
00217 
00218         tableInt.insert( i, QString::fromUtf8( argv[i] ) );
00219         tableString.insert( QString::fromUtf8( columns[i] ),
00220                             QString::fromUtf8( argv[i] ) );
00221     }
00222     OSQLResultItem item( tableString, tableInt );
00223     qu->items.append( item );
00224 
00225     return ((Query*)voi)->driver->handleCallBack( argc,
00226                                                   argv,
00227                                                   columns );
00228 
00229 
00230 }
00231 
00232 }}} // namespace OPIE::DB::Internal

Generated on Sat Nov 5 16:16:10 2005 for OPIE by  doxygen 1.4.2