1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#ifndef DBCLIENT_H
#define DBCLIENT_H
#include <commonObjects.h>
#include <variableType.h>
#include <list>
#include <selectcommand.h>
#include <modifycommand.h>
#include <scopeObject.h>
#include <rdbmsDataSource.h>
#include <sqlVariableBinder.h>
#include <sqlHandleAsVariableType.h>
#include "p2Helpers.h"
class SqlMergeTask;
class DatabaseClient : public virtual CommonObjects {
public:
typedef boost::shared_ptr<DB::SelectCommand> SelectPtr;
typedef boost::shared_ptr<DB::ModifyCommand> ModifyPtr;
static void SqlMergeColumnsInserter(SqlMergeTask * merge, const std::string & name, bool key);
protected:
class TxHelper {
public:
TxHelper(const DatabaseClient *);
private:
ScopeObject so;
};
template <typename... Args>
ModifyPtr Modify(const std::string & sql, const Args & ... args) const
{
auto db = dataSource<RdbmsDataSource>("postgres");
auto cmd = ModifyPtr(db->getWritable().newModifyCommand(sql));
Bind(cmd.get(), 0, args...);
return cmd;
}
template <typename... Args>
SelectPtr Select(const std::string & sql, const Args & ... args) const
{
auto db = dataSource<RdbmsDataSource>("postgres");
auto cmd = SelectPtr(db->getReadonly().newSelectCommand(sql));
Bind(cmd.get(), 0, args...);
return cmd;
}
class NoRowsFoundException : public std::runtime_error {
public:
NoRowsFoundException();
};
template <typename Rtn, typename... Args>
Rtn SelectScalar(const std::string & sql, const Args & ... args) const
{
auto db = dataSource<RdbmsDataSource>("postgres");
auto cmd = SelectPtr(db->getReadonly().newSelectCommand(sql));
Bind(cmd.get(), 0, args...);
while (cmd->fetch()) {
HandleAsVariableType h;
(*cmd)[0].apply(h);
Rtn r;
h.variable >> r;
return r;
}
throw NoRowsFoundException();
}
private:
static void Bind(DB::Command *, unsigned int) { }
template <typename Arg>
static void Bind(DB::Command * cmd, unsigned int offset, const Arg & arg)
{
VariableType v;
v << arg;
boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset), v);
}
template <typename Arg, typename... Args>
static void Bind(DB::Command * cmd, unsigned int offset, const Arg & arg, const Args & ... args)
{
Bind(cmd, offset, arg);
Bind(cmd, offset + 1, args...);
}
friend class TxHelper;
typedef boost::function<void(DataSourcePtr)> DataSourceCall;
void onAllDatasources(const DataSourceCall &) const;
};
#endif
|