mirror of
https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
synced 2023-10-19 17:58:31 +02:00
added lib files
This commit is contained in:
parent
9ebafce3fd
commit
5d7fb01f67
176
lib/curl.c
Normal file
176
lib/curl.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* curl.c:
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
|
||||
//***************************************************************************
|
||||
// Callbacks
|
||||
//***************************************************************************
|
||||
|
||||
static size_t WriteMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct* mem = (struct MemoryStruct*)data;
|
||||
|
||||
if (mem->memory)
|
||||
mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
|
||||
else
|
||||
mem->memory = (char*)malloc(mem->size + realsize + 1);
|
||||
|
||||
if (mem->memory)
|
||||
{
|
||||
memcpy (&(mem->memory[mem->size]), ptr, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
}
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
static size_t WriteHeaderCallback(void* ptr, size_t size, size_t nmemb, void* data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct* mem = (struct MemoryStruct*)data;
|
||||
char* p;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
// get filename
|
||||
{
|
||||
// Content-Disposition: attachment; filename="20140103_20140103_de_qy.zip"
|
||||
|
||||
const char* attribute = "Content-disposition: ";
|
||||
|
||||
if ((p = strcasestr((char*)ptr, attribute)))
|
||||
{
|
||||
if (p = strcasestr(p, "filename="))
|
||||
{
|
||||
p += strlen("filename=");
|
||||
|
||||
tell(4, "found filename at [%s]", p);
|
||||
|
||||
if (*p == '"')
|
||||
p++;
|
||||
|
||||
sprintf(mem->name, "%s", p);
|
||||
|
||||
if ((p = strchr(mem->name, '\n')))
|
||||
*p = 0;
|
||||
|
||||
if ((p = strchr(mem->name, '\r')))
|
||||
*p = 0;
|
||||
|
||||
if ((p = strchr(mem->name, '"')))
|
||||
*p = 0;
|
||||
|
||||
tell(4, "set name to '%s'", mem->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// since some sources update "ETag" an "Last-Modified:" without changing the contents
|
||||
// we have to use "Content-Length:" to check for updates :(
|
||||
{
|
||||
const char* attribute = "Content-Length: ";
|
||||
|
||||
if ((p = strcasestr((char*)ptr, attribute)))
|
||||
{
|
||||
sprintf(mem->tag, "%s", p+strlen(attribute));
|
||||
|
||||
if ((p = strchr(mem->tag, '\n')))
|
||||
*p = 0;
|
||||
|
||||
if ((p = strchr(mem->tag, '\r')))
|
||||
*p = 0;
|
||||
|
||||
if ((p = strchr(mem->tag, '"')))
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// Download File
|
||||
//***************************************************************************
|
||||
|
||||
int downloadFile(const char* url, int& size, MemoryStruct* data, int timeout, const char* userAgent)
|
||||
{
|
||||
CURL* curl_handle;
|
||||
long code;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
size = 0;
|
||||
|
||||
// init curl
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
|
||||
{
|
||||
tell(0, "Error, something went wrong with curl_global_init()");
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
if (!curl_handle)
|
||||
{
|
||||
tell(0, "Error, unable to get handle from curl_easy_init()");
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
if (EPG2VDRConfig.useproxy)
|
||||
{
|
||||
curl_easy_setopt(curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_PROXY, EPG2VDRConfig.httpproxy); // Specify HTTP proxy
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, url); // Specify URL to get
|
||||
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 0); // don't follow redirects
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); // Send all data to this function
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void*)data); // Pass our 'data' struct to the callback function
|
||||
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, WriteHeaderCallback); // Send header to this function
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void*)data); // Pass some header details to this struct
|
||||
curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 100*1024*1024); // Set maximum file size to get (bytes)
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1); // No progress meter
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); // No signaling
|
||||
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout); // Set timeout
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOBODY, data->headerOnly ? 1 : 0); //
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, userAgent); // Some servers don't like requests
|
||||
// that are made without a user-agent field
|
||||
// perform http-get
|
||||
|
||||
if ((res = curl_easy_perform(curl_handle)) != 0)
|
||||
{
|
||||
data->clear();
|
||||
|
||||
tell(1, "Error, download failed; %s (%d)",
|
||||
curl_easy_strerror(res), res);
|
||||
curl_easy_cleanup(curl_handle); // Cleanup curl stuff
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &code);
|
||||
curl_easy_cleanup(curl_handle); // cleanup curl stuff
|
||||
|
||||
if (code == 404)
|
||||
{
|
||||
data->clear();
|
||||
return fail;
|
||||
}
|
||||
|
||||
size = data->size;
|
||||
|
||||
return success;
|
||||
}
|
158
lib/dbdict.c
Normal file
158
lib/dbdict.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* dbdict.c
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "dbdict.h"
|
||||
|
||||
//***************************************************************************
|
||||
// cDbDict
|
||||
//***************************************************************************
|
||||
|
||||
cDbDict::cDbDict()
|
||||
{
|
||||
inside = no;
|
||||
}
|
||||
|
||||
cDbDict::~cDbDict()
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// In
|
||||
//***************************************************************************
|
||||
|
||||
int cDbDict::in(const char* file)
|
||||
{
|
||||
FILE* f;
|
||||
char* line = 0;
|
||||
size_t size = 0;
|
||||
char* path;
|
||||
|
||||
asprintf(&path, "%s", file);
|
||||
|
||||
f = fopen(path, "r");
|
||||
|
||||
while (getline(&line, &size, f) > 0)
|
||||
{
|
||||
char* p = strstr(line, "//");
|
||||
|
||||
if (p) *p = 0;
|
||||
|
||||
allTrim(line);
|
||||
|
||||
if (isEmpty(line))
|
||||
continue;
|
||||
|
||||
if (atLine(line) != success)
|
||||
{
|
||||
tell(0, "Found unexpected definition '%s', aborting", line);
|
||||
free(path);
|
||||
return fail;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(line);
|
||||
free(path);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// At Line
|
||||
//***************************************************************************
|
||||
|
||||
int cDbDict::atLine(const char* line)
|
||||
{
|
||||
const char* p;
|
||||
|
||||
if (p = strcasestr(line, "Table"))
|
||||
{
|
||||
char tableName[100];
|
||||
|
||||
p += strlen("Table");
|
||||
strcpy(tableName, p);
|
||||
tell(0, "Table: '%s'", tableName);
|
||||
}
|
||||
|
||||
else if (strchr(line, '{'))
|
||||
inside = yes;
|
||||
|
||||
else if (strchr(line, '}'))
|
||||
inside = no;
|
||||
|
||||
else if (inside)
|
||||
parseField(line);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// Get Token
|
||||
//***************************************************************************
|
||||
|
||||
int getToken(const char*& p, char* token, int size)
|
||||
{
|
||||
char* dest = token;
|
||||
int num = 0;
|
||||
|
||||
while (*p && *p == ' ')
|
||||
p++;
|
||||
|
||||
while (*p && *p != ' ' && num < size)
|
||||
{
|
||||
if (*p == '"')
|
||||
p++;
|
||||
else
|
||||
{
|
||||
*dest++ = *p++;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// Parse Field
|
||||
//***************************************************************************
|
||||
|
||||
int cDbDict::parseField(const char* line)
|
||||
{
|
||||
const int sizeTokenMax = 100;
|
||||
FieldDef f;
|
||||
char token[sizeTokenMax+TB];
|
||||
const char* p = line;
|
||||
|
||||
// tell(0, "Got: '%s'", p);
|
||||
|
||||
for (int i = 0; i < dtCount; i++)
|
||||
{
|
||||
if (getToken(p, token, sizeTokenMax) != success)
|
||||
{
|
||||
tell(0, "Errot: can't parse line [%s]", line);
|
||||
return fail;
|
||||
}
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case dtName: f.name = strdup(token); break;
|
||||
case dtDescription: break;
|
||||
case dtFormat: f.format = toDictFormat(token); break;
|
||||
case dtSize: f.size = atoi(token); break;
|
||||
case dtType: f.type = toType(token); break;
|
||||
}
|
||||
|
||||
free((char*)f.name); // böser cast ...
|
||||
|
||||
tell(0, "token %d -> '%s'", i, token);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
52
lib/dbdict.h
Normal file
52
lib/dbdict.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* dbdict.h
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DBDICT_H
|
||||
#define __DBDICT_H
|
||||
|
||||
#include "db.h"
|
||||
|
||||
//***************************************************************************
|
||||
// cDbDict
|
||||
//***************************************************************************
|
||||
|
||||
class cDbDict : public cDbService
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// declarations
|
||||
|
||||
enum DictToken
|
||||
{
|
||||
dtName,
|
||||
dtDescription,
|
||||
dtFormat,
|
||||
dtSize,
|
||||
dtType,
|
||||
|
||||
dtCount
|
||||
};
|
||||
|
||||
cDbDict();
|
||||
virtual ~cDbDict();
|
||||
|
||||
int in(const char* file);
|
||||
|
||||
protected:
|
||||
|
||||
int atLine(const char* line);
|
||||
int parseField(const char* line);
|
||||
|
||||
// data
|
||||
|
||||
int inside;
|
||||
static FieldDef fields[];
|
||||
|
||||
};
|
||||
|
||||
#endif // __DBDICT_H
|
279
lib/demo.c
Normal file
279
lib/demo.c
Normal file
@ -0,0 +1,279 @@
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "db.h"
|
||||
#include "tabledef.h"
|
||||
|
||||
cDbConnection* connection = 0;
|
||||
|
||||
//***************************************************************************
|
||||
// Init Connection
|
||||
//***************************************************************************
|
||||
|
||||
void initConnection()
|
||||
{
|
||||
cDbConnection::init();
|
||||
|
||||
cDbConnection::setEncoding("utf8");
|
||||
cDbConnection::setHost("localhost");
|
||||
|
||||
cDbConnection::setPort(3306);
|
||||
cDbConnection::setName("epg2vdr");
|
||||
cDbConnection::setUser("epg2vdr");
|
||||
cDbConnection::setPass("epg");
|
||||
cDbTable::setConfPath("/etc/epgd/");
|
||||
|
||||
connection = new cDbConnection();
|
||||
}
|
||||
|
||||
void exitConnection()
|
||||
{
|
||||
cDbConnection::exit();
|
||||
|
||||
if (connection)
|
||||
delete connection;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
int demoStatement()
|
||||
{
|
||||
int status = success;
|
||||
|
||||
cTableEvents* eventsDb = new cTableEvents(connection);
|
||||
|
||||
tell(0, "------------------- attach table ---------------");
|
||||
|
||||
// open table (attach)
|
||||
|
||||
if (eventsDb->open() != success)
|
||||
return fail;
|
||||
|
||||
tell(0, "---------------- prepare select statement -------------");
|
||||
|
||||
// vorbereiten (prepare) eines statement, am besten einmal bei programmstart!
|
||||
// ----------
|
||||
// select eventid, compshorttext, episodepart, episodelang
|
||||
// from events
|
||||
// where eventid > ?
|
||||
|
||||
cDbStatement* selectByCompTitle = new cDbStatement(eventsDb);
|
||||
|
||||
status += selectByCompTitle->build("select ");
|
||||
status += selectByCompTitle->bind(cTableEvents::fiEventId, cDBS::bndOut);
|
||||
status += selectByCompTitle->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", ");
|
||||
status += selectByCompTitle->bind(cTableEvents::fiTitle, cDBS::bndOut, ", ");
|
||||
status += selectByCompTitle->build(" from %s where ", eventsDb->TableName());
|
||||
status += selectByCompTitle->bindCmp(0, cTableEvents::fiEventId, 0, ">");
|
||||
|
||||
status += selectByCompTitle->prepare(); // prepare statement
|
||||
|
||||
if (status != success)
|
||||
{
|
||||
// prepare sollte oracle fehler ausgegeben haben!
|
||||
|
||||
delete eventsDb;
|
||||
delete selectByCompTitle;
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
tell(0, "------------------ prepare done ----------------------");
|
||||
|
||||
tell(0, "------------------ create some rows ----------------------");
|
||||
|
||||
eventsDb->clear(); // alle values löschen
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
char* title;
|
||||
asprintf(&title, "title %d", i);
|
||||
|
||||
eventsDb->setValue(cTableEvents::fiEventId, 800 + i * 100);
|
||||
eventsDb->setValue(cTableEvents::fiChannelId, "xxx-yyyy-zzz");
|
||||
eventsDb->setValue(cTableEvents::fiTitle, title);
|
||||
|
||||
eventsDb->store(); // store -> select mit anschl. update oder insert je nachdem ob dier PKey bereits vorhanden ist
|
||||
// eventsDb->insert(); // sofern man schon weiß das es ein insert ist
|
||||
// eventsDb->update(); // sofern man schon weiß das der Datensatz vorhanden ist
|
||||
|
||||
free(title);
|
||||
}
|
||||
|
||||
tell(0, "------------------ done ----------------------");
|
||||
|
||||
tell(0, "-------- select all where eventid > 1000 -------------");
|
||||
|
||||
eventsDb->clear(); // alle values löschen
|
||||
eventsDb->setValue(cTableEvents::fiEventId, 1000);
|
||||
|
||||
for (int f = selectByCompTitle->find(); f; f = selectByCompTitle->fetch())
|
||||
{
|
||||
tell(0, "id: %ld", eventsDb->getIntValue(cTableEvents::fiEventId));
|
||||
tell(0, "channel: %s", eventsDb->getStrValue(cTableEvents::fiChannelId));
|
||||
tell(0, "titel: %s", eventsDb->getStrValue(cTableEvents::fiTitle));
|
||||
}
|
||||
|
||||
// freigeben der Ergebnissmenge !!
|
||||
|
||||
selectByCompTitle->freeResult();
|
||||
|
||||
// folgendes am programmende
|
||||
|
||||
delete eventsDb; // implizietes close (detach)
|
||||
delete selectByCompTitle; // statement freigeben (auch gegen die DB)
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// Join
|
||||
//***************************************************************************
|
||||
|
||||
int joinDemo()
|
||||
{
|
||||
int status = success;
|
||||
|
||||
// grundsätzlich genügt hier auch eine Tabelle, für die anderen sind cDbValue Instanzen außreichend
|
||||
// so ist es etwas einfacher die cDbValues zu initialisieren.
|
||||
// Ich habe statische "virtual FieldDef* getFieldDef(int f)" Methode in der Tabellenklassen geplant
|
||||
// um ohne Instanz der cTable ein Feld einfach initialisieren zu können
|
||||
|
||||
cTableEvents* eventsDb = new cTableEvents(connection);
|
||||
cTableImageRefs* imageRefDb = new cTableImageRefs(connection);
|
||||
cTableImages* imageDb = new cTableImages(connection);
|
||||
|
||||
tell(0, "------------------- attach table ---------------");
|
||||
|
||||
// open table (attach)
|
||||
|
||||
if (eventsDb->open() != success)
|
||||
return fail;
|
||||
|
||||
if (imageDb->open() != success)
|
||||
return fail;
|
||||
|
||||
if (imageRefDb->open() != success)
|
||||
return fail;
|
||||
|
||||
tell(0, "---------------- prepare select statement -------------");
|
||||
|
||||
// all images
|
||||
|
||||
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||
|
||||
// prepare fields
|
||||
|
||||
cDbValue imageUpdSp;
|
||||
cDbValue imageSize;
|
||||
cDbValue masterId;
|
||||
|
||||
cDBS::FieldDef imageSizeDef = { "image", cDBS::ffUInt, 0, 999, cDBS::ftData }; // eine Art ein Feld zu erzeugen
|
||||
imageSize.setField(&imageSizeDef); // eine andere Art ein Feld zu erzeugen ...
|
||||
imageUpdSp.setField(imageDb->getField(cTableImages::fiUpdSp));
|
||||
masterId.setField(eventsDb->getField(cTableEvents::fiMasterId));
|
||||
|
||||
// select e.masterid, r.imagename, r.eventid, r.lfn, length(i.image)
|
||||
// from imagerefs r, images i, events e
|
||||
// where i.imagename = r.imagename
|
||||
// and e.eventid = r.eventid
|
||||
// and (i.updsp > ? or r.updsp > ?)
|
||||
|
||||
selectAllImages->build("select ");
|
||||
selectAllImages->setBindPrefix("e.");
|
||||
selectAllImages->bind(&masterId, cDBS::bndOut);
|
||||
selectAllImages->setBindPrefix("r.");
|
||||
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut, ", ");
|
||||
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||
selectAllImages->setBindPrefix("i.");
|
||||
selectAllImages->build(", length(");
|
||||
selectAllImages->bind(&imageSize, cDBS::bndOut);
|
||||
selectAllImages->build(")");
|
||||
selectAllImages->clrBindPrefix();
|
||||
selectAllImages->build(" from %s r, %s i, %s e where ",
|
||||
imageRefDb->TableName(), imageDb->TableName(), eventsDb->TableName());
|
||||
selectAllImages->build("e.%s = r.%s and i.%s = r.%s and (",
|
||||
eventsDb->getField(cTableEvents::fiEventId)->name,
|
||||
imageRefDb->getField(cTableImageRefs::fiEventId)->name,
|
||||
imageDb->getField(cTableImages::fiImgName)->name,
|
||||
imageRefDb->getField(cTableImageRefs::fiImgName)->name);
|
||||
selectAllImages->bindCmp("i", &imageUpdSp, ">");
|
||||
selectAllImages->build(" or ");
|
||||
selectAllImages->bindCmp("r", cTableImageRefs::fiUpdSp, 0, ">");
|
||||
selectAllImages->build(")");
|
||||
|
||||
status += selectAllImages->prepare();
|
||||
|
||||
if (status != success)
|
||||
{
|
||||
// prepare sollte oracle fehler ausgegeben haben!
|
||||
|
||||
delete eventsDb;
|
||||
delete imageDb;
|
||||
delete imageRefDb;
|
||||
delete selectAllImages;
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
tell(0, "------------------ prepare done ----------------------");
|
||||
|
||||
tell(0, "------------------ select ----------------------");
|
||||
|
||||
time_t since = time(0) - 60 * 60;
|
||||
imageRefDb->clear();
|
||||
imageRefDb->setValue(cTableImageRefs::fiUpdSp, since);
|
||||
imageUpdSp.setValue(since);
|
||||
|
||||
for (int res = selectAllImages->find(); res; res = selectAllImages->fetch())
|
||||
{
|
||||
// so kommst du an die Werte der unterschgiedlichen Tabellen
|
||||
|
||||
// int eventid = masterId.getIntValue();
|
||||
// const char* imageName = imageRefDb->getStrValue(cTableImageRefs::fiImgName);
|
||||
// int lfn = imageRefDb->getIntValue(cTableImageRefs::fiLfn);
|
||||
// int size = imageSize.getIntValue();
|
||||
|
||||
|
||||
}
|
||||
|
||||
// freigeben der Ergebnissmenge !!
|
||||
|
||||
selectAllImages->freeResult();
|
||||
|
||||
// folgendes am programmende
|
||||
|
||||
delete eventsDb; // implizietes close (detach)
|
||||
delete imageDb;
|
||||
delete imageRefDb;
|
||||
delete selectAllImages; // statement freigeben (auch gegen die DB)
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Main
|
||||
//***************************************************************************
|
||||
|
||||
int main()
|
||||
{
|
||||
EPG2VDRConfig.logstdout = yes;
|
||||
EPG2VDRConfig.loglevel = 2;
|
||||
|
||||
initConnection();
|
||||
|
||||
// demoStatement();
|
||||
// joinDemo();
|
||||
|
||||
tell(0, "uuid: '%s'", getUniqueId());
|
||||
|
||||
exitConnection();
|
||||
|
||||
return 0;
|
||||
}
|
190
lib/imgtools.c
Normal file
190
lib/imgtools.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* imgtools.c
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "imgtools.h"
|
||||
|
||||
//***************************************************************************
|
||||
// Image converting stuff
|
||||
//***************************************************************************
|
||||
|
||||
int fromJpeg(Imlib_Image& image, unsigned char* buffer, int size)
|
||||
{
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int w, h;
|
||||
DATA8 *ptr, *line[16], *data;
|
||||
DATA32 *ptr2, *dest;
|
||||
int x, y;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_mem_src(&cinfo, buffer, size);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
w = cinfo.output_width;
|
||||
h = cinfo.output_height;
|
||||
|
||||
image = imlib_create_image(w, h);
|
||||
imlib_context_set_image(image);
|
||||
|
||||
dest = ptr2 = imlib_image_get_data();
|
||||
data = (DATA8*)malloc(w * 16 * cinfo.output_components);
|
||||
|
||||
for (int i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||
line[i] = data + (i * w * cinfo.output_components);
|
||||
|
||||
for (int l = 0; l < h; l += cinfo.rec_outbuf_height)
|
||||
{
|
||||
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
|
||||
int scans = cinfo.rec_outbuf_height;
|
||||
|
||||
if (h - l < scans)
|
||||
scans = h - l;
|
||||
|
||||
ptr = data;
|
||||
|
||||
for (y = 0; y < scans; y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
|
||||
ptr += cinfo.output_components;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
imlib_image_put_back_data(dest);
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
long toJpeg(Imlib_Image image, MemoryStruct* data, int quality)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo = { 0 };
|
||||
struct jpeg_error_mgr jerr;
|
||||
DATA32* ptr;
|
||||
DATA8* buf;
|
||||
long unsigned int size = data->size;
|
||||
|
||||
imlib_context_set_image(image);
|
||||
|
||||
data->clear();
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_mem_dest(&cinfo, (unsigned char**)(&data->memory), &size);
|
||||
|
||||
cinfo.image_width = imlib_image_get_width();
|
||||
cinfo.image_height = imlib_image_get_height();
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
// get data pointer
|
||||
|
||||
if (!(ptr = imlib_image_get_data_for_reading_only()))
|
||||
return 0;
|
||||
|
||||
// allocate a small buffer to convert image data */
|
||||
|
||||
buf = (DATA8*)malloc(imlib_image_get_width() * 3 * sizeof(DATA8));
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
// convert scanline from ARGB to RGB packed
|
||||
|
||||
for (int j = 0, i = 0; i < imlib_image_get_width(); i++)
|
||||
{
|
||||
buf[j++] = ((*ptr) >> 16) & 0xff;
|
||||
buf[j++] = ((*ptr) >> 8) & 0xff;
|
||||
buf[j++] = ((*ptr)) & 0xff;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
// write scanline
|
||||
|
||||
jpeg_write_scanlines(&cinfo, (JSAMPROW*)(&buf), 1);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
return data->size;
|
||||
}
|
||||
|
||||
int scaleImageToJpegBuffer(Imlib_Image image, MemoryStruct* data, int width, int height)
|
||||
{
|
||||
if (width && height)
|
||||
{
|
||||
Imlib_Image scaledImage;
|
||||
|
||||
imlib_context_set_image(image);
|
||||
|
||||
int imgWidth = imlib_image_get_width();
|
||||
int imgHeight = imlib_image_get_height();
|
||||
double ratio = (double)imgWidth / (double)imgHeight;
|
||||
|
||||
if ((double)width/(double)imgWidth < (double)height/(double)imgHeight)
|
||||
height = (int)((double)width / ratio);
|
||||
else
|
||||
width = (int)((double)height * ratio);
|
||||
|
||||
scaledImage = imlib_create_image(width, height);
|
||||
imlib_context_set_image(scaledImage);
|
||||
|
||||
imlib_context_set_color(240, 240, 240, 255);
|
||||
imlib_image_fill_rectangle(0, 0, width, height);
|
||||
|
||||
imlib_blend_image_onto_image(image, 0, 0, 0,
|
||||
imgWidth, imgHeight, 0, 0,
|
||||
width, height);
|
||||
|
||||
toJpeg(scaledImage, data, 70);
|
||||
|
||||
imlib_context_set_image(scaledImage);
|
||||
imlib_free_image();
|
||||
|
||||
tell(1, "Scaled image to %d/%d, now %d bytes", width, height, (int)data->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
toJpeg(image, data, 70);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int scaleJpegBuffer(MemoryStruct* data, int width, int height)
|
||||
{
|
||||
Imlib_Image image;
|
||||
|
||||
fromJpeg(image, (unsigned char*)data->memory, data->size);
|
||||
|
||||
scaleImageToJpegBuffer(image, data, width, height);
|
||||
|
||||
imlib_context_set_image(image);
|
||||
imlib_free_image();
|
||||
|
||||
return success;
|
||||
}
|
28
lib/imgtools.h
Normal file
28
lib/imgtools.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* imgtools.c
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __IMGTOOLS_H
|
||||
#define __IMGTOOLS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jpeglib.h>
|
||||
#include <Imlib2.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
//***************************************************************************
|
||||
// Image Manipulating
|
||||
//***************************************************************************
|
||||
|
||||
int fromJpeg(Imlib_Image& image, unsigned char* buffer, int size);
|
||||
long toJpeg(Imlib_Image image, MemoryStruct* data, int quality);
|
||||
int scaleImageToJpegBuffer(Imlib_Image image, MemoryStruct* data, int width = 0, int height = 0);
|
||||
int scaleJpegBuffer(MemoryStruct* data, int width = 0, int height = 0);
|
||||
|
||||
//***************************************************************************
|
||||
#endif // __IMGTOOLS_H
|
458
lib/test.c
Normal file
458
lib/test.c
Normal file
@ -0,0 +1,458 @@
|
||||
|
||||
#include <stdint.h> // uint_64_t
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "db.h"
|
||||
#include "tabledef.h"
|
||||
#include "dbdict.h"
|
||||
|
||||
cDbConnection* connection = 0;
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
class cTimeMs
|
||||
{
|
||||
private:
|
||||
|
||||
uint64_t begin;
|
||||
|
||||
public:
|
||||
|
||||
cTimeMs(int Ms = 0);
|
||||
static uint64_t Now(void);
|
||||
void Set(int Ms = 0);
|
||||
bool TimedOut(void);
|
||||
uint64_t Elapsed(void);
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Init Connection
|
||||
//***************************************************************************
|
||||
|
||||
void initConnection()
|
||||
{
|
||||
cDbConnection::init();
|
||||
|
||||
cDbConnection::setEncoding("utf8");
|
||||
cDbConnection::setHost("localhost");
|
||||
cDbConnection::setPort(EPG2VDRConfig.dbPort);
|
||||
cDbConnection::setName(EPG2VDRConfig.dbName);
|
||||
cDbConnection::setUser(EPG2VDRConfig.dbUser);
|
||||
cDbConnection::setPass(EPG2VDRConfig.dbPass);
|
||||
cDbTable::setConfPath("/etc/epgd/");
|
||||
|
||||
connection = new cDbConnection();
|
||||
}
|
||||
|
||||
void exitConnection()
|
||||
{
|
||||
cDbConnection::exit();
|
||||
|
||||
if (connection)
|
||||
delete connection;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
void chkCompress()
|
||||
{
|
||||
std::string s = "_+*!#?=&%$< Hallo TEIL Hallo Folge ";
|
||||
|
||||
printf("'%s'\n", s.c_str());
|
||||
prepareCompressed(s);
|
||||
printf("'%s'\n", s.c_str());
|
||||
|
||||
s = "Place Vendôme - Heiße Diamanten";
|
||||
printf("'%s'\n", s.c_str());
|
||||
prepareCompressed(s);
|
||||
printf("'%s'\n", s.c_str());
|
||||
|
||||
s = "Halöö älter";
|
||||
printf("'%s'\n", s.c_str());
|
||||
prepareCompressed(s);
|
||||
printf("'%s'\n", s.c_str());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
void chkStatement1()
|
||||
{
|
||||
cDbTable* epgDb = new cTableEvents(connection);
|
||||
|
||||
if (epgDb->open() != success)
|
||||
{
|
||||
tell(0, "Could not access database '%s:%d' (%s)",
|
||||
cDbConnection::getHost(), cDbConnection::getPort(), epgDb->TableName());
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
// prepare statement to mark wasted DVB events
|
||||
|
||||
cDbValue* endTime = new cDbValue("starttime+duration", cDBS::ffInt, 10);
|
||||
cDbStatement* updateDelFlg = new cDbStatement(epgDb);
|
||||
|
||||
// update events set delflg = ?, updsp = ?
|
||||
// where channelid = ? and source = ?
|
||||
// and starttime+duration > ?
|
||||
// and starttime < ?
|
||||
// and (tableid > ? or (tableid = ? and version <> ?))
|
||||
|
||||
updateDelFlg->build("update %s set ", epgDb->TableName());
|
||||
updateDelFlg->bind(cTableEvents::fiDelFlg, cDBS::bndIn | cDBS::bndSet);
|
||||
updateDelFlg->bind(cTableEvents::fiUpdSp, cDBS::bndIn | cDBS::bndSet, ", ");
|
||||
updateDelFlg->build(" where ");
|
||||
updateDelFlg->bind(cTableEvents::fiChannelId, cDBS::bndIn | cDBS::bndSet);
|
||||
updateDelFlg->bind(cTableEvents::fiSource, cDBS::bndIn | cDBS::bndSet, " and ");
|
||||
|
||||
updateDelFlg->bindCmp(0, endTime, ">", " and ");
|
||||
|
||||
updateDelFlg->bindCmp(0, cTableEvents::fiStartTime, 0, "<" , " and ");
|
||||
updateDelFlg->bindCmp(0, cTableEvents::fiTableId, 0, ">" , " and (");
|
||||
updateDelFlg->bindCmp(0, cTableEvents::fiTableId, 0, "=" , " or (");
|
||||
updateDelFlg->bindCmp(0, cTableEvents::fiVersion, 0, "<>" , " and ");
|
||||
updateDelFlg->build("));");
|
||||
|
||||
updateDelFlg->prepare();
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
void chkStatement2()
|
||||
{
|
||||
cDbTable* imageRefDb = new cTableImageRefs(connection);
|
||||
cDbTable* imageDb = new cTableImages(connection);
|
||||
|
||||
if (imageRefDb->open() != success)
|
||||
return ;
|
||||
|
||||
if (imageDb->open() != success)
|
||||
return ;
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||
|
||||
cDbValue imageData;
|
||||
imageData.setField(imageDb->getField(cTableImages::fiImage));
|
||||
|
||||
// select r.imagename, r.eventid, r.lfn, i.image from imagerefs r, images i
|
||||
// where r.imagename = i.imagename and i.image is not null;
|
||||
|
||||
selectAllImages->build("select ");
|
||||
selectAllImages->setBindPrefix("r.");
|
||||
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut);
|
||||
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||
selectAllImages->setBindPrefix("i.");
|
||||
selectAllImages->bind(&imageData, cDBS::bndOut, ",");
|
||||
selectAllImages->clrBindPrefix();
|
||||
selectAllImages->build(" from %s r, %s i where ", imageRefDb->TableName(), imageDb->TableName());
|
||||
selectAllImages->build("r.%s = i.%s and i.%s is not null;",
|
||||
imageRefDb->getField(cTableImageRefs::fiImgName)->name,
|
||||
imageDb->getField(cTableImages::fiImgName)->name,
|
||||
imageDb->getField(cTableImages::fiImage)->name);
|
||||
|
||||
selectAllImages->prepare();
|
||||
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
//delete s;
|
||||
delete imageRefDb;
|
||||
delete imageDb;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
void chkStatement3()
|
||||
{
|
||||
int count = 0;
|
||||
int lcount = 0;
|
||||
|
||||
cDbTable* epgDb = new cTableEvents(connection);
|
||||
cDbTable* mapDb = new cTableChannelMap(connection);
|
||||
|
||||
if (epgDb->open() != success)
|
||||
return ;
|
||||
|
||||
if (mapDb->open() != success)
|
||||
return ;
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
cDbStatement* s = new cDbStatement(epgDb);
|
||||
|
||||
s->build("select ");
|
||||
s->setBindPrefix("e.");
|
||||
s->bind(cTableEvents::fiEventId, cDBS::bndOut);
|
||||
s->bind(cTableEvents::fiChannelId, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiSource, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiDelFlg, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiFileRef, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiTableId, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiVersion, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiTitle, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiShortText, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiStartTime, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiDuration, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiParentalRating, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiVps, cDBS::bndOut, ", ");
|
||||
s->bind(cTableEvents::fiDescription, cDBS::bndOut, ", ");
|
||||
s->clrBindPrefix();
|
||||
s->build(" from eventsview e, %s m where ", mapDb->TableName());
|
||||
s->build("e.%s = m.%s and e.%s = m.%s and ",
|
||||
epgDb->getField(cTableEvents::fiChannelId)->name,
|
||||
mapDb->getField(cTableChannelMap::fiChannelName)->name,
|
||||
epgDb->getField(cTableEvents::fiSource)->name,
|
||||
mapDb->getField(cTableChannelMap::fiSource)->name);
|
||||
s->bindCmp("e", cTableEvents::fiUpdSp, 0, ">");
|
||||
s->build(" order by m.%s;", mapDb->getField(cTableChannelMap::fiChannelName)->name);
|
||||
|
||||
s->prepare();
|
||||
|
||||
epgDb->clear();
|
||||
epgDb->setValue(cTableEvents::fiUpdSp, (double)0);
|
||||
epgDb->setValue(cTableEvents::fiSource, "vdr"); // used by selectUpdEventsByChannel
|
||||
epgDb->setValue(cTableEvents::fiChannelId, "xxxxxxxxxxxxx"); // used by selectUpdEventsByChannel
|
||||
|
||||
int channels = 0;
|
||||
char chan[100]; *chan = 0;
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
for (int found = s->find(); found; found = s->fetch())
|
||||
{
|
||||
if (!*chan || strcmp(chan, epgDb->getStrValue(cTableEvents::fiChannelId)) != 0)
|
||||
{
|
||||
if (*chan)
|
||||
tell(0, "processed %-20s with %d events", chan, count - lcount);
|
||||
|
||||
lcount = count;
|
||||
channels++;
|
||||
strcpy(chan, epgDb->getStrValue(cTableEvents::fiChannelId));
|
||||
|
||||
tell(0, "processing %-20s now", chan);
|
||||
}
|
||||
|
||||
tell(0, "-> '%s' - (%ld)", epgDb->getStrValue(cTableEvents::fiChannelId),
|
||||
epgDb->getIntValue(cTableEvents::fiEventId));
|
||||
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
s->freeResult();
|
||||
|
||||
tell(0, "---------------------------------------------------");
|
||||
tell(0, "updated %d channels and %d events", channels, count);
|
||||
tell(0, "---------------------------------------------------");
|
||||
|
||||
delete s;
|
||||
delete epgDb;
|
||||
delete mapDb;
|
||||
}
|
||||
|
||||
// --- cTimeMs ---------------------------------------------------------------
|
||||
|
||||
cTimeMs::cTimeMs(int Ms)
|
||||
{
|
||||
if (Ms >= 0)
|
||||
Set(Ms);
|
||||
else
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
uint64_t cTimeMs::Now(void)
|
||||
{
|
||||
#define MIN_RESOLUTION 5 // ms
|
||||
static bool initialized = false;
|
||||
static bool monotonic = false;
|
||||
struct timespec tp;
|
||||
if (!initialized) {
|
||||
// check if monotonic timer is available and provides enough accurate resolution:
|
||||
if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
|
||||
// long Resolution = tp.tv_nsec;
|
||||
// require a minimum resolution:
|
||||
if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
|
||||
monotonic = true;
|
||||
}
|
||||
else
|
||||
tell(0, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
|
||||
}
|
||||
else
|
||||
tell(0, "cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
|
||||
}
|
||||
else
|
||||
tell(0, "cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
|
||||
initialized = true;
|
||||
}
|
||||
if (monotonic) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
|
||||
return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
|
||||
tell(0, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
|
||||
monotonic = false;
|
||||
// fall back to gettimeofday()
|
||||
}
|
||||
struct timeval t;
|
||||
if (gettimeofday(&t, NULL) == 0)
|
||||
return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cTimeMs::Set(int Ms)
|
||||
{
|
||||
begin = Now() + Ms;
|
||||
}
|
||||
|
||||
bool cTimeMs::TimedOut(void)
|
||||
{
|
||||
return Now() >= begin;
|
||||
}
|
||||
|
||||
uint64_t cTimeMs::Elapsed(void)
|
||||
{
|
||||
return Now() - begin;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
void chkStatement4()
|
||||
{
|
||||
cDbTable* eventDb = new cTableEvents(connection);
|
||||
if (eventDb->open() != success) return;
|
||||
|
||||
cDbTable* imageRefDb = new cTableImageRefs(connection);
|
||||
if (imageRefDb->open() != success) return;
|
||||
|
||||
cDbTable* imageDb = new cTableImages(connection);
|
||||
if (imageDb->open() != success) return;
|
||||
|
||||
// select e.masterid, r.imagename, r.eventid, r.lfn, i.image
|
||||
// from imagerefs r, images i, events e
|
||||
// where r.imagename = i.imagename
|
||||
// and e.eventid = r.eventid,
|
||||
// and i.image is not null
|
||||
// and (i.updsp > ? or r.updsp > ?);
|
||||
|
||||
cDBS::FieldDef masterFld = { "masterid", cDBS::ffUInt, 0, 999, cDBS::ftData };
|
||||
cDbValue masterId;
|
||||
cDbValue imageData;
|
||||
cDbValue imageUpdSp;
|
||||
|
||||
masterId.setField(&masterFld);
|
||||
imageData.setField(imageDb->getField(cTableImages::fiImage));
|
||||
imageUpdSp.setField(imageDb->getField(cTableImages::fiUpdSp));
|
||||
|
||||
cDbStatement* selectAllImages = new cDbStatement(imageRefDb);
|
||||
|
||||
selectAllImages->build("select ");
|
||||
selectAllImages->setBindPrefix("e.");
|
||||
selectAllImages->bind(&masterId, cDBS::bndOut);
|
||||
selectAllImages->setBindPrefix("r.");
|
||||
selectAllImages->bind(cTableImageRefs::fiImgName, cDBS::bndOut, ", ");
|
||||
selectAllImages->bind(cTableImageRefs::fiEventId, cDBS::bndOut, ", ");
|
||||
selectAllImages->bind(cTableImageRefs::fiLfn, cDBS::bndOut, ", ");
|
||||
selectAllImages->setBindPrefix("i.");
|
||||
selectAllImages->bind(&imageData, cDBS::bndOut, ", ");
|
||||
selectAllImages->clrBindPrefix();
|
||||
selectAllImages->build(" from %s r, %s i, %s e where ",
|
||||
imageRefDb->TableName(), imageDb->TableName(), eventDb->TableName());
|
||||
selectAllImages->build("e.%s = r.%s and i.%s = r.%s and i.%s is not null and (",
|
||||
eventDb->getField(cTableEvents::fiEventId)->name,
|
||||
imageRefDb->getField(cTableImageRefs::fiEventId)->name,
|
||||
imageDb->getField(cTableImageRefs::fiImgName)->name,
|
||||
imageRefDb->getField(cTableImageRefs::fiImgName)->name,
|
||||
imageDb->getField(cTableImages::fiImage)->name);
|
||||
selectAllImages->bindCmp("i", &imageUpdSp, ">");
|
||||
selectAllImages->build(" or ");
|
||||
selectAllImages->bindCmp("r", cTableImageRefs::fiUpdSp, 0, ">");
|
||||
selectAllImages->build(");");
|
||||
|
||||
selectAllImages->prepare();
|
||||
|
||||
imageRefDb->clear();
|
||||
imageRefDb->setValue(cTableImageRefs::fiUpdSp, 1377733333L);
|
||||
imageUpdSp.setValue(1377733333L);
|
||||
|
||||
int count = 0;
|
||||
for (int res = selectAllImages->find(); res; res = selectAllImages->fetch())
|
||||
{
|
||||
count ++;
|
||||
}
|
||||
tell(0,"%d", count);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// Main
|
||||
//***************************************************************************
|
||||
|
||||
int main()
|
||||
{
|
||||
EPG2VDRConfig.logstdout = yes;
|
||||
EPG2VDRConfig.loglevel = 2;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
char* lang = setlocale(LC_CTYPE, 0);
|
||||
|
||||
if (lang)
|
||||
{
|
||||
tell(0, "Set locale to '%s'", lang);
|
||||
|
||||
if ((strcasestr(lang, "UTF-8") != 0) || (strcasestr(lang, "UTF8") != 0))
|
||||
tell(0, "detected UTF-8");
|
||||
else
|
||||
tell(0, "no UTF-8");
|
||||
}
|
||||
else
|
||||
{
|
||||
tell(0, "Reseting locale for LC_CTYPE failed.");
|
||||
}
|
||||
|
||||
|
||||
cDbDict* dict = new cDbDict();
|
||||
|
||||
dict->in("../epg.dat");
|
||||
|
||||
delete dict;
|
||||
|
||||
return 0;
|
||||
|
||||
initConnection();
|
||||
|
||||
chkCompress();
|
||||
|
||||
tell(0, "duration was: '%s'", ms2Dur(2340).c_str());
|
||||
|
||||
// chkStatement1();
|
||||
// chkStatement2();
|
||||
// chkStatement3();
|
||||
// chkStatement4();
|
||||
|
||||
exitConnection();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user