This repository has been archived by the owner on Jun 12, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Client.cpp
161 lines (146 loc) · 4.88 KB
/
Client.cpp
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*!
* \brief The file contains OLE DB client implementation
* \author \verbatim
Created by: Alexander Egorov
\endverbatim
* \date \verbatim
Creation date: 2010-04-11
\endverbatim
* Copyright 2008-2012 Alexander Egorov <egoroff@gmail.com> (http://www.egoroff.spb.ru)
*/
#include "StdAfx.h"
#include "Client.h"
inline void Client::InitializeAndEstablishConnection()
{
CDBPropSet dbinit(DBPROPSET_DBINIT);
bool result = dbinit.AddProperty(
DBPROP_INIT_PROVIDERSTRING,
connectionString_);
if (!result) {
throw std::exception("Failed to initialize connection");
}
HRESULT r = ds_.Open(CLSID_SQLNCLI, &dbinit);
ThrowIfError(r, ds_.m_spInit, IID_IDBInitialize);
session_.Open(ds_);
}
Client::Client(const CStringW& connectionString)
: connectionString_(connectionString)
{
InitializeAndEstablishConnection();
}
Client::~Client()
{
session_.Close();
ds_.Close();
}
void Client::ThrowIfError(
HRESULT result,
const CCommand<CNoAccessor>& cmd) const
{
ThrowIfError(result, cmd.m_spCommand, IID_ICommand);
}
void Client::ThrowIfError(
HRESULT result,
const CCommand<CManualAccessor>& cmd) const
{
ThrowIfError(result, cmd.m_spCommand, IID_ICommand);
}
void Client::ThrowIfError(
HRESULT result,
const CCommand<CDynamicStringAccessorW>& cmd) const
{
ThrowIfError(result, cmd.m_spCommand, IID_ICommand);
}
long Client::ExecuteNonQuery(LPCWSTR pStatement)
{
CCommand<CNoAccessor> cmd;
cmd.CreateCommand(session_);
DBROWCOUNT affected;
HRESULT result = cmd.Open(
session_,
pStatement,
0,
&affected,
DBGUID_DEFAULT,
false);
ThrowIfError(result, cmd);
return affected;
};
void Client::ExecuteReader(
LPCWSTR pStatement,
CCommand<CManualAccessor>* pCmd,
const std::map<CStringW,
CStringW>& rParameters)
{
HRESULT result = NULL;
pCmd->Create(session_, pStatement);
pCmd->Prepare();
std::map<CStringW, CStringW>::const_iterator it;
result = pCmd->CreateParameterAccessor(
rParameters.size(),
reinterpret_cast<void*>(0x01),
0);
ThrowIfError(result, *pCmd);
for (it = rParameters.begin(); it != rParameters.end(); ++it) {
size_t ix = _wtoi(it->first);
if ((ix <= 0) || (ix > rParameters.size())) {
throw std::exception("bad bind parameter key");
}
pCmd->AddParameterEntry(
ix,
DBTYPE_WSTR,
it->second.GetLength(),
(void*)it->second.GetString());
}
DBROWCOUNT affected;
result = pCmd->Open(NULL, &affected, true);
ThrowIfError(result, *pCmd);
};
void Client::ExecuteReader(
LPCWSTR pStatement,
CCommand<CDynamicStringAccessorW>* pCmd)
{
DBROWCOUNT affected;
HRESULT result = pCmd->Open(session_, pStatement, 0, &affected);
ThrowIfError(result, *pCmd);
};
DBLENGTH Client::CalculateStringLength(DBTYPE type, DBLENGTH size)
{
switch (type) {
case DBTYPE_BOOL : return 2;
case DBTYPE_BYTES : return size * 2;
case DBTYPE_BSTR : return size;
case DBTYPE_STR : return size;
case DBTYPE_WSTR : return size;
case DBTYPE_I1 : return 5;
case DBTYPE_I2 : return 7;
case DBTYPE_I4 : return 12;
case DBTYPE_I8 : return 22;
case DBTYPE_UI1 : return 4;
case DBTYPE_UI2 : return 6;
case DBTYPE_UI4 : return 11;
case DBTYPE_UI8 : return 21;
case DBTYPE_R4 : return 13;
case DBTYPE_R8 : return 23; // maybe 9
case DBTYPE_DECIMAL : return 23;
case DBTYPE_NUMERIC : return 23;
case DBTYPE_VARIANT : return 20;
case DBTYPE_IDISPATCH : return 32;
case DBTYPE_IUNKNOWN : return 32;
case DBTYPE_GUID : return 38;
case DBTYPE_ARRAY : return 32;
case DBTYPE_VECTOR : return 32;
case DBTYPE_DATE : return 32;
case DBTYPE_DBDATE : return 32;
case DBTYPE_DBTIME : return 32;
case DBTYPE_DBTIMESTAMP : return 32;
case DBTYPE_FILETIME : return 32;
case DBTYPE_PROPVARIANT : return 32;
case DBTYPE_VARNUMERIC : return 32;
case DBTYPE_CY : return 32;
default : {
ATLASSERT(FALSE); // unhandled column type
return 32;
}
}
}