diff options
author | randomdan <randomdan@localhost> | 2011-02-09 01:33:33 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-02-09 01:33:33 +0000 |
commit | f8960d5c24db641cf43828e2cfc4546871657390 (patch) | |
tree | 423fc25eec8f35e9a2f0a37faf7a293454337059 | |
parent | Fix crash caused by taking reference of temp VariableType (diff) | |
download | project2-f8960d5c24db641cf43828e2cfc4546871657390.tar.bz2 project2-f8960d5c24db641cf43828e2cfc4546871657390.tar.xz project2-f8960d5c24db641cf43828e2cfc4546871657390.zip |
Fix the build system to do dependencies properly
Break down libodbcpp into a set of base classes; libdbpp
Add a native PostgreSQL implementation of libdbpp; libpqpp
Extend project2 rdbms stuff to work with generic connectors
Update datasources to specify connector type
Build libmisc as .so
-rw-r--r-- | project2/Jamfile.jam | 79 | ||||
-rw-r--r-- | project2/dumpTask.cpp | 4 | ||||
-rw-r--r-- | project2/rdbmsDataSource.cpp | 98 | ||||
-rw-r--r-- | project2/rdbmsDataSource.h | 42 | ||||
-rw-r--r-- | project2/sqlCheck.cpp | 72 | ||||
-rw-r--r-- | project2/sqlCheck.h | 4 | ||||
-rw-r--r-- | project2/sqlMergeTask.cpp | 48 | ||||
-rw-r--r-- | project2/sqlMergeTask.h | 2 | ||||
-rw-r--r-- | project2/sqlRows.cpp | 26 | ||||
-rw-r--r-- | project2/sqlRows.h | 12 | ||||
-rw-r--r-- | project2/sqlTask.cpp | 4 | ||||
-rw-r--r-- | project2/sqlTask.h | 4 | ||||
-rw-r--r-- | project2/sqlVariableBinder.cpp | 16 | ||||
-rw-r--r-- | project2/sqlVariableBinder.h | 6 | ||||
-rw-r--r-- | project2/tablepatch.cpp | 23 | ||||
-rw-r--r-- | project2/tablepatch.h | 2 |
16 files changed, 275 insertions, 167 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index d42e278..8f4ca6b 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -1,6 +1,11 @@ import package ; import feature : feature ; +alias glibmm : : : : + <cflags>"`pkg-config --cflags glibmm-2.4`" + <linkflags>"`pkg-config --libs glibmm-2.4`" + ; + alias libxmlpp : : : : <cflags>"`pkg-config --cflags libxml++-2.6`" <linkflags>"`pkg-config --libs libxml++-2.6`" ; @@ -10,7 +15,6 @@ alias libxslt : : : : lib fcgi : : <name>fcgi ; lib fcgi++ : : <name>fcgi++ ; -lib odbc : : <name>odbc ; lib boost_regex : : <name>boost_regex ; lib boost_filesystem : : <name>boost_filesystem ; lib boost_date_time : : <name>boost_date_time ; @@ -19,6 +23,17 @@ lib esmtp : : <name>esmtp ; lib curl : : <name>curl ; lib osspuuid : : <name>ossp-uuid++ ; +alias p2parts : : : : + <library>p2common + <library>p2url + <library>p2files + <library>p2processes + <library>p2sql + <library>p2mail + <library>p2regex + <library>p2xml + ; + feature uuid : boost ossp : propagated ; lib p2uuid : @@ -78,17 +93,21 @@ lib p2xmlSession : : <library>../libmisc//misc <library>libxmlpp - <library>p2uuid <uuid>ossp:<define>OSSP_UUID + : : + <library>p2uuid ; lib p2sql : [ glob sql*.cpp tablepatch.cpp rdbmsDataSource.cpp ] + ../libdbpp//dbpp + ../libodbcpp//odbcpp + ../libpqpp//pqpp : - <library>../libmisc//misc - <library>../libodbcpp//odbcpp <library>libxmlpp - <library>odbc + : : + <library>../libodbcpp//odbcpp + <library>../libpqpp//pqpp ; lib p2url : @@ -109,54 +128,38 @@ lib p2mail : ; lib p2web : - [ glob cgi/cgi*.cpp ] : - <library>p2common + [ glob cgi/cgi*.cpp ] + : + <library>../libmisc//misc <library>cgicc + <library>glibmm + <library>libxmlpp <uuid>ossp:<define>OSSP_UUID + : : + <library>p2parts + <library>p2xmlSession ; exe p2cgi : - cgi/p2webCgi.cpp : + cgi/p2webCgi.cpp + : <library>p2web - <library>p2url - <library>p2sql - <library>p2mail - <library>p2files - <library>p2regex - <library>p2processes - <library>p2xml - <library>p2xmlSession - <library>p2uuid <uuid>ossp:<define>OSSP_UUID ; exe p2fcgi : - cgi/p2webFCgi.cpp cgi/FCgiIO.cpp : + cgi/p2webFCgi.cpp cgi/FCgiIO.cpp + fcgi++ + fcgi + : <library>p2web - <library>fcgi++ - <library>fcgi - <library>p2url - <library>p2sql - <library>p2mail - <library>p2files - <library>p2regex - <library>p2processes - <library>p2xml - <library>p2xmlSession - <library>p2uuid <uuid>ossp:<define>OSSP_UUID ; exe p2console : - [ glob console/*.cpp ] : - <library>p2common - <library>p2url - <library>p2files - <library>p2processes - <library>p2sql - <library>p2mail - <library>p2regex - <library>p2xml + [ glob console/*.cpp ] + : + <library>p2parts ; explicit install ; diff --git a/project2/dumpTask.cpp b/project2/dumpTask.cpp index 5dfeba6..cdf8c1b 100644 --- a/project2/dumpTask.cpp +++ b/project2/dumpTask.cpp @@ -55,10 +55,10 @@ class Printer : public boost::static_visitor<> { fprintf(stderr, "%g", i); } void operator()(const Glib::ustring & i) const { - fprintf(stderr, "'%s'", i.c_str()); + fprintf(stderr, "'%.*s'", i.length(), i.c_str()); } void operator()(const boost::shared_ptr<const Glib::ustring> & i) const { - fprintf(stderr, "'%s'", i->c_str()); + fprintf(stderr, "'%.*s'", i->length(), i->c_str()); } void operator()(const boost::posix_time::ptime & i) const { fprintf(stderr, "[%s]", boost::posix_time::to_iso_extended_string(i).c_str()); diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp index e79b841..98e2d5a 100644 --- a/project2/rdbmsDataSource.cpp +++ b/project2/rdbmsDataSource.cpp @@ -6,6 +6,11 @@ #include <errno.h> #include <sqlext.h> +#include "../libpqpp/connection.h" +#include "../libodbcpp/connection.h" + +class UnknownConnectionProvider : public std::exception { }; + class RdbmsDataSourceLoader : public ElementLoaderImpl<RdbmsDataSource> { public: RdbmsDataSourceLoader() : ElementLoaderImpl<RdbmsDataSource>("rdbmsdatasource") @@ -41,13 +46,13 @@ RdbmsDataSource::DSNSet RdbmsDataSource::changedDSNs; RdbmsDataSource::RdbmsDataSource(const xmlpp::Element * p) : SourceObject(p), DataSource(p), - masterDsn(xmlChildText(p, "masterdsn")), + masterDsn(dynamic_cast<const xmlpp::Element *>(p->find("masterdsn").front())), preferLocal(p->get_attribute_value("preferlocal") != "false") { BOOST_FOREACH(const xmlpp::Node * node, p->find("readonly/dsn")) { const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); if (elem) { - roDSNs[elem->get_attribute_value("host")] = elem->get_child_text()->get_content(); + roDSNs.insert(ReadonlyDSNs::value_type(elem->get_attribute_value("host"), p)); } } } @@ -61,22 +66,22 @@ RdbmsDataSource::loadComplete(const CommonObjects *) { } -ODBC::Connection & +const DB::Connection & RdbmsDataSource::getWritable() const { ConnectionPtr master = connectTo(masterDsn); - if (!master->inTx()) { - master->beginTx(); + if (!master->connection->inTx()) { + master->connection->beginTx(); } changedDSNs.insert(name); - return *master; + return *master->connection; } -ODBC::Connection & +const DB::Connection & RdbmsDataSource::getReadonly() const { if (changedDSNs.find(name) != changedDSNs.end()) { - return *connectTo(masterDsn); + return *connectTo(masterDsn)->connection; } if (localhost.length() == 0 && preferLocal) { struct utsname name; @@ -93,11 +98,11 @@ RdbmsDataSource::getReadonly() const ReadonlyDSNs::const_iterator ro = roDSNs.find(localhost); try { if (ro == roDSNs.end()) { - syslog(LOG_WARNING, "%s: No database host makes local host name (%s) Will use master DSN", + syslog(LOG_WARNING, "%s: No database host matches local host name (%s) Will use master DSN", __FUNCTION__, localhost.c_str()); - return *connectTo(masterDsn); + return *connectTo(masterDsn)->connection; } - return *connectTo(ro->second); + return *connectTo(ro->second)->connection; } catch (...) { // Failed to connect to a preferred DB... carry on and try the others... @@ -105,20 +110,20 @@ RdbmsDataSource::getReadonly() const } BOOST_FOREACH(ReadonlyDSNs::value_type db, roDSNs) { try { - return *connectTo(db.second); + return *connectTo(db.second)->connection; } catch (...) { } } - return *connectTo(masterDsn); + return *connectTo(masterDsn)->connection; } void RdbmsDataSource::commit() { DBHosts::const_iterator m = dbhosts.find(masterDsn); - if (m != dbhosts.end() && m->second->inTx()) { - m->second->commitTx(); + if (m != dbhosts.end() && m->second->connection->inTx()) { + m->second->connection->commitTx(); } } @@ -126,14 +131,14 @@ void RdbmsDataSource::rollback() { DBHosts::const_iterator m = dbhosts.find(masterDsn); - if (m != dbhosts.end() && m->second->inTx()) { - m->second->rollbackTx(); + if (m != dbhosts.end() && m->second->connection->inTx()) { + m->second->connection->rollbackTx(); } changedDSNs.erase(name); } RdbmsDataSource::ConnectionPtr -RdbmsDataSource::connectTo(const std::string & dsn) +RdbmsDataSource::connectTo(const ConnectionInfo & dsn) { FailedHosts::iterator dbf = failedhosts.find(dsn); if (dbf != failedhosts.end()) { @@ -147,11 +152,9 @@ RdbmsDataSource::connectTo(const std::string & dsn) DBHosts::const_iterator dbi = dbhosts.find(dsn); if (dbi != dbhosts.end()) { try { - SQLINTEGER dead = dbi->second->getAttrInt(SQL_ATTR_CONNECTION_DEAD); - if (dead == SQL_CD_FALSE) { - dbi->second->touch(); - return dbi->second; - } + dbi->second->connection->ping(); + dbi->second->touch(); + return dbi->second; } catch (...) { // Connection in failed state @@ -160,24 +163,29 @@ RdbmsDataSource::connectTo(const std::string & dsn) } try { - ConnectionPtr db = ConnectionPtr(new RdbmsConnection(dsn, 300)); + ConnectionPtr db = ConnectionPtr(new RdbmsConnection(dsn.connect(), 300)); dbhosts[dsn] = db; db->touch(); return db; } - catch (const ODBC::ConnectionError & e) { + catch (const DB::ConnectionError & e) { failedhosts.insert(FailedHosts::value_type(dsn, e)); throw; } } -RdbmsDataSource::RdbmsConnection::RdbmsConnection(const std::string & dsn, time_t kat) : - ODBC::Connection(dsn), +RdbmsDataSource::RdbmsConnection::RdbmsConnection(const DB::Connection * con, time_t kat) : + connection(con), lastUsedTime(0), keepAliveTime(kat) { } +RdbmsDataSource::RdbmsConnection::~RdbmsConnection() +{ + delete connection; +} + void RdbmsDataSource::RdbmsConnection::touch() const { @@ -190,3 +198,39 @@ RdbmsDataSource::RdbmsConnection::isExpired() const return (time(NULL) > lastUsedTime + keepAliveTime); } +RdbmsDataSource::ConnectionInfo::ConnectionInfo(const xmlpp::Element * n) +{ + BOOST_FOREACH(const xmlpp::Node * node, n->find("odbc")) { + type = "ODBC"; + dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content(); + } + BOOST_FOREACH(const xmlpp::Node * node, n->find("postgresql")) { + type = "PQ"; + dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content(); + } +} + +DB::Connection * +RdbmsDataSource::ConnectionInfo::connect() const +{ + if (type == "ODBC") { + return new ODBC::Connection(dsn); + } + if (type == "PQ") { + return new PQ::Connection(dsn); + } + throw UnknownConnectionProvider(); +} + +bool +RdbmsDataSource::ConnectionInfo::operator<(const RdbmsDataSource::ConnectionInfo & other) const +{ + if (type < other.type) { + return true; + } + if (type == other.type && dsn < other.dsn) { + return true; + } + return false; +} + diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h index ad97624..84c6d03 100644 --- a/project2/rdbmsDataSource.h +++ b/project2/rdbmsDataSource.h @@ -5,35 +5,57 @@ #include <boost/shared_ptr.hpp> #include <map> #include "dataSource.h" -#include "connection.h" +#include "../libdbpp/connection.h" +#include "../libdbpp/error.h" class RdbmsDataSource : public DataSource { public: - class RdbmsConnection : public ODBC::Connection { + class RdbmsConnection { public: - RdbmsConnection(const std::string & dsn, time_t keepAliveTime); + RdbmsConnection(const DB::Connection * connection, time_t kat); + ~RdbmsConnection(); + void touch() const; bool isExpired() const; + const DB::Connection * const connection; + private: mutable time_t lastUsedTime; const time_t keepAliveTime; }; + + class ConnectionInfo { + public: + ConnectionInfo(const xmlpp::Element *); + + DB::Connection * connect() const; + + bool operator<(const ConnectionInfo & o) const; + + private: + std::string dsn; + std::string type; + }; + typedef boost::shared_ptr<RdbmsConnection> ConnectionPtr; - typedef std::map<std::string, std::string> ReadonlyDSNs; // Map hostname to DSN string - typedef std::map<std::string, ConnectionPtr> DBHosts; // Map DSN strings to connections - typedef std::map<std::string, const ODBC::ConnectionError> FailedHosts; // Map DSN strings to failures + typedef std::map<std::string, ConnectionInfo> ReadonlyDSNs; // Map hostname to DSN string + typedef std::map<ConnectionInfo, ConnectionPtr> DBHosts; // Map DSN strings to connections + typedef std::map<ConnectionInfo, const DB::ConnectionError> FailedHosts; // Map DSN strings to failures + RdbmsDataSource(const xmlpp::Element * p); ~RdbmsDataSource(); - ODBC::Connection & getReadonly() const; - ODBC::Connection & getWritable() const; + + const DB::Connection & getReadonly() const; + const DB::Connection & getWritable() const; virtual void loadComplete(const CommonObjects *); virtual void commit(); virtual void rollback(); - const std::string masterDsn; + + const ConnectionInfo masterDsn; const bool preferLocal; protected: - static ConnectionPtr connectTo(const std::string & dsn); + static ConnectionPtr connectTo(const ConnectionInfo & dsn); ReadonlyDSNs roDSNs; private: diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp index 9a5bb94..fc8f4bc 100644 --- a/project2/sqlCheck.cpp +++ b/project2/sqlCheck.cpp @@ -30,38 +30,64 @@ SqlCheck::~SqlCheck() void SqlCheck::loadComplete(const CommonObjects * co) { - query = new ODBC::SelectCommand(LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( - &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getReadonly(), sql); + query = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( + &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getReadonly().newSelectCommand(sql); } +class HandleDoCompare : public DB::HandleField { + public: + HandleDoCompare(double tV, const std::string & tO) : + retVal(false), + testValue(tV), + testOp(tO) { + } + void null() { + } + void string(const char * c, size_t l) { + } + void integer(int64_t i) { + floatingpoint(i); + } + void floatingpoint(double val) { + if ((testOp == "==" || testOp == "=") && val == testValue) { + retVal = true; + } + else if (testOp == "<" && val < testValue) { + retVal = true; + } + else if (testOp == ">" && val > testValue) { + retVal = true; + } + else if (testOp == "!=" && val != testValue) { + retVal = true; + } + else if ((testOp == "<=" || testOp == "=<") && val <= testValue) { + retVal = true; + } + else if ((testOp == ">=" || testOp == "=>") && val >= testValue) { + retVal = true; + } + } + void timestamp(const struct tm & t) { + } + bool operator()() const { + return retVal; + } + private: + bool retVal; + double testValue; + std::string testOp; +}; bool SqlCheck::performCheck() const { BOOST_FOREACH(Parameters::value_type p, parameters) { boost::apply_visitor<const OdbcVariableBinder, const VariableType>(OdbcVariableBinder(query, atoi(p.second->name.c_str())), p.second->value); } - bool retVal = false; + HandleDoCompare h(testValue, testOp); while (query->fetch()) { - int val = (*query)[0]; - if ((testOp == "==" || testOp == "=") && val == testValue) { - retVal = true; - } - else if (testOp == "<" && val < testValue) { - retVal = true; - } - else if (testOp == ">" && val > testValue) { - retVal = true; - } - else if (testOp == "!=" && val != testValue) { - retVal = true; - } - else if ((testOp == "<=" || testOp == "=<") && val <= testValue) { - retVal = true; - } - else if ((testOp == ">=" || testOp == "=>") && val >= testValue) { - retVal = true; - } + (*query)[0].apply(h); } - return retVal; + return h(); } diff --git a/project2/sqlCheck.h b/project2/sqlCheck.h index bfc7b37..50132c1 100644 --- a/project2/sqlCheck.h +++ b/project2/sqlCheck.h @@ -4,7 +4,7 @@ #include "paramChecker.h" #include "iHaveParameters.h" -namespace ODBC { class SelectCommand; } +namespace DB { class SelectCommand; } class SqlCheck : public IHaveParameters, public ParamChecker { public: @@ -19,7 +19,7 @@ class SqlCheck : public IHaveParameters, public ParamChecker { const std::string testOp; const double testValue; private: - ODBC::SelectCommand * query; + DB::SelectCommand * query; }; #endif diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 6a5ebf7..f707a77 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -136,22 +136,28 @@ void SqlMergeTask::createTempTable() const { if (useView) { - ModifyCommand(*destdb, stringf( + ModifyCommand * cv = destdb->newModifyCommand(stringf( "CREATE VIEW %s AS %s", dtablet.c_str(), - boost::algorithm::join(sqls, " UNION ").c_str())).execute(); + boost::algorithm::join(sqls, " UNION ").c_str())); + cv->execute(); + delete cv; } else { - ModifyCommand(*destdb, stringf( + ModifyCommand * ctt = destdb->newModifyCommand(stringf( "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s WHERE 0=1", dtablet.c_str(), - dtable.c_str())).execute(); + dtable.c_str())); + ctt->execute(); + delete ctt; BOOST_FOREACH(Columns::value_type c, cols) { if (!c->maptable.empty()) { - ModifyCommand(*destdb, stringf( + ModifyCommand * at = destdb->newModifyCommand(stringf( "ALTER TABLE %s ADD COLUMN %s VARCHAR(1000)", dtablet.c_str(), - c->mapcolumn.c_str())).execute(); + c->mapcolumn.c_str())); + at->execute(); + delete at; } } } @@ -161,12 +167,15 @@ void SqlMergeTask::dropTempTable() const { if (tempTableCreated) { + ModifyCommand * d; if (useView) { - ModifyCommand(*destdb, "DROP VIEW " + dtablet).execute(); + d = destdb->newModifyCommand("DROP VIEW " + dtablet); } else { - ModifyCommand(*destdb, "DROP TABLE " + dtablet).execute(); + d = destdb->newModifyCommand("DROP TABLE " + dtablet); } + d->execute(); + delete d; } } void @@ -178,13 +187,17 @@ SqlMergeTask::createTempKey() const idx.appendf("ALTER TABLE %s ADD CONSTRAINT pk_%s PRIMARY KEY(%s)", dtablet.c_str(), dtablet.c_str(), boost::algorithm::join(keys, ", ").c_str()); - ModifyCommand(*destdb, idx).execute(); + ModifyCommand * at = destdb->newModifyCommand(idx); + at->execute(); + delete at; /* Indexes */ int n = 0; BOOST_FOREACH(const Keys::value_type & i, indexes) { - ModifyCommand(*destdb, stringf( + ModifyCommand * ci = destdb->newModifyCommand(stringf( "CREATE INDEX idx_%s_%d ON %s(%s)", - dtablet.c_str(), n, dtablet.c_str(), i.c_str())).execute(); + dtablet.c_str(), n, dtablet.c_str(), i.c_str())); + ci->execute(); + delete ci; n += 1; } } @@ -209,7 +222,7 @@ SqlMergeTask::insertCommand() const } } ins.append(")"); - return new ModifyCommand(*destdb, ins); + return destdb->newModifyCommand(ins); } class Populate : public NoOutputExecute { @@ -306,11 +319,14 @@ SqlMergeTask::copyToTempTable() const ins.append((*c)->column); } ins.appendf(" FROM (%s) tmp_src", sql.c_str()); - ModifyCommand(*destdb, ins).execute(); + ModifyCommand * cttt = destdb->newModifyCommand(ins); + cttt->execute(); + delete cttt; } BOOST_FOREACH(Columns::value_type c, cols) { if (!c->maptable.empty()) { - ModifyCommand(*destdb, stringf( + ModifyCommand * utt = destdb->newModifyCommand( + stringf( "UPDATE %s d SET %s = (SELECT m.%s FROM %s m WHERE m.%s = d.%s) WHERE %s IS NULL", dtablet.c_str(), c->column.c_str(), @@ -318,7 +334,9 @@ SqlMergeTask::copyToTempTable() const c->maptable.c_str(), c->mapcolumn.c_str(), c->mapcolumn.c_str(), - c->column.c_str())).execute(); + c->column.c_str())); + utt->execute(); + delete utt; } } } diff --git a/project2/sqlMergeTask.h b/project2/sqlMergeTask.h index c7a7e4e..85a6b4e 100644 --- a/project2/sqlMergeTask.h +++ b/project2/sqlMergeTask.h @@ -64,7 +64,7 @@ class SqlMergeTask : public Task { ModifyCommand * insCmd; public: - ODBC::Connection * destdb; + const DB::Connection * destdb; const Variable dataSource; const Table dtable; const Table dtablet; diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp index f592337..94f9fc1 100644 --- a/project2/sqlRows.cpp +++ b/project2/sqlRows.cpp @@ -43,23 +43,21 @@ SqlRows::setFilter(const Glib::ustring & name) } } -class HandleAsVariableType : public ODBC::HandleField { +class HandleAsVariableType : public DB::HandleField { public: void null() { } - void string(const std::vector<char> & c, size_t l) { - variable = boost::shared_ptr<Glib::ustring>(new Glib::ustring(&c[0], &c[l])); + void string(const char * c, size_t l) { + variable = boost::shared_ptr<Glib::ustring>(new Glib::ustring(c, c + l)); } - void integer(SQLINTEGER i) { + void integer(int64_t i) { variable = i; } - void floatingpoint(SQLDOUBLE d) { + void floatingpoint(double d) { variable = d; } - void timestamp(const SQL_TIMESTAMP_STRUCT & t) + void timestamp(const struct tm & t) { - variable = boost::shared_ptr<boost::posix_time::ptime>(new boost::posix_time::ptime( - boost::gregorian::date(t.year, t.month, t.day), - boost::posix_time::time_duration(t.hour, t.minute, t.second, t.fraction))); + variable = boost::shared_ptr<boost::posix_time::ptime>(new boost::posix_time::ptime(boost::posix_time::ptime_from_tm(t))); } VariableType variable; }; @@ -111,7 +109,7 @@ SqlRows::execute(const RowProcessor * rp) const unsigned int offset = 0; Glib::ustring sql; sqlCommand.writeSql(sql); - query = new ODBC::SelectCommand(db->getReadonly(), sql); + query = db->getReadonly().newSelectCommand(sql); sqlCommand.bindParams(rp, query, offset); while (query->fetch()) { rp->rowReady(); @@ -158,7 +156,7 @@ SqlRows::SqlCommand::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlCommand::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlCommand::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const { BOOST_FOREACH(const SqlWriterPtr & w, writers) { w->bindParams(rp, cmd, offset); @@ -194,7 +192,7 @@ SqlRows::SqlFilter::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlFilter::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlFilter::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const { if (active) { BOOST_FOREACH(const SqlWriterPtr & w, writers) { @@ -215,7 +213,7 @@ SqlRows::SqlParameter::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlParameter::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlParameter::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const { boost::apply_visitor<const OdbcVariableBinder, const VariableType>(OdbcVariableBinder(cmd, offset++), rp->getParameter(name)); } @@ -232,7 +230,7 @@ SqlRows::SqlText::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlText::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlText::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const { } diff --git a/project2/sqlRows.h b/project2/sqlRows.h index 942da5d..a1f4fab 100644 --- a/project2/sqlRows.h +++ b/project2/sqlRows.h @@ -36,13 +36,13 @@ class SqlRows : public RowSet { SqlWriter(); virtual ~SqlWriter(); virtual void writeSql(Glib::ustring & sql) const = 0; - virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const = 0; + virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const = 0; }; class SqlText : public SqlWriter { public: SqlText(const xmlpp::TextNode *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; const Glib::ustring text; }; @@ -50,7 +50,7 @@ class SqlRows : public RowSet { public: SqlParameter(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; const Glib::ustring name; }; @@ -58,7 +58,7 @@ class SqlRows : public RowSet { public: SqlFilter(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; const Glib::ustring name; bool active; @@ -70,7 +70,7 @@ class SqlRows : public RowSet { public: SqlCommand(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters; typedef std::pair<Filters::const_iterator, Filters::const_iterator> FiltersRangeType; Filters filters; @@ -78,7 +78,7 @@ class SqlRows : public RowSet { Writers writers; }; SqlCommand sqlCommand; - mutable ODBC::SelectCommand * query; + mutable DB::SelectCommand * query; const RdbmsDataSource * db; }; diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp index 3c54660..341dbb9 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -27,8 +27,8 @@ SqlTask::~SqlTask() void SqlTask::loadComplete(const CommonObjects * co) { - modify = new ODBC::ModifyCommand(LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( - &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable(), sql); + modify = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( + &CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable().newModifyCommand(sql); } void diff --git a/project2/sqlTask.h b/project2/sqlTask.h index 6432022..4805307 100644 --- a/project2/sqlTask.h +++ b/project2/sqlTask.h @@ -7,7 +7,7 @@ #include "task.h" #include "iHaveParameters.h" -namespace ODBC { class ModifyCommand; } +namespace DB { class ModifyCommand; } class SqlTask : public Task, public IHaveParameters { public: @@ -19,7 +19,7 @@ class SqlTask : public Task, public IHaveParameters { const Variable dataSource; const std::string sql; protected: - mutable ODBC::ModifyCommand * modify; + mutable DB::ModifyCommand * modify; }; #endif diff --git a/project2/sqlVariableBinder.cpp b/project2/sqlVariableBinder.cpp index 13912f3..bc5b235 100644 --- a/project2/sqlVariableBinder.cpp +++ b/project2/sqlVariableBinder.cpp @@ -1,8 +1,8 @@ #include "sqlVariableBinder.h" #include "command.h" -#include <boost/date_time/posix_time/posix_time_duration.hpp> +#include <boost/date_time/posix_time/conversion.hpp> -OdbcVariableBinder::OdbcVariableBinder(ODBC::Command * c, unsigned int i) : +OdbcVariableBinder::OdbcVariableBinder(DB::Command * c, unsigned int i) : cmd(c), idx(i) { @@ -71,16 +71,8 @@ OdbcVariableBinder::operator()(const float & i) const void OdbcVariableBinder::operator()(const boost::posix_time::ptime & i) const { - SQL_TIMESTAMP_STRUCT t; - boost::gregorian::date::ymd_type ymd(i.date().year_month_day()); - t.year = ymd.year; - t.month = ymd.month; - t.day = ymd.day; - t.hour = i.time_of_day().hours(); - t.minute = i.time_of_day().minutes(); - t.second = i.time_of_day().seconds(); - t.fraction = i.time_of_day().fractional_seconds(); - cmd->bindParamT(idx, t); + struct tm tm(boost::posix_time::to_tm(i)); + cmd->bindParamT(idx, &tm); } void OdbcVariableBinder::operator()(const boost::shared_ptr<const boost::posix_time::ptime> & i) const diff --git a/project2/sqlVariableBinder.h b/project2/sqlVariableBinder.h index f175be1..5a75f07 100644 --- a/project2/sqlVariableBinder.h +++ b/project2/sqlVariableBinder.h @@ -6,12 +6,12 @@ #include <boost/date_time/posix_time/ptime.hpp> #include <glibmm/ustring.h> -namespace ODBC { +namespace DB { class Command; } class OdbcVariableBinder : public boost::static_visitor<> { public: - OdbcVariableBinder(ODBC::Command * c, unsigned int i); + OdbcVariableBinder(DB::Command * c, unsigned int i); void operator()(const Glib::ustring & i) const; void operator()(const boost::shared_ptr<const Glib::ustring> & i) const; void operator()(const long long unsigned int & i) const; @@ -28,7 +28,7 @@ class OdbcVariableBinder : public boost::static_visitor<> { void operator()(const boost::shared_ptr<const boost::posix_time::ptime> & i) const; private: - ODBC::Command * cmd; + DB::Command * cmd; unsigned int idx; }; diff --git a/project2/tablepatch.cpp b/project2/tablepatch.cpp index ddf7e03..8acc8da 100644 --- a/project2/tablepatch.cpp +++ b/project2/tablepatch.cpp @@ -95,8 +95,9 @@ TablePatch::doDeletes(const char * where, const char * order) toDelSql.appendf(" ORDER BY %s", order); } toDelSql.append(")"); - ModifyCommand del(db, toDelSql); - del.execute(); + ModifyCommand * del = db.newModifyCommand(toDelSql); + del->execute(); + delete del; } void @@ -186,16 +187,18 @@ TablePatch::doUpdates(const char * where, const char * order) // ----------------------------------------------------------------- // Iterator over update list make changes -------------------------- // ----------------------------------------------------------------- - SelectCommand toUpd(db, toUpdSel); - ModifyCommand upd(db, updSql); + SelectCommand * toUpd = db.newSelectCommand(toUpdSel); + ModifyCommand * upd = db.newModifyCommand(updSql); int cs = cols.size(); - toUpd.execute(); + toUpd->execute(); for (int c = 0; c < cs; c += 1) { - toUpd[c].rebind(&upd, c); + (*toUpd)[c].rebind(upd, c); } - while (toUpd.fetch()) { - upd.execute(false); + while (toUpd->fetch()) { + upd->execute(false); } + delete toUpd; + delete upd; } void @@ -250,7 +253,9 @@ TablePatch::doInserts(const char * order) if (order && *order) { toInsSql.appendf(" ORDER BY %s", order); } - ModifyCommand(db, toInsSql).execute(); + ModifyCommand * ins = db.newModifyCommand(toInsSql); + ins->execute(); + delete ins; } const char * diff --git a/project2/tablepatch.h b/project2/tablepatch.h index 118e379..7352635 100644 --- a/project2/tablepatch.h +++ b/project2/tablepatch.h @@ -8,7 +8,7 @@ #include <modifycommand.h> #include <selectcommand.h> -using namespace ODBC; +using namespace DB; class TablePatch { public: |