diff options
Diffstat (limited to 'lib/demo.c')
-rw-r--r-- | lib/demo.c | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/lib/demo.c b/lib/demo.c new file mode 100644 index 0000000..0c4c234 --- /dev/null +++ b/lib/demo.c @@ -0,0 +1,531 @@ +/* + * demo.h + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "config.h" +#include "common.h" + +#include "db.h" +#include "epgservice.h" + +cDbConnection* connection = 0; +const char* logPrefix = ""; + +//*************************************************************************** +// Init Connection +//*************************************************************************** + +void initConnection() +{ + cDbConnection::init(); + + cDbConnection::setHost("localhost"); + // cDbConnection::setHost("192.168.200.101"); + cDbConnection::setPort(3306); + cDbConnection::setName("epg2vdr"); + cDbConnection::setUser("epg2vdr"); + cDbConnection::setPass("epg"); + + cDbConnection::setConfPath("/etc/epgd/"); + cDbConnection::setEncoding("utf8"); + + connection = new cDbConnection(); +} + +void exitConnection() +{ + cDbConnection::exit(); + + if (connection) + delete connection; +} + +//*************************************************************************** +// +//*************************************************************************** + +int demoStatement() +{ + int status = success; + + cDbTable* eventsDb = new cDbTable(connection, "events"); + + 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("EventId", cDBS::bndOut); + status += selectByCompTitle->bind("ChannelId", cDBS::bndOut, ", "); + status += selectByCompTitle->bind("Title", cDBS::bndOut, ", "); + status += selectByCompTitle->build(" from %s where ", eventsDb->TableName()); + status += selectByCompTitle->bindCmp(0, eventsDb->getField("EventId"), 0, ">"); + + status += selectByCompTitle->prepare(); // prepare statement + + if (status != success) + { + // prepare sollte MySQL 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(eventsDb->getField("EventId"), 800 + i * 100); + eventsDb->setValue(eventsDb->getField("ChannelId"), "xxx-yyyy-zzz"); + eventsDb->setValue(eventsDb->getField("Title"), 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(eventsDb->getField("EventId"), 1000); + + for (int f = selectByCompTitle->find(); f; f = selectByCompTitle->fetch()) + { + tell(0, "id: %ld", eventsDb->getIntValue(eventsDb->getField("EventId"))); + tell(0, "channel: %s", eventsDb->getStrValue(eventsDb->getField("ChannelId"))); + tell(0, "titel: %s", eventsDb->getStrValue(eventsDb->getField("Title"))); + } + + // freigeben der Ergebnissmenge !! + + selectByCompTitle->freeResult(); + + // folgendes am programmende + + delete eventsDb; // implizietes close (detach) + delete selectByCompTitle; // statement freigeben (auch gegen die DB) + + return success; +} + +//*************************************************************************** +// Join +//*************************************************************************** + +// #define F_INIT(a,b) cDbFieldDef* a##b = 0; dbDict.init(a##b, #a, #b) + +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 + + cDbTable* eventsDb = new cDbTable(connection, "events"); + cDbTable* imageRefDb = new cDbTable(connection, "imagerefs"); + cDbTable* imageDb = new cDbTable(connection, "images"); + + cDbTable* timerDb = new cDbTable(connection, "timers"); + timerDb->open(yes); + delete timerDb; + + // init dict fields as needed (normaly done once at programm start) + // init and using the pointer improve the speed since the lookup via + // the name is dine only once + + // F_INIT(events, EventId); // ergibt: cDbFieldDef* eventsEventId; dbDict.init(eventsEventId, "events", "EventId"); + + tell(0, "----------------- open table connection ---------------"); + + // open tables (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; + + cDbFieldDef imageSizeDef("image", "image", cDBS::ffUInt, 999, cDBS::ftData, 0); // eine Art ein Feld zu erzeugen + imageSize.setField(&imageSizeDef); + imageUpdSp.setField(imageDb->getField("UpdSp")); + masterId.setField(eventsDb->getField("MasterId")); + + // 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("ImgName", cDBS::bndOut, ", "); + selectAllImages->bind("EventId", cDBS::bndOut, ", "); + selectAllImages->bind("Lfn", 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 (", + "EventId", // eventsEventId->getDbName(), + imageRefDb->getField("EventId")->getDbName(), + "imagename", // direkt den DB Feldnamen verwenden -> nicht so schön da nicht dynamisch + imageRefDb->getField("ImgName")->getDbName()); // ordentlich via dictionary übersetzt -> schön ;) + selectAllImages->bindCmp("i", &imageUpdSp, ">"); + selectAllImages->build(" or "); + selectAllImages->bindCmp("r", imageRefDb->getField("UpdSp"), 0, ">"); + selectAllImages->build(")"); + + status += selectAllImages->prepare(); + + if (status != success) + { + // prepare sollte MySQL Fehler ausgegeben haben! + + delete eventsDb; + delete imageDb; + delete imageRefDb; + delete selectAllImages; + + return fail; + } + + tell(0, "------------------ prepare done ----------------------"); + + + tell(0, "------------------ select ----------------------"); + + time_t since = 0; //time(0) - 60 * 60; + imageRefDb->clear(); + imageRefDb->setValue(imageRefDb->getField("UpdSp"), since); + imageUpdSp.setValue(since); + + for (int res = selectAllImages->find(); res; res = selectAllImages->fetch()) + { + // so kommst du an die Werte der unterschiedlichen Tabellen + + int eventid = masterId.getIntValue(); + const char* imageName = imageRefDb->getStrValue("ImgName"); + int lfn = imageRefDb->getIntValue(imageRefDb->getField("Lfn")); + int size = imageSize.getIntValue(); + + tell(0, "Found (%d) '%s', %d, %d", eventid, imageName, lfn, size); + } + + tell(0, "------------------ done ----------------------"); + + // freigeben der Ergebnissmenge !! + + selectAllImages->freeResult(); + + + // folgendes am programmende + + delete eventsDb; // implizites close (detach) + delete imageDb; + delete imageRefDb; + delete selectAllImages; // statement freigeben (auch gegen die DB) + + return success; +} + +//*************************************************************************** +// +//*************************************************************************** + +int insertDemo() +{ + cDbTable* timerDb = new cDbTable(connection, "timers"); + if (timerDb->open() != success) return fail; + + timerDb->clear(); + timerDb->setValue("EventId", 4444444); + + if (timerDb->insert() == success) + { + tell(0, "Insert succeeded with ID %d", timerDb->getLastInsertId()); + } + + delete timerDb; + + return done; +} + +//*************************************************************************** +// +//*************************************************************************** + +int findUseEvent() +{ + cDbTable* useeventsDb = new cDbTable(connection, "useevents"); + if (useeventsDb->open() != success) return fail; + + // select event by useid + + tell(0, "========================================"); + + cDbStatement* selectEventById = new cDbStatement(useeventsDb); + + // select * from eventsview + // where useid = ? + // and updflg in (.....) + + selectEventById->build("select "); + selectEventById->bindAllOut(); + selectEventById->build(" from %s where ", useeventsDb->TableName()); + selectEventById->bind("USEID", cDBS::bndIn | cDBS::bndSet); + selectEventById->build(" and %s in (%s)", + useeventsDb->getField("UPDFLG")->getDbName(), + Us::getNeeded()); + + selectEventById->prepare(); + + tell(0, "========================================"); + + useeventsDb->clear(); + useeventsDb->setValue("USEID", 1146680); + + const char* flds[] = + { + "ACTOR", + "AUDIO", + "CATEGORY", + "COUNTRY", + "DIRECTOR", + "FLAGS", + "GENRE", + "INFO", + "MUSIC", + "PRODUCER", + "SCREENPLAY", + "SHORTREVIEW", + "TIPP", + "TOPIC", + "YEAR", + "RATING", + "NUMRATING", + "MODERATOR", + "OTHER", + "GUEST", + "CAMERA", + + 0 + }; + + if (selectEventById->find()) + { + FILE* f; + char* fileName = 0; + + asprintf(&fileName, "%s/info.epg2vdr", "."); + + if (!(f = fopen(fileName, "w"))) + { + selectEventById->freeResult(); + tell(0, "Error opening file '%s' failed, %s", fileName, strerror(errno)); + free(fileName); + + return fail; + } + + tell(0, "Storing event details to '%s'", fileName); + + for (int i = 0; flds[i]; i++) + { + cDbFieldDef* field = useeventsDb->getField(flds[i]); + + if (!field) + { + tell(0, "Warning: Field '%s' not found at table '%s'", flds[i], useeventsDb->TableName()); + continue; + } + + if (field->getFormat() == cDbService::ffAscii || + field->getFormat() == cDbService::ffText || + field->getFormat() == cDbService::ffMText) + { + fprintf(f, "%s: %s\n", flds[i], useeventsDb->getStrValue(flds[i])); + } + else + { + fprintf(f, "%s: %ld\n", flds[i], useeventsDb->getIntValue(flds[i])); + } + } + + selectEventById->freeResult(); + free(fileName); + fclose(f); + } + + tell(0, "========================================"); + + selectEventById->freeResult(); + + return done; +} + +//*************************************************************************** +// +//*************************************************************************** + +int updateRecordingDirectory() +{ + int ins = 0; + + cDbTable* recordingDirDb = new cDbTable(connection, "recordingdirs"); + if (recordingDirDb->open() != success) return fail; + + // char* dir = strdup("more~Marvel's Agents of S.H.I.E.L.D.~xxx.ts"); + char* dir = strdup("aaaaa~bbbbbb~ccccc.ts"); + char* pos = strrchr(dir, '~'); + + if (pos) + { + *pos = 0; + + for (int level = 0; level < 3; level++) + { + recordingDirDb->clear(); + + recordingDirDb->setValue("VDRUUID", "foobar"); + recordingDirDb->setValue("DIRECTORY", dir); + + if (!recordingDirDb->find()) + { + ins++; + recordingDirDb->store(); + } + + recordingDirDb->reset(); + + char* pos = strrchr(dir, '~'); + if (pos) *pos=0; + } + } + + tell(0, "inserted %d directories", ins); + + delete recordingDirDb; + free(dir); + + return ins; +} + +//*************************************************************************** +// Main +//*************************************************************************** + +int main(int argc, char** argv) +{ + cEpgConfig::logstdout = yes; + cEpgConfig::loglevel = 2; + + const char* path = "/etc/epgd/epg.dat"; + + if (argc > 1) + path = argv[1]; + + // read deictionary + + dbDict.setFilterFromNameFct(toFieldFilter); + + if (dbDict.in(path, ffEpgd) != success) + { + tell(0, "Invalid dictionary configuration, aborting!"); + return 1; + } + + cUserTimes userTimes; + + tell(0, "--------------"); + //userTimes.clear(); + tell(0, "--------------"); + + userTimes.add("@Now", "What's on now?") ; + userTimes.add("@Next", "What's on next?" ); + userTimes.add("!20:15", "prime time"); + userTimes.add("22:20", "late night"); + userTimes.add("00:00"); + + tell(0, "--------------"); + + for (int i = 0; i < 6; i++) + { + cUserTimes::UserTime* t = userTimes.next(); + + tell(0, "%d - %s (%s) %s", t->getHHMM(), t->getTitle(), t->getHHMMStr(), t->isHighlighted() ? "highlighted" : ""); + } + + return 0; + + // dbDict.show(); + + initConnection(); + + // demoStatement(); + // joinDemo(); + // insertDemo(); + + tell(0, "uuid: '%s'", getUniqueId()); + + tell(0, "- - - - - - - - - - - - - - - - - "); + + //updateRecordingDirectory(); + findUseEvent(); + + tell(0, "- - - - - - - - - - - - - - - - - "); + + exitConnection(); + + return 0; +} |