From Giona
/*
* Implementation of a class to manage a sqlite database
* --------------------------------------------------------------
* Author: Rosario Marino
*/
#include "SqliteDb.h"
/*
* Constructor
*/
SqliteDb::SqliteDb()
{
Debug::debug("SqliteDb::SqliteDb()");
this->db = NULL;
this->connected = false;
this->lastError=NO_ERROR;
this->dataBaseName = NULL;
this->rsTmp = NULL;
}
/*
* Destructor
*/
SqliteDb::~SqliteDb()
{
Debug::debug("SqliteDb::~SqliteDb()");
}
/*
* Returns last error code
*/
int SqliteDb::getLastError()
{
Debug::debug("int SqliteDb::getLastError()");
return this->lastError;
}
/*
* Returns true if the database is connected to the source
*/
bool SqliteDb::isConnected()
{
Debug::debug("bool SqliteDb::isConnected()");
return this->connected;
}
/*
* Sets the name of the database to connect. Returns false
* in case of error.
*/
bool SqliteDb::setDataBaseName(char* dataBaseName)
{
Debug::debug("bool SqliteDb::setDataBaseName(char* dataBaseName)");
if(dataBaseName==NULL)
{
Debug::debugError("bool SqliteDb::setDataBaseName(char* dataBaseName)","ERROR_NULL_PARAMETER","parameter: dataBaseName");
this->lastError = ERROR_NULL_PARAMETER;
return false;
}
if(strcmp(dataBaseName,"")==0)
{
Debug::debugError("bool SqliteDb::setDataBaseName(char* dataBaseName)","ERROR_EMPTY_STRING","parameter: dataBaseName");
this->lastError = ERROR_EMPTY_STRING;
return false;
}
this->dataBaseName=dataBaseName;
return true;
}
/*
* Returns the name of database
*/
char* SqliteDb::getDatabaseName()
{
Debug::debug("char* SqliteDb::getDatabaseName()");
return this->dataBaseName;
}
/*
* Open the connection to the data source.
* If the data source does not exist, a new one is created.
* Returns FALSE in case of error
*/
bool SqliteDb::openDataBase()
{
Debug::debug("bool SqliteDb::openDataBase()");
if(this->isConnected())
{
Debug::debugError("bool SqliteDb::openDataBase()","ERROR_CONNECTION_OPEN_YET","the database connection is open yet\
you cannot connect to another data source untill you close the previous one");
this->lastError = ERROR_CONNECTION_OPEN_YET;
return false;
}
if(this->dataBaseName==NULL)
{
Debug::debugError("bool SqliteDb::openDataBase()","ERROR_DATABASE_NAME_NOT_SET","You must set the name of the database before trying to open it.\
Use: bool SqliteDb::setDataBaseName(char* dataBaseName)");
this->lastError = ERROR_DATABASE_NAME_NOT_SET;
return false;
}
int ret = sqlite3_open(this->dataBaseName, &this->db);
if(ret != SQLITE_OK)
{
char* txt=strdup(sqlite3_errmsg(this->db));
Debug::debugError("bool SqliteDb::openDataBase()","ERROR_SQLITE_ERROR", txt);
this->lastError = ERROR_SQLITE_ERROR;
return false;
}
this->connected=true;
return true;
}
/*
* Close the connection to the data source.
* Returns false in case of error
*/
bool SqliteDb::closeDataBase()
{
Debug::debug("bool SqliteDb::closeDataBase()");
if(!this->connected)
{
Debug::debugError("bool SqliteDb::closeDataBase()","ERROR_CONNECTION_NOT_OPEN", EMPTY_STRING);
this->lastError=ERROR_CONNECTION_NOT_OPEN;
return false;
}
int ret = sqlite3_close(this->db);
if(ret != SQLITE_OK)
{
char* txt=strdup(sqlite3_errmsg(this->db));
Debug::debugError("bool SqliteDb::closeDataBase()","ERROR_SQLITE_ERROR", txt);
this->lastError = ERROR_SQLITE_ERROR;
return false;
}
return true;
}
/*
* Execute an SQL command (CREATE TABLE, INSERT; UPDATE; DELETE....)
* Returns false in case of error
*/
bool SqliteDb::executeSqlCommand(char* sqlCommand)
{
Debug::debug("bool SqliteDb::executeSqlCommand(char* sqlCommand)");
if(!this->connected)
{
Debug::debugError("bool SqliteDb::executeSqlCommand(char* sqlCommand)","ERROR_CONNECTION_NOT_OPEN", "there is no connection to the data source.\
Use bool SqliteDb::openDataBase()");
this->lastError=ERROR_CONNECTION_NOT_OPEN;
return false;
}
if(sqlCommand==NULL)
{
Debug::debugError("bool SqliteDb::executeSqlCommand(char* sqlCommand)","ERROR_NULL_PARAMETER", "parameter: sqlCommand");
this->lastError = ERROR_NULL_PARAMETER;
return false;
}
if(strcmp(sqlCommand,"")==0)
{
Debug::debugError("bool SqliteDb::executeSqlCommand(char* sqlCommand)","ERROR_EMPTY_STRING", "parameter: sqlCommand");
this->lastError = ERROR_EMPTY_STRING;
return false;
}
char *zErrMsg = NULL;
int ret = sqlite3_exec(this->db, sqlCommand, NULL, NULL, &zErrMsg);
if(ret != SQLITE_OK)
{
char* txt= strdup(zErrMsg);
Debug::debugError("bool SqliteDb::executeSqlCommand(char* sqlCommand)","ERROR_SQLITE_ERROR", txt);
Debug::debugError("bool SqliteDb::executeSqlCommand(char* sqlCommand)","ERROR_SQLITE_ERROR", sqlCommand);
this->lastError = ERROR_SQLITE_ERROR;
if(zErrMsg)
sqlite3_free(zErrMsg);
return false;
}
if(zErrMsg)
sqlite3_free(zErrMsg);
return true;
}
/*
* Execute the query on the data source and returns the Result Set
* Returns NULL in case of error.
*/
SqliteDBResultSet* SqliteDb::executeQuery(char* query)
{
Debug::debug("SqliteDBResultSet* SqliteDb::executeQuery(char* query)");
if(!this->connected)
{
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_CONNECTION_NOT_OPEN", "there is no connection to the data source.\
Use bool SqliteDb::openDataBase()");
this->lastError=ERROR_CONNECTION_NOT_OPEN;
return false;
}
if(query==NULL)
{
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_NULL_PARAMETER", "parameter: query");
this->lastError = ERROR_NULL_PARAMETER;
return false;
}
if(strcmp(query,"")==0)
{
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_EMPTY_STRING", "parameter: query");
this->lastError = ERROR_EMPTY_STRING;
return false;
}
char *zErrMsg = NULL;
this->rsTmp = new SqliteDBResultSet();
this->nRows = 0;
int ret = sqlite3_exec(this->db, query, select_callback, this, &zErrMsg);
if(ret != SQLITE_OK)
{
char* txt= strdup(zErrMsg);
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_SQLITE_ERROR", txt);
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_SQLITE_ERROR", query);
this->lastError = ERROR_SQLITE_ERROR;
if(zErrMsg)
sqlite3_free(zErrMsg);
return NULL;
}
SqliteDBResultSet* rs = this->rsTmp;
this->rsTmp=NULL;
if(zErrMsg)
sqlite3_free(zErrMsg);
return rs;
}
/*
* Compile a Result Set when a query is executed (Private method)
*/
bool SqliteDb::compileResultSet(int num_fields, char **p_fields, char **p_col_names)
{
Debug::debug("bool SqliteDb::compileResultSet(int num_fields, char **p_fields, char **p_col_names)");
if(this->rsTmp->getNColumns()==0)
{
for (int i=0; i < num_fields; i++)
{
char* txt=strdup(p_col_names[i]);
if(!this->rsTmp->addColumn(txt))
{
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_CANT_CREATE_RESULT_SET", "error in adding a column name");
this->lastError = ERROR_CANT_CREATE_RESULT_SET;
return false;
}
}
}
for (int i=0; i < num_fields; i++)
{
char* txt=strdup(p_fields[i]);
if(!rsTmp->addField(txt))
{
Debug::debugError("SqliteDBResultSet* SqliteDb::executeQuery(char* query)","ERROR_CANT_CREATE_RESULT_SET", "error in adding a filed");
this->lastError = ERROR_CANT_CREATE_RESULT_SET;
return false;
}
}
return true;
}
/*
* Callback invoked by sqlite3_exec (Private method)
*/
int SqliteDb::select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names)
{
Debug::debug("int SqliteDb::select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names)");
SqliteDb* dbTmp=(SqliteDb*) p_data;
if(!dbTmp->compileResultSet(num_fields, p_fields, p_col_names))
{
Debug::debugError("int SqliteDb::select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names)","ERROR_CANT_CREATE_RESULT_SET", "error filling a result set");
return ERROR_CANT_CREATE_RESULT_SET;
}
return SQLITE_OK;
}
/*
* Double apices
*/
char* SqliteDb::apex(char* field)
{
Debug::debug("char* SqliteDb::apex(char* field)");
int fieldLength = strlen(field);
char result[5000];
result[0]='\\0';
for(int i=0; i<fieldLength; i++)
{
if(field[i]=='\'')
sprintf(result,"%s''",result);
else
{
sprintf(result,"%s%c",result, field[i]);
}
}
char* res=strdup(result);
return res;
}
BACK