/* � � � � � � � � This file is part of the Opie Project =. .=l. � � � � � �.>+-= �_;:, � � .> � �:=|. This program is free software; you can .> <`_, � > �. � <= redistribute it and/or modify it under :`=1 )Y*s>-.-- � : the terms of the GNU Library General Public .="- .-=="i, � � .._ License as published by the Free Software �- . � .-<_> � � .<> Foundation; either version 2 of the License, � � �._= =} � � � : or (at your option) any later version. � � .%`+i> � � � _;_. � � .i_,=:_. � � �-<s. This program is distributed in the hope that � � �+ �. �-:. � � � = it will be useful, but WITHOUT ANY WARRANTY; � � : .. � �.:, � � . . . without even the implied warranty of � � =_ � � � �+ � � =;=|` MERCHANTABILITY or FITNESS FOR A � _.=:. � � � : � �:=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= � � � = � � � ; Library General Public License for more ++= � -. � � .` � � .: details. �: � � = �...= . :.=- �-. � .:....=;==+<; You should have received a copy of the GNU � -_. . . � )=. �= Library General Public License along with � � -- � � � �:-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "osqlquery.h" #include "osqlitedriver.h" #include <opie2/odebug.h> #include <stdlib.h> #include <stdio.h> namespace Opie { namespace DB { namespace Internal { namespace { struct Query { OSQLError::ValueList errors; OSQLResultItem::ValueList items; OSQLiteDriver *driver; }; } OSQLiteDriver::OSQLiteDriver( QLibrary *lib ) : OSQLDriver( lib ) { m_sqlite = 0l; } OSQLiteDriver::~OSQLiteDriver() { close(); } QString OSQLiteDriver::id()const { return QString::fromLatin1("SQLite"); } void OSQLiteDriver::setUserName( const QString& ) {} void OSQLiteDriver::setPassword( const QString& ) {} void OSQLiteDriver::setUrl( const QString& url ) { m_url = url; } void OSQLiteDriver::setOptions( const QStringList& ) { } /* * Functions to patch a regex search into sqlite */ int sqliteRlikeCompare(const char *zPattern, const char *zString, sqregex *reg){ int res; if (reg->regex_raw == NULL || (strcmp (zPattern, reg->regex_raw) != 0)){ if (reg->regex_raw != NULL) { free(reg->regex_raw); regfree(®->regex_c); } reg->regex_raw = (char *)malloc(strlen(zPattern)+1); strncpy(reg->regex_raw, zPattern, strlen(zPattern)+1); res = regcomp(®->regex_c, zPattern, REG_EXTENDED); if ( res != 0 ) { printf("Regcomp failed with code %u on string %s\n",res,zPattern); free(reg->regex_raw); reg->regex_raw=NULL; return 0; } } res = (regexec(®->regex_c, zString, 0, NULL, 0)==0); return res; } void rlikeFunc( sqlite3_context* context, int count, sqlite3_value** values ){ const unsigned char* argv0 = sqlite3_value_text( values[0] ); const unsigned char* argv1 = sqlite3_value_text( values[1] ); if( count < 2 || argv0 == 0 || argv1 == 0 ){ qWarning( "One of arguments Null!!\n" ); return; } sqlite3_result_int(context, sqliteRlikeCompare((const char*)argv0, (const char*)argv1, (sqregex *) sqlite3_user_data( context ) )); } /* * try to open a db specified via setUrl * and options */ bool OSQLiteDriver::open() { odebug << "OSQLiteDriver::open: about to open" << oendl; int error = sqlite3_open( m_url.utf8(), &m_sqlite ); /* failed to open */ if ( error != SQLITE_OK ) { // FIXME set the last error owarn << "OSQLiteDriver::open: " << error << "" << oendl; sqlite3_close( m_sqlite ); return false; } if ( sqlite3_create_function( m_sqlite, "rlike", 2, SQLITE_UTF8, &sqreg, rlikeFunc, NULL, NULL ) != SQLITE_OK ){ odebug << "Unable to create user defined function!" << oendl; return false; } sqreg.regex_raw = NULL; return true; } /* close the db * sqlite closes them without * telling failure or success */ bool OSQLiteDriver::close() { if ( m_sqlite ){ sqlite3_close( m_sqlite ); m_sqlite=0l; } if ( sqreg.regex_raw != NULL){ odebug << "Freeing regex on close" << oendl; free( sqreg.regex_raw ); sqreg.regex_raw = NULL; regfree( &sqreg.regex_c ); } return true; } /* Query */ OSQLResult OSQLiteDriver::query( OSQLQuery* qu) { if ( !m_sqlite ) { // FIXME set error code OSQLResult result( OSQLResult::Failure ); return result; } Query query; query.driver = this; char *err; /* SQLITE_OK 0 if return code > 0 == failure */ if ( sqlite3_exec( m_sqlite, qu->query().utf8(), &call_back, &query, &err ) > SQLITE_OK ) { owarn << "OSQLiteDriver::query: Error while executing " << err << "" << oendl; free( err ); // FixMe Errors } OSQLResult result(OSQLResult::Success, query.items, query.errors ); return result; } OSQLTable::ValueList OSQLiteDriver::tables() const { return OSQLTable::ValueList(); } OSQLError OSQLiteDriver::lastError() { OSQLError error; return error; }; /* handle a callback add the row to the global * OSQLResultItem */ int OSQLiteDriver::handleCallBack( int, char**, char** ) { return 0; } /* callback_handler add the values to the list*/ int OSQLiteDriver::call_back( void* voi, int argc, char** argv, char** columns ) { Query* qu = (Query*)voi; //copy them over to a OSQLResultItem QMap<QString, QString> tableString; QMap<int, QString> tableInt; for (int i = 0; i < argc; i++ ) { tableInt.insert( i, QString::fromUtf8( argv[i] ) ); tableString.insert( QString::fromUtf8( columns[i] ), QString::fromUtf8( argv[i] ) ); } OSQLResultItem item( tableString, tableInt ); qu->items.append( item ); return ((Query*)voi)->driver->handleCallBack( argc, argv, columns ); } }}} // namespace OPIE::DB::Internal