Version 0.1.5 - introduced new DB API

This commit is contained in:
louis 2014-10-25 05:55:19 +02:00
parent 74969a32d8
commit f2167b1467
13 changed files with 236 additions and 37 deletions

View File

@ -33,3 +33,6 @@ Version 0.1.3
Version 0.1.4 Version 0.1.4
- added ScraperGetPosterBannerV2 Service - added ScraperGetPosterBannerV2 Service
Versionn 0.1.5
- introduced new DB API

View File

@ -11,6 +11,7 @@
#include <stdint.h> // uint_64_t #include <stdint.h> // uint_64_t
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <string> #include <string>
#include <openssl/md5.h> // MD5_* #include <openssl/md5.h> // MD5_*
@ -280,5 +281,147 @@ class LogDuration
int logLevel; int logLevel;
}; };
//***************************************************************************
// Semaphore
//***************************************************************************
#include <sys/sem.h>
class Sem
{
public:
Sem(key_t aKey)
{
locked = no;
key = aKey;
if ((id = semget(key, 1, 0666 | IPC_CREAT)) == -1)
tell(0, "Error: Can't get semaphore, errno (%d) '%s'",
errno, strerror(errno));
}
~Sem()
{
if (locked)
v();
}
// ----------------------
// get lock
int p()
{
sembuf sops[2];
sops[0].sem_num = 0;
sops[0].sem_op = 0; // wait for lock
sops[0].sem_flg = SEM_UNDO;
sops[1].sem_num = 0;
sops[1].sem_op = 1; // increment
sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT;
if (semop(id, sops, 2) == -1)
{
tell(0, "Error: Can't lock semaphore, errno (%d) '%s'",
errno, strerror(errno));
return fail;
}
locked = yes;
return success;
}
// ----------------------
// increment
int inc()
{
sembuf sops[1];
sops[0].sem_num = 0;
sops[0].sem_op = 1; // increment
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
if (semop(id, sops, 1) == -1)
{
if (errno != EAGAIN)
tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
errno, strerror(errno));
return fail;
}
locked = yes;
return success;
}
// ----------------------
// decrement
int dec()
{
return v();
}
// ----------------------
// check
int check()
{
sembuf sops[1];
sops[0].sem_num = 0;
sops[0].sem_op = 0;
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
if (semop(id, sops, 1) == -1)
{
if (errno != EAGAIN)
tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
errno, strerror(errno));
return fail;
}
return success;
}
// ----------------------
// release lock
int v()
{
sembuf sops;
sops.sem_num = 0;
sops.sem_op = -1; // release control
sops.sem_flg = SEM_UNDO | IPC_NOWAIT;
if (semop(id, &sops, 1) == -1)
{
if (errno != EAGAIN)
tell(0, "Error: Can't unlock semaphore, errno (%d) '%s'",
errno, strerror(errno));
return fail;
}
locked = no;
return success;
}
private:
key_t key;
int id;
int locked;
};
//*************************************************************************** //***************************************************************************
#endif //___COMMON_H #endif //___COMMON_H

View File

@ -11,6 +11,8 @@
#include "common.h" #include "common.h"
#define EPG_PLUGIN_SEM_KEY 0x3db00001
//*************************************************************************** //***************************************************************************
// Config // Config
//*************************************************************************** //***************************************************************************

View File

@ -512,6 +512,7 @@ int cDbConnection::dbPort = 3306;
char* cDbConnection::dbUser = 0; char* cDbConnection::dbUser = 0;
char* cDbConnection::dbPass = 0; char* cDbConnection::dbPass = 0;
char* cDbConnection::dbName = 0; char* cDbConnection::dbName = 0;
Sem* cDbConnection::sem = 0;
//*************************************************************************** //***************************************************************************
// Object // Object

View File

@ -8,11 +8,15 @@
#ifndef __DB_H #ifndef __DB_H
#define __DB_H #define __DB_H
#include <linux/unistd.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <errno.h> #include <errno.h>
#include <mysql/mysql.h> #include <mysql/mysql.h>
#include <list> #include <list>
@ -550,13 +554,11 @@ class cDbConnection
virtual ~cDbConnection() virtual ~cDbConnection()
{ {
if (mysql) close();
{
mysql_close(mysql);
mysql_thread_end();
}
} }
int isConnected() { return getMySql() > 0; }
int attachConnection() int attachConnection()
{ {
static int first = yes; static int first = yes;
@ -565,14 +567,16 @@ class cDbConnection
{ {
connectDropped = yes; connectDropped = yes;
tell(0, "Calling mysql_init(%ld)", syscall(__NR_gettid));
if (!(mysql = mysql_init(0))) if (!(mysql = mysql_init(0)))
return errorSql(this, "attachConnection(init)"); return errorSql(this, "attachConnection(init)");
if (!mysql_real_connect(mysql, dbHost, if (!mysql_real_connect(mysql, dbHost,
dbUser, dbPass, dbName, dbPort, 0, 0)) dbUser, dbPass, dbName, dbPort, 0, 0))
{ {
mysql_close(mysql); close();
mysql = 0;
tell(0, "Error, connecting to database at '%s' on port (%d) failed", tell(0, "Error, connecting to database at '%s' on port (%d) failed",
dbHost, dbPort); dbHost, dbPort);
@ -601,19 +605,25 @@ class cDbConnection
return success; return success;
} }
void detachConnection() void close()
{ {
attached--; if (mysql)
if (!attached)
{ {
tell(0, "Closing mysql connection and calling mysql_thread_end(%ld)", syscall(__NR_gettid));
mysql_close(mysql); mysql_close(mysql);
mysql_thread_end(); mysql_thread_end();
mysql = 0; mysql = 0;
} }
} }
int isConnected() { return getMySql() > 0; } void detachConnection()
{
attached--;
if (!attached)
close();
}
int check() int check()
{ {
@ -724,12 +734,7 @@ class cDbConnection
MYSQL* getMySql() MYSQL* getMySql()
{ {
if (connectDropped && mysql) if (connectDropped && mysql)
{ close();
mysql_close(mysql);
mysql_thread_end();
mysql = 0;
attached = 0;
}
return mysql; return mysql;
} }
@ -756,22 +761,59 @@ class cDbConnection
int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0); int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0);
void showStat(const char* name = "") { statements.showStat(name); } void showStat(const char* name = "") { statements.showStat(name); }
static int init() // -----------------------------------------------------------
// init() and exit() must exactly called 'once' per process
static int init(key_t semKey)
{ {
if (mysql_library_init(0, 0, 0)) if (semKey && !sem)
sem = new Sem(semKey);
if (!sem || sem->check() == success)
{ {
tell(0, "Error: mysql_library_init failed"); // call only once per process
return fail; // return errorSql(0, "init(library_init)");
if (sem)
tell(1, "Info: Calling mysql_library_init()");
if (mysql_library_init(0, 0, 0))
{
tell(0, "Error: mysql_library_init() failed");
return fail;
}
} }
else if (sem)
{
tell(1, "Info: Skipping calling mysql_library_init(), it's already done!");
}
if (sem)
sem->inc(); // count usage per process
return success; return success;
} }
static int exit() static int exit()
{ {
mysql_library_end(); mysql_thread_end();
if (sem)
sem->dec();
if (!sem || sem->check() == success)
{
if (sem)
tell(1, "Info: Released the last usage of mysql_lib, calling mysql_library_end() now");
mysql_library_end();
}
else if (sem)
{
tell(1, "Info: The mysql_lib is still in use, skipping mysql_library_end() call");
}
free(dbHost); free(dbHost);
free(dbUser); free(dbUser);
free(dbPass); free(dbPass);
@ -792,6 +834,8 @@ class cDbConnection
int inTact; int inTact;
int connectDropped; int connectDropped;
static Sem* sem;
static char* encoding; static char* encoding;
// connecting data // connecting data

View File

@ -15,7 +15,7 @@ const char* logPrefix = "demo";
void initConnection() void initConnection()
{ {
cDbConnection::init(); cDbConnection::init(0x3db00012);
cDbConnection::setEncoding("utf8"); cDbConnection::setEncoding("utf8");
cDbConnection::setHost("localhost"); cDbConnection::setHost("localhost");

View File

@ -117,9 +117,9 @@ cDbService::FieldDef cTableEvents::fields[] =
// episodes (constable) // episodes (constable)
{ "episode", ffAscii, 250, fiEpisode, ftData }, // { "episodecompname", ffAscii, 250, fiEpisode, ftData },
{ "episodepart", ffAscii, 250, fiEpisodePart, ftData }, // { "episodecomppartname", ffAscii, 250, fiEpisodePart, ftData },
{ "episodelang", ffAscii, 3, fiEpisodeLang, ftData }, // { "episodelang", ffAscii, 3, fiEpisodeLang, ftData },
// tv scraper // tv scraper

View File

@ -251,9 +251,9 @@ class cTableEvents : public cDbTable
fiExtEpNum, fiExtEpNum,
fiImageCount, fiImageCount,
fiEpisode, // fiEpisode,
fiEpisodePart, // fiEpisodePart,
fiEpisodeLang, // fiEpisodeLang,
fiScrSeriesId, fiScrSeriesId,
fiScrSeriesEpisode, fiScrSeriesEpisode,

View File

@ -21,7 +21,7 @@ const char* logPrefix = "test";
void initConnection() void initConnection()
{ {
cDbConnection::init(); cDbConnection::init(0x3db00011);
cDbConnection::setEncoding("utf8"); cDbConnection::setEncoding("utf8");
cDbConnection::setHost("localhost"); cDbConnection::setHost("localhost");

View File

@ -6,7 +6,10 @@
* $Id$ * $Id$
*/ */
#include "lib/config.h"
#include "scraper2vdr.h" #include "scraper2vdr.h"
const char* logPrefix = LOG_PREFIX; const char* logPrefix = LOG_PREFIX;
#if defined (APIVERSNUM) && (APIVERSNUM < 10600) #if defined (APIVERSNUM) && (APIVERSNUM < 10600)
@ -80,7 +83,7 @@ eOSState cScraper2VdrPluginMenu::ProcessKey(eKeys key) {
//*************************************************************************** //***************************************************************************
cPluginScraper2vdr::cPluginScraper2vdr(void) { cPluginScraper2vdr::cPluginScraper2vdr(void) {
cDbConnection::init(); cDbConnection::init(EPG_PLUGIN_SEM_KEY);
} }
cPluginScraper2vdr::~cPluginScraper2vdr() { cPluginScraper2vdr::~cPluginScraper2vdr() {

View File

@ -13,7 +13,7 @@
//*************************************************************************** //***************************************************************************
// Constants // Constants
//*************************************************************************** //***************************************************************************
static const char *VERSION = "0.1.4"; static const char *VERSION = "0.1.5";
static const char *DESCRIPTION = "'scraper2vdr' plugin"; static const char *DESCRIPTION = "'scraper2vdr' plugin";
static const char *MAINMENUENTRY = "Scraper2Vdr"; static const char *MAINMENUENTRY = "Scraper2Vdr";

View File

@ -354,7 +354,7 @@ void cScrapManager::DumpMovies(void) {
} }
void cScrapManager::DumpRecordings(void) { void cScrapManager::DumpRecordings(void) {
tell(0, "%d recordings in memory:", recordings.size()); tell(0, "%ld recordings in memory:", recordings.size());
for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) { for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) {
sRecordingsKey key = it->first; sRecordingsKey key = it->first;
sEventsValue val = it->second; sEventsValue val = it->second;
@ -481,6 +481,7 @@ bool cScrapManager::GetMovie(cMovie *m) {
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) { bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
sEventsValue v; sEventsValue v;
v.episodeId = 0;
if (call->event) { if (call->event) {
sEventsKey k; sEventsKey k;
k.eventId = call->event->EventID(); k.eventId = call->event->EventID();
@ -516,6 +517,7 @@ bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) { bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) {
sEventsValue v; sEventsValue v;
v.episodeId = 0;
if (call->event) { if (call->event) {
sEventsKey k; sEventsKey k;
k.eventId = call->event->EventID(); k.eventId = call->event->EventID();

View File

@ -77,7 +77,6 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started", true
cUpdate::~cUpdate() { cUpdate::~cUpdate() {
if (loopActive) if (loopActive)
Stop(); Stop();
exitDb();
} }
// global field definitions // global field definitions
@ -1356,6 +1355,8 @@ void cUpdate::Action()
worked = no; worked = no;
} }
exitDb(); // don't call exit in dtor, outside from thread!!
loopActive = no; loopActive = no;
tell(0, "Update thread ended (pid=%d)", getpid()); tell(0, "Update thread ended (pid=%d)", getpid());
} }