diff --git a/livesupport/products/scheduler/doc/model/SchedulerModel.zuml b/livesupport/products/scheduler/doc/model/SchedulerModel.zuml index 00c7d4ed9..f84cd246a 100644 Binary files a/livesupport/products/scheduler/doc/model/SchedulerModel.zuml and b/livesupport/products/scheduler/doc/model/SchedulerModel.zuml differ diff --git a/livesupport/products/scheduler/etc/Makefile.in b/livesupport/products/scheduler/etc/Makefile.in index 8441b199f..bda7bc1ad 100644 --- a/livesupport/products/scheduler/etc/Makefile.in +++ b/livesupport/products/scheduler/etc/Makefile.in @@ -21,7 +21,7 @@ # # # Author : $Author: fgerlits $ -# Version : $Revision: 1.17 $ +# Version : $Revision: 1.18 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/Makefile.in,v $ # # @configure_input@ @@ -130,7 +130,9 @@ SCHEDULER_OBJS = ${TMP_DIR}/SignalDispatcher.o \ ${TMP_DIR}/DisplayAudioClipsMethod.o \ ${TMP_DIR}/RevertEditedPlaylistMethod.o \ ${TMP_DIR}/SavePlaylistMethod.o \ - ${TMP_DIR}/PlayLogEntry.o + ${TMP_DIR}/PlayLogFactory.o \ + ${TMP_DIR}/PostgresqlPlayLog.o + SCHEDULER_EXE_OBJS = ${SCHEDULER_OBJS} \ ${TMP_DIR}/main.o @@ -163,7 +165,7 @@ TEST_RUNNER_OBJS = ${SCHEDULER_OBJS} \ ${TMP_DIR}/DisplayAudioClipsMethodTest.o \ ${TMP_DIR}/SavePlaylistMethodTest.o \ ${TMP_DIR}/RevertEditedPlaylistMethodTest.o \ - ${TMP_DIR}/PlayLogEntryTest.o \ + ${TMP_DIR}/PostgresqlPlayLogTest.o \ ${TMP_DIR}/TestRunner.o TEST_RUNNER_LIBS = ${SCHEDULER_EXE_LIBS} -lcppunit -ldl diff --git a/livesupport/products/scheduler/etc/playLogEntry.xml b/livesupport/products/scheduler/etc/playLogEntry.xml deleted file mode 100644 index c6355e782..000000000 --- a/livesupport/products/scheduler/etc/playLogEntry.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -]> - diff --git a/livesupport/products/scheduler/etc/playLogFactory.xml b/livesupport/products/scheduler/etc/playLogFactory.xml new file mode 100644 index 000000000..2fd65fe9a --- /dev/null +++ b/livesupport/products/scheduler/etc/playLogFactory.xml @@ -0,0 +1,10 @@ + + + + +]> + + + diff --git a/livesupport/products/scheduler/src/PlayLogEntry.h b/livesupport/products/scheduler/src/PlayLogEntry.h index b8b22670c..3553a07e9 100644 --- a/livesupport/products/scheduler/src/PlayLogEntry.h +++ b/livesupport/products/scheduler/src/PlayLogEntry.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/PlayLogEntry.h,v $ ------------------------------------------------------------------------------*/ @@ -69,16 +69,11 @@ using namespace LiveSupport::Core; * PlayLogEntries contain information about the audio clips played. * * @author $Author: fgerlits $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ -class PlayLogEntry : public Configurable +class PlayLogEntry { private: - /** - * The name of the configuration XML elmenent used by PlayLogEntry. - */ - static const std::string configElementNameStr; - /** * The unique id of the play log entry. */ @@ -92,7 +87,7 @@ class PlayLogEntry : public Configurable /** * The time this audio clip was played. */ - Ptr::Ref timeStamp; + Ptr::Ref timestamp; public: @@ -105,19 +100,18 @@ class PlayLogEntry : public Configurable /** * Create a play log entry by specifying all details. - * This is used for testing purposes. * * @param id the ID of the play log entry. * @param audioClipId the ID of the audio clip logged - * @param timeStamp the time this audio clip was played. + * @param timestamp the time this audio clip was played. */ PlayLogEntry(Ptr::Ref id, Ptr::Ref audioClipId, - Ptr::Ref timeStamp) throw() + Ptr::Ref timestamp) throw() { this->id = id; this->audioClipId = audioClipId; - this->timeStamp = timeStamp; + this->timestamp = timestamp; } /** @@ -128,31 +122,6 @@ class PlayLogEntry : public Configurable { } - /** - * Return the name of the XML element this object expects - * to be sent to a call to configure(). - * - * @return the name of the expected XML configuration element. - */ - static const std::string - getConfigElementName(void) throw () - { - return configElementNameStr; - } - - /** - * Configure the object based on the XML element supplied. - * The supplied element is expected to be of the name - * returned by configElementName(). - * - * @param element the XML element to configure the object from. - * @exception std::invalid_argument if the supplied XML element - * contains bad configuration information - */ - virtual void - configure(const xmlpp::Element & element) - throw (std::invalid_argument); - /** * Return the ID of the play log entry. * @@ -181,9 +150,9 @@ class PlayLogEntry : public Configurable * @return the the time the audio clip was played. */ Ptr::Ref - getTimeStamp(void) const throw () + getTimestamp(void) const throw () { - return timeStamp; + return timestamp; } }; diff --git a/livesupport/products/scheduler/src/PlayLogFactory.cxx b/livesupport/products/scheduler/src/PlayLogFactory.cxx new file mode 100644 index 000000000..6226db9b7 --- /dev/null +++ b/livesupport/products/scheduler/src/PlayLogFactory.cxx @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PlayLogFactory.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include "LiveSupport/Db/ConnectionManagerFactory.h" +#include "PostgresqlPlayLog.h" +#include "PlayLogFactory.h" + + +using namespace LiveSupport::Core; +using namespace LiveSupport::Db; +using namespace LiveSupport::Scheduler; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * The name of the config element for this class + *----------------------------------------------------------------------------*/ +const std::string PlayLogFactory::configElementNameStr = + "playLogFactory"; + +/*------------------------------------------------------------------------------ + * The singleton instance of PlayLogFactory + *----------------------------------------------------------------------------*/ +Ptr::Ref PlayLogFactory::singleton; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Return the singleton instance to PlayLogFactory + *----------------------------------------------------------------------------*/ +Ptr::Ref +PlayLogFactory :: getInstance(void) throw () +{ + if (!singleton.get()) { + singleton.reset(new PlayLogFactory()); + } + + return singleton; +} + + +/*------------------------------------------------------------------------------ + * Configure the play log factory. + *----------------------------------------------------------------------------*/ +void +PlayLogFactory :: configure(const xmlpp::Element & element) + throw (std::invalid_argument, + std::logic_error) +{ + if (element.get_name() != configElementNameStr) { + std::string eMsg = "Bad configuration element "; + eMsg += element.get_name(); + throw std::invalid_argument(eMsg); + } + + playLog.reset(); + + Ptr::Ref cmf = + ConnectionManagerFactory::getInstance(); + Ptr::Ref cm = cmf->getConnectionManager(); + + // try to look for a PostgresqlPlayLog configuration element + xmlpp::Node::NodeList nodes = + element.get_children(PostgresqlPlayLog::getConfigElementName()); + if (nodes.size() >= 1) { + const xmlpp::Element * configElement = + dynamic_cast (*(nodes.begin())); + Ptr::Ref dbs(new PostgresqlPlayLog(cm)); + dbs->configure(*configElement); + playLog = dbs; + } + + if (!playLog) { + throw std::invalid_argument("no play log factories to configure"); + } +} + + +/*------------------------------------------------------------------------------ + * Install the play log factory. + *----------------------------------------------------------------------------*/ +void +PlayLogFactory :: install(void) throw (std::exception) +{ + if (!playLog) { + throw std::logic_error("PlayLogFactory not yet configured"); + } + + playLog->install(); +} + + +/*------------------------------------------------------------------------------ + * Uninstall the play log factory. + *----------------------------------------------------------------------------*/ +void +PlayLogFactory :: uninstall(void) throw (std::exception) +{ + if (!playLog) { + throw std::logic_error("PlayLogFactory not yet configured"); + } + + playLog->uninstall(); +} + diff --git a/livesupport/products/scheduler/src/PlayLogFactory.h b/livesupport/products/scheduler/src/PlayLogFactory.h new file mode 100644 index 000000000..474c8bad4 --- /dev/null +++ b/livesupport/products/scheduler/src/PlayLogFactory.h @@ -0,0 +1,208 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PlayLogFactory.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef PlayLogFactory_h +#define PlayLogFactory_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + +#include "LiveSupport/Core/Configurable.h" +#include "LiveSupport/Core/Installable.h" +#include "PlayLogInterface.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * The factory to create appropriate PlayLog objects. + * + * This object has to be configured with an element that contains + * the configuration element that the factory should build. + * Currently only PostgresqlPlayLog is supported by this factory. + * + * An example configuration element is the following: + * + *

+ *      <playLogFactory>
+ *          <postgresqlPlayLog/>
+ *      </playLogFactory>
+ *  
+ * + * The DTD for the above element is: + * + *

+ *  <!ELEMENT playLogFactory (postgresqlPlayLog) >
+ *  
+ * + * For details on the <postgreslPlayLog> element, see the + * PostgresqlPlayLog documentation. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + * @see PostgresqlPlayLog + */ +class PlayLogFactory : virtual public Configurable, + virtual public Installable +{ + private: + /** + * The name of the configuration XML elmenent used by this object. + */ + static const std::string configElementNameStr; + + /** + * The singleton instance of this object. + */ + static Ptr::Ref singleton; + + /** + * The play log created by this factory. + */ + Ptr::Ref playLog; + + /** + * The default constructor. + */ + PlayLogFactory(void) throw() + { + } + + + public: + /** + * A virtual destructor, as this class has virtual functions. + */ + virtual + ~PlayLogFactory(void) throw () + { + } + + /** + * Return the name of the XML element this object expects + * to be sent to a call to configure(). + * + * @return the name of the expected XML configuration element. + */ + static const std::string + getConfigElementName(void) throw () + { + return configElementNameStr; + } + + /** + * Returns the singleton instance of this object. + * + * @return the singleton instance of this object. + */ + static Ptr::Ref + getInstance() throw (); + + /** + * Configure the object based on the XML element supplied. + * + * @param element the XML element to configure the object from. + * @exception std::invalid_argument if the supplied XML element + * contains bad configuration information + * @exception std::logic_error if the object has already + * been configured, and can not be reconfigured. + */ + virtual void + configure(const xmlpp::Element & element) + throw (std::invalid_argument, + std::logic_error); + + /** + * Install the component. + * This step involves creating the environment in which the component + * will run. This may be creation of coniguration files, + * database tables, etc. + * + * @exception std::exception on installation problems, + * especially if the PlayLogFactory was not yet configured. + */ + virtual void + install(void) throw (std::exception); + + /** + * Uninstall the component. + * Removes all the resources created in the install step. + * + * @exception std::exception on unistallation problems, + e especially if the PlayLogFactory was not yet configured. + */ + virtual void + uninstall(void) throw (std::exception); + + /** + * Return a play log. + * + * @return the appropriate play log, according to the + * configuration of this factory. + */ + Ptr::Ref + getPlayLog(void) throw () + { + return playLog; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Scheduler +} // namespace LiveSupport + +#endif // PlayLogFactory_h + diff --git a/livesupport/products/scheduler/src/PlayLogInterface.h b/livesupport/products/scheduler/src/PlayLogInterface.h new file mode 100644 index 000000000..9857dd9a4 --- /dev/null +++ b/livesupport/products/scheduler/src/PlayLogInterface.h @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PlayLogInterface.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef PlayLogInterface_h +#define PlayLogInterface_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include + +#include "LiveSupport/Core/Ptr.h" +#include "LiveSupport/Core/Installable.h" +#include "LiveSupport/Core/Playlist.h" +#include "PlayLogEntry.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace boost::posix_time; + +using namespace LiveSupport; +using namespace LiveSupport::Core; + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * The generic interface for the component scheduling events. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + */ +class PlayLogInterface : virtual public Installable +{ + public: + /** + * Add a new entry to the play log. + * + * @param audioClipId the audio clip played. + * @param timeStamp the time the clip was played (started). + * @return the id of the newly created play log entry. + */ + virtual Ptr::Ref + addPlayLogEntry(Ptr::Ref audioClipId, + Ptr::Ref timeStamp) + throw (std::invalid_argument) + = 0; + + /** + * Return the list of play log entries for a specified time interval. + * + * @param fromTime the start of the time of the interval queried, + * inclusive + * @param toTime to end of the time of the interval queried, + * non-inclusive + * @return a vector of the play log entries for the time region. + */ + virtual Ptr::Ref> >::Ref + getPlayLogEntries(Ptr::Ref fromTime, + Ptr::Ref toTime) + throw (std::invalid_argument) + = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Scheduler +} // namespace LiveSupport + +#endif // PlayLogInterface_h + diff --git a/livesupport/products/scheduler/src/PostgresqlPlayLog.cxx b/livesupport/products/scheduler/src/PostgresqlPlayLog.cxx new file mode 100644 index 000000000..1ad2b9d0e --- /dev/null +++ b/livesupport/products/scheduler/src/PostgresqlPlayLog.cxx @@ -0,0 +1,257 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlPlayLog.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include +#include + +#include "LiveSupport/Db/Conversion.h" +#include "PostgresqlPlayLog.h" + +using namespace odbc; + +using namespace LiveSupport::Core; +using namespace LiveSupport::Db; +using namespace LiveSupport::Scheduler; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * The name of the config element for this class + *----------------------------------------------------------------------------*/ +const std::string PostgresqlPlayLog::configElementNameStr = + "postgresqlPlayLog"; + +/*------------------------------------------------------------------------------ + * The SQL create statement, used for installation. + *----------------------------------------------------------------------------*/ +const std::string PostgresqlPlayLog::createStmt = + "CREATE TABLE playLog\n" + "(\n" + " id INT NOT NULL,\n" + " audioClipId INT NOT NULL,\n" + " timestamp TIMESTAMP NOT NULL,\n" + "\n" + " PRIMARY KEY(id)\n" + ");"; + +/*------------------------------------------------------------------------------ + * The SQL create statement, used for installation. + *----------------------------------------------------------------------------*/ +const std::string PostgresqlPlayLog::dropStmt = + "DROP TABLE playLog;"; + +/*------------------------------------------------------------------------------ + * The SQL statement for adding a play log entry. + * It's a simple insert. + *----------------------------------------------------------------------------*/ +const std::string PostgresqlPlayLog::addPlayLogEntryStmt = + "INSERT INTO playLog(id, audioClipId, timeStamp) VALUES(?, ?, ?)"; + +/*------------------------------------------------------------------------------ + * The SQL statement for querying scheduled entries for a time interval + * The parameters for this call are: from, to + * and returns the properties: audioClipId, timeStamp for all + * play log entries between from and to, ordered by timeStamp. + * TODO: the below query only lists entries starting inside [from:to[ + * but what about entries starting before, but flowing into [from:to[ ? + *----------------------------------------------------------------------------*/ +const std::string PostgresqlPlayLog::getPlayLogEntriesStmt = + "SELECT id, audioClipId, timeStamp FROM playLog WHERE " + "(? <= timeStamp) AND (timeStamp < ?) " + "ORDER BY timeStamp"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Configure the schedule. + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLog :: configure(const xmlpp::Element & element) + throw (std::invalid_argument, + std::logic_error) +{ + if (element.get_name() != configElementNameStr) { + std::string eMsg = "bad configuration element "; + eMsg += element.get_name(); + throw std::invalid_argument(eMsg); + } + + // nothing to do here, really +} + + +/*------------------------------------------------------------------------------ + * Install the PostgresqlPlayLog. + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLog :: install(void) throw (std::exception) +{ + Ptr::Ref conn; + try { + conn = cm->getConnection(); + Ptr::Ref stmt(conn->createStatement()); + stmt->execute(createStmt); + cm->returnConnection(conn); + } catch (std::exception &e) { + if (conn) { + cm->returnConnection(conn); + } + throw std::logic_error(e.what()); + } +} + + +/*------------------------------------------------------------------------------ + * Uninstall the PostgresqlPlayLog. + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLog :: uninstall(void) throw (std::exception) +{ + Ptr::Ref conn; + try { + conn = cm->getConnection(); + Ptr::Ref stmt(conn->createStatement()); + stmt->execute(dropStmt); + cm->returnConnection(conn); + } catch (std::exception &e) { + if (conn) { + cm->returnConnection(conn); + } + throw std::logic_error(e.what()); + } +} + + +/*------------------------------------------------------------------------------ + * Add a new play log entry + *----------------------------------------------------------------------------*/ +Ptr::Ref +PostgresqlPlayLog :: addPlayLogEntry( + Ptr::Ref audioClipId, + Ptr::Ref clipTimestamp) + throw (std::invalid_argument) +{ + Ptr::Ref conn; + bool result = false; + Ptr::Ref id; + + try { + conn = cm->getConnection(); + Ptr::Ref timestamp; + Ptr::Ref pstmt(conn->prepareStatement( + addPlayLogEntryStmt)); + id = UniqueId::generateId(); + pstmt->setInt(1, id->getId()); + + pstmt->setInt(2, audioClipId->getId()); + + timestamp = Conversion::ptimeToTimestamp(clipTimestamp); + pstmt->setTimestamp(3, *timestamp); + + result = (pstmt->executeUpdate() == 1); + + cm->returnConnection(conn); + } catch (std::exception &e) { + if (conn) { + cm->returnConnection(conn); + } + throw std::invalid_argument(e.what()); + } + + if (!result) { + throw std::invalid_argument("couldn't insert into database"); + } + + return id; +} + + +/*------------------------------------------------------------------------------ + * Get the play log entries for a given time interval + *----------------------------------------------------------------------------*/ +Ptr::Ref> >::Ref +PostgresqlPlayLog :: getPlayLogEntries( + Ptr::Ref fromTime, + Ptr::Ref toTime) + throw (std::invalid_argument) +{ + Ptr::Ref conn; + Ptr::Ref> >::Ref result( + new std::vector::Ref>()); + + try { + conn = cm->getConnection(); + Ptr::Ref timestamp; + Ptr::Ref pstmt(conn->prepareStatement( + getPlayLogEntriesStmt)); + timestamp = Conversion::ptimeToTimestamp(fromTime); + pstmt->setTimestamp(1, *timestamp); + timestamp = Conversion::ptimeToTimestamp(toTime); + pstmt->setTimestamp(2, *timestamp); + + Ptr::Ref rs(pstmt->executeQuery()); + while (rs->next()) { + Ptr::Ref id(new UniqueId(rs->getInt(1))); + Ptr::Ref audioClipId(new UniqueId(rs->getInt(2))); + + *timestamp = rs->getTimestamp(3); + Ptr::Ref clipTimestamp + = Conversion::timestampToPtime(timestamp); + + Ptr::Ref entry(new PlayLogEntry(id, + audioClipId, + clipTimestamp)); + result->push_back(entry); + } + + cm->returnConnection(conn); + } catch (std::exception &e) { + if (conn) { + cm->returnConnection(conn); + } + throw std::invalid_argument("couldn't get play log entries"); + } + + return result; +} + diff --git a/livesupport/products/scheduler/src/PostgresqlPlayLog.h b/livesupport/products/scheduler/src/PostgresqlPlayLog.h new file mode 100644 index 000000000..b7ee2dc27 --- /dev/null +++ b/livesupport/products/scheduler/src/PostgresqlPlayLog.h @@ -0,0 +1,236 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlPlayLog.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef PostresqlPlayLog_h +#define PostresqlPlayLog_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include + +#include "LiveSupport/Core/Ptr.h" +#include "LiveSupport/Core/Configurable.h" +#include "LiveSupport/Db/ConnectionManagerInterface.h" +#include "PlayLogInterface.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; +using namespace LiveSupport::Core; + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An object containing a log of the clips played in a PostreSQL database. + * + * This object has to be configured with a simple empty element, as + * the following: + * + *

+ *      <postgresqlPlayLog/>
+ *  
+ * + * The DTD for the above element is: + * + *

+ *  <!ELEMENT postgresqlPlayLog EMPTY >
+ *  
+ * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + */ +class PostgresqlPlayLog : public Configurable, + public PlayLogInterface +{ + private: + /** + * The name of the configuration XML elmenent used by this object. + */ + static const std::string configElementNameStr; + + /** + * The SQL create statement used in the installation step. + */ + static const std::string createStmt; + + /** + * The SQL drop statement used in the uninstallation step. + */ + static const std::string dropStmt; + + /** + * The SQL statement for adding a play log entry. + */ + static const std::string addPlayLogEntryStmt; + + /** + * The SQL statement for getting the play log for a time interval + */ + static const std::string getPlayLogEntriesStmt; + + /** + * The database connection manager to use for connecting the + * database. + */ + Ptr::Ref cm; + + /** + * The default constructor. + */ + PostgresqlPlayLog(void) throw() + { + } + + + public: + /** + * Construct a PostgresqlPlayLog. + * + * @param cm the connection manager the PostgresqlPlayLog will use to + * connect to the database. + */ + PostgresqlPlayLog(Ptr::Ref cm) + throw () + { + this->cm = cm; + } + + /** + * A virtual destructor, as this class has virtual functions. + */ + virtual + ~PostgresqlPlayLog(void) throw () + { + } + + /** + * Return the name of the XML element this object expects + * to be sent to a call to configure(). + * + * @return the name of the expected XML configuration element. + */ + static const std::string + getConfigElementName(void) throw () + { + return configElementNameStr; + } + + /** + * Configure the object based on the XML element supplied. + * The supplied element is expected to be of the name + * returned by configElementName(). + * + * @param element the XML element to configure the object from. + * @exception std::invalid_argument if the supplied XML element + * contains bad configuraiton information + * @exception std::logic_error if the object has already + * been configured, and can not be reconfigured. + */ + virtual void + configure(const xmlpp::Element & element) + throw (std::invalid_argument, + std::logic_error); + + /** + * Install the component. + * This step involves creating the environment in which the component + * will run. This may be creation of coniguration files, + * database tables, etc. + * + * @exception std::exception on installation problems. + */ + virtual void + install(void) throw (std::exception); + + /** + * Uninstall the component. + * Removes all the resources created in the install step. + * + * @exception std::exception on unistallation problems. + */ + virtual void + uninstall(void) throw (std::exception); + + /** + * Add a new entry to the play log. + * + * @param audioClipId the audio clip played. + * @param timeStamp the time the clip was played (started). + * @return the id of the newly created play log entry. + */ + virtual Ptr::Ref + addPlayLogEntry(Ptr::Ref audioClipId, + Ptr::Ref timeStamp) + throw (std::invalid_argument); + + /** + * Return the list of play log entries for a specified time interval. + * + * @param fromTime the start of the time of the interval queried, + * inclusive + * @param toTime to end of the time of the interval queried, + * non-inclusive + * @return a vector of the play log entries for the time region. + */ + virtual Ptr::Ref> >::Ref + getPlayLogEntries(Ptr::Ref fromTime, + Ptr::Ref toTime) + throw (std::invalid_argument); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Scheduler +} // namespace LiveSupport + +#endif // PostresqlPlayLog_h + diff --git a/livesupport/products/scheduler/src/PostgresqlPlayLogTest.cxx b/livesupport/products/scheduler/src/PostgresqlPlayLogTest.cxx new file mode 100644 index 000000000..bbaf7f0b5 --- /dev/null +++ b/livesupport/products/scheduler/src/PostgresqlPlayLogTest.cxx @@ -0,0 +1,200 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlPlayLogTest.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#if HAVE_UNISTD_H +#include +#else +#error "Need unistd.h" +#endif + + +#include +#include + +#include "LiveSupport/Db/ConnectionManagerFactory.h" +#include "PostgresqlPlayLog.h" +#include "PostgresqlPlayLogTest.h" + + +using namespace boost::posix_time; + +using namespace LiveSupport::Scheduler; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +CPPUNIT_TEST_SUITE_REGISTRATION(PostgresqlPlayLogTest); + +/** + * The name of the configuration file for the connection manager factory. + */ +static const std::string configFileName = "etc/connectionManagerFactory.xml"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Set up the test environment + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLogTest :: setUp(void) throw () +{ + try { + Ptr::Ref parser( + new xmlpp::DomParser(configFileName, true)); + const xmlpp::Document * document = parser->get_document(); + const xmlpp::Element * root = document->get_root_node(); + + Ptr::Ref cmf = + ConnectionManagerFactory::getInstance(); + cmf->configure(*root); + cm = cmf->getConnectionManager(); + + playLog.reset(new PostgresqlPlayLog(cm)); + playLog->install(); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL("semantic error in configuration file"); + } catch (xmlpp::exception &e) { + CPPUNIT_FAIL("error parsing configuration file"); + } +} + + +/*------------------------------------------------------------------------------ + * Clean up the test environment + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLogTest :: tearDown(void) throw () +{ + playLog->uninstall(); + playLog.reset(); + cm.reset(); +} + + +/*------------------------------------------------------------------------------ + * Add a single item to the play log. + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLogTest :: firstTest(void) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref audioClipId = UniqueId::generateId(); + Ptr::Ref timestamp(new ptime(time_from_string( + "2004-10-25 16:09:00"))); + + try { + playLog->addPlayLogEntry(audioClipId, timestamp); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } +} + + +/*------------------------------------------------------------------------------ + * See if getPlayLogEntries() returns correct lists + *----------------------------------------------------------------------------*/ +void +PostgresqlPlayLogTest :: getPlayLogEntriesTest(void) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref audioClipId; + Ptr::Ref timestamp; + Ptr::Ref fromTime; + Ptr::Ref toTime; + + Ptr::Ref> >::Ref entries; + Ptr::Ref entry; + + try { + audioClipId.reset(new UniqueId(10001)); + timestamp.reset(new ptime(time_from_string("2004-10-25 10:00:00"))); + playLog->addPlayLogEntry(audioClipId, timestamp); + + audioClipId.reset(new UniqueId(10002)); + timestamp.reset(new ptime(time_from_string("2004-10-25 10:12:00"))); + playLog->addPlayLogEntry(audioClipId, timestamp); + + audioClipId.reset(new UniqueId(10003)); + timestamp.reset(new ptime(time_from_string("2004-10-25 12:00:00"))); + playLog->addPlayLogEntry(audioClipId, timestamp); + + // first interval + fromTime.reset(new ptime(time_from_string("2004-10-25 10:00:00"))); + toTime.reset( new ptime(time_from_string("2004-10-25 12:00:00"))); + entries = playLog->getPlayLogEntries(fromTime, toTime); + + CPPUNIT_ASSERT(entries->size() == 2); + entry = (*entries)[0]; + CPPUNIT_ASSERT(entry->getAudioClipId()->getId() == 10001); + timestamp.reset(new ptime(time_from_string("2004-10-25 10:00:00"))); + CPPUNIT_ASSERT(*(entry->getTimestamp()) == *timestamp); + entry = (*entries)[1]; + CPPUNIT_ASSERT(entry->getAudioClipId()->getId() == 10002); + timestamp.reset(new ptime(time_from_string("2004-10-25 10:12:00"))); + CPPUNIT_ASSERT(*(entry->getTimestamp()) == *timestamp); + + // second interval + fromTime.reset(new ptime(time_from_string("2004-10-25 10:10:00"))); + toTime.reset( new ptime(time_from_string("2005-10-25 00:00:00"))); + entries = playLog->getPlayLogEntries(fromTime, toTime); + + CPPUNIT_ASSERT(entries->size() == 2); + entry = (*entries)[0]; + CPPUNIT_ASSERT(entry->getAudioClipId()->getId() == 10002); + timestamp.reset(new ptime(time_from_string("2004-10-25 10:12:00"))); + CPPUNIT_ASSERT(*(entry->getTimestamp()) == *timestamp); + entry = (*entries)[1]; + CPPUNIT_ASSERT(entry->getAudioClipId()->getId() == 10003); + timestamp.reset(new ptime(time_from_string("2004-10-25 12:00:00"))); + CPPUNIT_ASSERT(*(entry->getTimestamp()) == *timestamp); + + // third interval -- this one's empty + fromTime.reset(new ptime(time_from_string("2004-10-25 13:00:00"))); + toTime.reset( new ptime(time_from_string("2005-10-25 13:00:00"))); + entries = playLog->getPlayLogEntries(fromTime, toTime); + + CPPUNIT_ASSERT(entries->size() == 0); + + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } +} diff --git a/livesupport/products/scheduler/src/PostgresqlPlayLogTest.h b/livesupport/products/scheduler/src/PostgresqlPlayLogTest.h new file mode 100644 index 000000000..5c73e5a9a --- /dev/null +++ b/livesupport/products/scheduler/src/PostgresqlPlayLogTest.h @@ -0,0 +1,135 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + LiveSupport is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlPlayLogTest.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef PostgresqlPlayLogTest_h +#define PostgresqlPlayLogTest_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + +#include "LiveSupport/Db/ConnectionManagerInterface.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; +using namespace LiveSupport::Db; +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Unit test for the PostgresqlPlayLog class. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + * @see PostgresqlPlayLog + */ +class PostgresqlPlayLogTest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(PostgresqlPlayLogTest); + CPPUNIT_TEST(firstTest); + CPPUNIT_TEST(getPlayLogEntriesTest); + CPPUNIT_TEST_SUITE_END(); + + private: + + /** + * The connection manager used for testing. + */ + Ptr::Ref cm; + + /** + * The schedule used for testing. + */ + Ptr::Ref playLog; + + + protected: + + /** + * Add a single play log entry. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + firstTest(void) throw (CPPUNIT_NS::Exception); + + /** + * Add a few play log entries, then query time intervals around them. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + getPlayLogEntriesTest(void) throw (CPPUNIT_NS::Exception); + + + public: + + /** + * Set up the environment for the test case. + */ + void + setUp(void) throw (); + + /** + * Clean up the environment after the test case. + */ + void + tearDown(void) throw (); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Scheduler +} // namespace LiveSupport + +#endif // PostgresqlScheduleTest_h +