added lib files

This commit is contained in:
louis 2014-05-09 16:20:06 +02:00
parent 9ebafce3fd
commit 5d7fb01f67
7 changed files with 1341 additions and 0 deletions

176
lib/curl.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}