presage  0.8.7
sqliteDatabaseConnector.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************
00003  *  Presage, an extensible predictive text entry system
00004  *  ---------------------------------------------------
00005  *
00006  *  Copyright (C) 2008  Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License along
00019     with this program; if not, write to the Free Software Foundation, Inc.,
00020     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021                                                                              *
00022                                                                 **********(*)*/
00023 
00024 
00025 #include "sqliteDatabaseConnector.h"
00026 
00027 #ifdef HAVE_STDLIB_H
00028 # include <stdlib.h> // for free()
00029 #endif
00030 
00031 SqliteDatabaseConnector::SqliteDatabaseConnector(const std::string database_name)
00032     : DatabaseConnector()
00033 {
00034     db_name = database_name;
00035     openDatabase();
00036 }
00037 
00038 SqliteDatabaseConnector::SqliteDatabaseConnector(const std::string database_name, const std::string logger_level)
00039     : DatabaseConnector(logger_level)
00040 {
00041     db_name = database_name;
00042     openDatabase();
00043 }
00044 
00045 SqliteDatabaseConnector::~SqliteDatabaseConnector()
00046 {
00047     closeDatabase();
00048 }
00049 
00050 void SqliteDatabaseConnector::openDatabase()
00051 {
00052 #if defined(HAVE_SQLITE3_H)
00053     int result = sqlite3_open(db_name.c_str(), &db);
00054     if (result != SQLITE_OK) {
00055         std::string error = sqlite3_errmsg(db);
00056         logger << ERROR << "Unable to open database: " << db_name << " : " << endl;
00057         throw SqliteDatabaseConnectorException(PRESAGE_SQLITE_OPEN_DATABASE_ERROR, error);
00058     }
00059 #elif defined(HAVE_SQLITE_H)
00060     char* errormsg = 0;
00061     db = sqlite_open(db_name.c_str(), 0, &errormsg);
00062     if (db == 0) {
00063         std::string error;
00064         if (errormsg != 0) {
00065             error = errormsg;
00066         }
00067 #ifdef HAVE_STDLIB_H
00068         free(errormsg);
00069 #endif
00070         logger << ERROR << "Unable to open database: " << db_name << " : " << endl;
00071         throw SqliteDatabaseConnectorException(error);
00072     }
00073 #endif
00074 
00075 
00076 }
00077 
00078 void SqliteDatabaseConnector::closeDatabase()
00079 {
00080     if (db) {
00081 #if defined(HAVE_SQLITE3_H)
00082         sqlite3_close(db);
00083 #elif defined(HAVE_SQLITE_H)
00084         sqlite_close(db);
00085 #endif
00086     }
00087 }
00088 
00089 NgramTable SqliteDatabaseConnector::executeSql(const std::string query) const
00090 {
00091     NgramTable answer;
00092     
00093     char* sqlite_error_msg = 0;
00094 
00095     logger << DEBUG << "executing query: " << query << endl;
00096 #if defined(HAVE_SQLITE3_H)
00097     int result = sqlite3_exec(
00098 #elif defined(HAVE_SQLITE_H)
00099     int result = sqlite_exec(
00100 #endif
00101         db,
00102         query.c_str(),
00103         callback,
00104         &answer,
00105         &sqlite_error_msg
00106     );
00107 
00108     if (result != SQLITE_OK) {
00109         std::string error;
00110         if (sqlite_error_msg != 0) {
00111             error = sqlite_error_msg;
00112         }
00113 #if defined(HAVE_SQLITE3_H)
00114         sqlite3_free(sqlite_error_msg);
00115 #elif defined(HAVE_SQLITE_H)
00116 # ifdef HAVE_STDLIB_H
00117         free(sqlite_error_msg);
00118 # endif
00119 #endif
00120         logger << ERROR << "Error executing SQL: '" 
00121                << query << "' on database: '" << db_name
00122                << "' : " << error << endl;
00123         throw SqliteDatabaseConnectorException(PRESAGE_SQLITE_EXECUTE_SQL_ERROR, error);
00124     }
00125 
00126     return answer;
00127 }
00128 
00129 int SqliteDatabaseConnector::callback(
00130     void *pArg,
00131     int argc,
00132     char **argv,
00133     char **columnNames)
00134 {
00135     NgramTable& query_result = *static_cast<NgramTable*>(pArg);
00136 
00137     //std::cerr << "building ngram: ";
00138     Ngram ngram;
00139     for (int i = 0; i < argc; i++) {
00140         if (argv[i] != NULL) {
00141             //std::cerr << "(" << columnNames[i] << ":" << argv[i] << ")" << '\t';
00142             ngram.push_back(argv[i]);
00143         }
00144         else
00145         {
00146             //std::cerr << "argv[" << i << "] is NULL" << std::endl;
00147             ngram.push_back(""); // empty string to represent NULL value
00148         }
00149     }
00150     //std::cerr << std::endl;
00151 
00152     query_result.push_back(ngram);
00153 
00154     return SQLITE_OK;
00155 }