diff options
Diffstat (limited to 'database/database.cpp')
-rw-r--r-- | database/database.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/database/database.cpp b/database/database.cpp new file mode 100644 index 0000000..22c41cd --- /dev/null +++ b/database/database.cpp @@ -0,0 +1,274 @@ +/* + * File: database.h + * Author: savop + * + * Created on 3. September 2009, 22:20 + */ + +#include <string.h> +#include <stdlib.h> +#include <sqlite3.h> +#include "database.h" +#include "../common.h" +#include "object.h" +#include "../upnp.h" + +cSQLiteDatabase* cSQLiteDatabase::mInstance = NULL; + +cSQLiteDatabase::cSQLiteDatabase(){ + this->mActiveTransaction = false; + this->mDatabase = NULL; + this->mLastRow = NULL; + this->mRows = NULL; +} + +cSQLiteDatabase::~cSQLiteDatabase(){ + sqlite3_close(this->mDatabase); +} + +cSQLiteDatabase* cSQLiteDatabase::getInstance(){ + if(cSQLiteDatabase::mInstance == NULL){ + cSQLiteDatabase::mInstance = new cSQLiteDatabase; + DatabaseLocker.Wait(); + cSQLiteDatabase::mInstance->initialize(); + } + + if(cSQLiteDatabase::mInstance != NULL) + return cSQLiteDatabase::mInstance; + else + return NULL; +} + +int cSQLiteDatabase::execStatement(const char* Statement){ + char* Error; + if(!this->mDatabase){ + ERROR("Database not open. Cannot continue"); + return -1; + } + this->mRows = new cRows; +#ifdef SQLITE_PRINT_STATEMENTS + MESSAGE("SQLite: %s", Statement); +#endif + if(sqlite3_exec(this->mDatabase, Statement, cSQLiteDatabase::getResultRow, (cSQLiteDatabase*)this, &Error)!=SQLITE_OK){ + ERROR("Database error: %s", Error); + ERROR("Statement was: %s", Statement); + sqlite3_free(Error); + return -1; + } + + sqlite3_free(Error); + return 0; +} + +int cSQLiteDatabase::getResultRow(void* DB, int NumCols, char** Values, char** ColNames){ + cRow* Row = new cRow; + Row->ColCount = NumCols; + Row->Columns = new char*[NumCols]; + Row->Values = new char*[NumCols]; + for(int i=0; i < NumCols; i++){ + Row->Columns[i] = strdup0(ColNames[i]); + Row->Values[i] = strdup0(Values[i]); + } + cSQLiteDatabase* Database = (cSQLiteDatabase*)DB; + Database->mRows->Add(Row); + return 0; +} + +cRows::cRows(){ + this->mLastRow = NULL; +} + +cRows::~cRows(){ + this->mLastRow = NULL; +} + +bool cRows::fetchRow(cRow** Row){ + if(this->mLastRow==NULL){ + this->mLastRow = this->First(); + } + else { + this->mLastRow = this->Next(this->mLastRow); + } + if(this->mLastRow != NULL){ + *Row = this->mLastRow; + return true; + } + else { + *Row = NULL; + return false; + } + return false; +} + +cRow::cRow(){ + this->currentCol = 0; + this->ColCount = 0; + this->Columns = NULL; + this->Values = NULL; +} + +cRow::~cRow(){ + for(int i=0;i<this->ColCount;i++){ + delete Columns[i]; + delete Values[i]; + } + this->Columns = NULL; + this->Values = NULL; +} + +bool cRow::fetchColumn(cString* Column, cString* Value){ + char *Col, *Val; + bool ret = this->fetchColumn(&Col, &Val); + if(ret){ + *Column = cString(Col,true); + *Value = cString(Val,true); + } + return ret; +} + +bool cRow::fetchColumn(char** Column, char** Value){ + if(currentCol>=this->ColCount){ + return false; + } + #ifdef SQLITE_PRINT_FETCHES + MESSAGE("Fetching column %s='%s' (%d/%d)", this->Columns[currentCol], this->Values[currentCol], currentCol+1, this->ColCount); + #endif + *Column = strdup0(this->Columns[currentCol]); + *Value = strcasecmp(this->Values[currentCol],"NULL")?strdup0(this->Values[currentCol]):NULL; + currentCol++; + return true; +} + +int cSQLiteDatabase::initialize(){ + int ret; + cString File = cString::sprintf("%s/%s", cPluginUpnp::getConfigDirectory(), SQLITE_DB_FILE); + if((ret = sqlite3_open(File, &this->mDatabase))){ + ERROR("Unable to open database file %s (Error code: %d)!", *File, ret); + sqlite3_close(this->mDatabase); + return -1; + } + MESSAGE("Database file %s opened.", *File); + if(this->initializeTables()){ + ERROR("Error while creating tables"); + return -1; + } + else if(this->initializeTriggers()){ + ERROR("Error while setting triggers"); + return -1; + } + return 0; +} + +void cSQLiteDatabase::startTransaction(){ + if(this->mActiveTransaction){ + if(this->mAutoCommit){ + this->commitTransaction(); + } + else { + this->rollbackTransaction(); + } + } + this->execStatement("BEGIN TRANSACTION"); + this->mActiveTransaction = true; +} + +void cSQLiteDatabase::commitTransaction(){ + this->execStatement("COMMIT TRANSACTION"); + this->mActiveTransaction = false; +} + +void cSQLiteDatabase::rollbackTransaction(){ + this->execStatement("ROLLBACK TRANSACTION"); + this->mActiveTransaction = false; +} + +int cSQLiteDatabase::initializeTables(){ + int ret = 0; + this->startTransaction(); + if(this->execStatement(SQLITE_CREATE_TABLE_SYSTEM)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_PRIMARY_KEYS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_ALBUMS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_AUDIOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_AUDIOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_CONTAINER)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_IMAGEITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_MOVIES)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_OBJECTS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_PHOTOS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_PLAYLISTS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_RESOURCES)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_SEARCHCLASS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_VIDEOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_CREATE_TABLE_VIDEOITEMS)==-1) ret = -1; + if(ret){ + this->rollbackTransaction(); + } + else { + this->commitTransaction(); + } + return ret; +} + +int cSQLiteDatabase::initializeTriggers(){ + int ret = 0; + this->startTransaction(); + if(this->execStatement(SQLITE_TRIGGER_UPDATE_SYSTEM)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_UPDATE_OBJECTID)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_ALBUMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_PLAYLISTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_IMAGEITEMS_PHOTOS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_AUDIOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_IMAGEITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_ITEMS_VIDEOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_OBJECTS_OBJECTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_CONTAINERS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_OBJECT_RESOURCES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_VIDEOITEMS_MOVIES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_D_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_ALBUMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_PLAYLISTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_IMAGEITEMS_PHOTOS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_AUDIOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_IMAGEITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_ITEMS_VIDEOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_OBJECTS_OBJECTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_CONTAINERS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_OBJECT_RESOURCES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_VIDEOITEMS_MOVIES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_I_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_AUDIOITEMS_AUDIOBROADCASTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_ALBUMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_PLAYLISTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_CONTAINERS_SEARCHCLASSES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_IMAGEITEMS_PHOTOS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_AUDIOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_IMAGEITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_ITEMS_VIDEOITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_OBJECTS_OBJECTS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_CONTAINERS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_ITEMS)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_OBJECT_RESOURCES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_VIDEOITEMS_MOVIES)==-1) ret = -1; + if(this->execStatement(SQLITE_TRIGGER_U_VIDEOITEMS_VIDEOBROADCASTS)==-1) ret = -1; + if(ret){ + this->rollbackTransaction(); + } + else { + this->commitTransaction(); + } + return ret; +} + +long cSQLiteDatabase::getLastInsertRowID() const { + return (long)sqlite3_last_insert_rowid(this->mDatabase); +}
\ No newline at end of file |