summaryrefslogtreecommitdiff
path: root/libodbcpp/param.cpp
blob: 91fc9e8549806e6fa7075e735bca0f6a1f99f312 (plain)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <sqlext.h>
#include "param.h"
#include "command.h"
#include "error.h"
#include <string.h>

ODBC::Param::Param() :
	paramCmd(NULL),
	paramIdx(0),
	paramBound(false)
{
}

ODBC::Param::Param(Command * c, unsigned int i) :
	paramCmd(c),
	paramIdx(i),
	paramBound(false)
{
}

ODBC::Param::~Param(){
}

template <class ParamType>
ParamType *
ODBC::Command::makeParam(unsigned int idx)
{
	if (idx >= params.size()) {
		throw Error("%s: Bind out of bounds", __FUNCTION__);
	}
	Param * & p = params[idx];
	if (p) {
		ParamType * np = dynamic_cast<ParamType *>(p);
		if (np) {
			return np;
		}
		delete p;
	}
	ParamType * np = new ParamType(this, idx);
	p = np;
	return np;
}

void
ODBC::Param::bind() const
{
	if (!paramBound) {
		RETCODE rc = SQLBindParameter(paramCmd->hStmt, paramIdx + 1, SQL_PARAM_INPUT, ctype(), stype(),
				size(), dp(), const_cast<void *>(dataAddress()), size(), &bindLen);
		if (!SQL_SUCCEEDED(rc)) {
			throw Error(rc, SQL_HANDLE_STMT, paramCmd->hStmt, "%s: Bind for parameter %u",
					__FUNCTION__, paramIdx);
		}
		paramBound = true;
	}
}

#define SIMPLEBINDER(ctype, otype, suf) \
void \
ODBC::Command::bindParam##suf(unsigned int i, ctype val) \
{ \
	ODBC::otype * p = makeParam<ODBC::otype>(i); \
	*p = val; \
	p->bind(); \
}
SIMPLEBINDER(int, SignedIntegerParam, I);
SIMPLEBINDER(long, SignedIntegerParam, I);
SIMPLEBINDER(long long, SignedIntegerParam, I);
SIMPLEBINDER(unsigned int, UnsignedIntegerParam, I);
SIMPLEBINDER(unsigned long int, UnsignedIntegerParam, I);
SIMPLEBINDER(unsigned long long int, UnsignedIntegerParam, I);

SIMPLEBINDER(double, FloatingPointParam, F);
SIMPLEBINDER(float, FloatingPointParam, F);

SIMPLEBINDER(const Glib::ustring &, GlibUstringParam, S);

SIMPLEBINDER(const struct tm *, TimeStampParam, T);
SIMPLEBINDER(const SQL_TIMESTAMP_STRUCT &, TimeStampParam, T);
SIMPLEBINDER(time_t, TimeStampParam, T);

void
ODBC::Command::bindNull(unsigned int i)
{
	makeParam<NullParam>(i)->bind();
}

void
ODBC::GlibUstringParam::operator=(Glib::ustring const & d)
{
	const char * addr = data.data();
	data = d;
	bindLen = d.bytes();
	paramBound &= (addr == data.data());
	if (!paramBound) {
		paramBound = false;
		bind();
	}
}

void
ODBC::TimeStampParam::operator=(long const & d)
{
	struct tm t;
	gmtime_r(&d, &t);
	data << t;
}