DCL 3.7.4
Loading...
Searching...
No Matches
SQLQuery.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h>
5#endif
6// 2005.01.26
7
8#include <wchar.h> // wcschr
9#include <wctype.h> // iswspace
10
11#include <dcl/Object.h>
12
13#if __DCL_HAVE_ALLOC_DEBUG
14#undef __DCL_ALLOC_LEVEL
15#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
16#endif
17
18#include <dcl/Charset.h>
19#include <dcl/SQL.h>
20
21#if __DCL_HAVE_THIS_FILE__
22#undef __THIS_FILE__
23static const char_t __THIS_FILE__[] = __T("dcl/SQLQuery.cpp");
24#endif
25
26__DCL_BEGIN_NAMESPACE
27
30
32{
33 __fields = NULL;
34 __count = 0;
35}
36
41
43{
44 if (__fields) {
45 __DCL_ASSERT(__count > 0);
46 delete[] __fields;
47 __fields = NULL;
48 __count = 0;
49 }
50 __fieldMap.clear();
51}
52
54{
55 SQL::Query* hQuery = _query->handle();
56
57 __DCL_ASSERT(hQuery->fieldCount() > 0);
58 __DCL_ASSERT((__fields == NULL) && (__count == 0));
59
60 clear();
61
62 __count = hQuery->fieldCount();
63 __fields = new SQLField[__count];
64 __DCL_ASSERT(__fields != NULL);
65
66 SQLField* _field = NULL;
67 for(size_t i = 0; i < hQuery->fieldCount(); i++) {
68 _field = &(__fields[i]);
69 _field->__query = _query;
70 if (!hQuery->getField(i, &(_field->__handle))) {
71 throw new SQLException(_query, NULL);
72 }
73 }
74}
75
76// public
79{
80 __DCL_ASSERT(_name != NULL);
82
83 SQLField* _field = NULL;
84
85 if (__count >= 7) { // 순차검색 n*n/2 Hashing 3*n
86 if (__fieldMap.isEmpty()) {
87 __fieldMap.initBuckets(__count);
88 for(size_t i = 0; i < __count; i++)
89 __fieldMap[__fields[i].name()] = &__fields[i];
90 }
91 _field = (SQLField*)(__fieldMap[_name]);
92 }
93 else {
94 for(size_t i = 0; i < __count; i++) {
95// if (__fields[i].fieldName() == strFieldName)
96 if (String::compare(__fields[i].name(), _name) == 0) {
97 _field = &__fields[i];
98 break;
99 }
100 }
101 }
102
103 if (_field == NULL) {
104 throw new InvalidIndexException(_name);
105 }
106
107 return *_field;
108}
109
112
114{
115 __params = NULL;
116 __count = 0;
117}
118
120{
121 clear();
122}
123
125{
126 if (__params) {
127 __DCL_ASSERT(__count > 0);
128 delete[] __params;
129 __params = NULL;
130 __count = 0;
131 }
132 __paramMap.clear();
133}
134
135void SQLParams::initialize(SQLQuery* _query, const StringArray _names)
136{
137 SQL::Query* hQuery = _query->handle();
138
139 __DCL_ASSERT((__params == NULL) && (__count == 0));
140 __DCL_ASSERT(hQuery->paramCount() == _names.size());
141
142 __count = hQuery->paramCount();
143 __params = new SQLParam[__count];
144 __DCL_ASSERT(__params != NULL);
145
146 for(size_t i = 0; i < hQuery->paramCount(); i++) {
147 SQLParam* _param = &__params[i];
148 _param->__query = _query;
149 if (!hQuery->getParam(i, (SQL::Param**)&(_param->__handle))) {
150 throw new SQLException(_query, NULL);
151 }
152 ((SQL::Param*)(_param->__handle))->setName(_names[i]);
153 }
154}
155
156// public
157SQLParam& SQLParams::byName(const wchar_t* _name) _CONST
159{
160 __DCL_ASSERT(_name != NULL);
162
163 SQLParam* r = NULL;
164
165 if (__count >= 7) { // 순차검색 n*n/2 Hashing 3*n
166 if (__paramMap.isEmpty()) {
167 __paramMap.initBuckets(__count);
168 for (size_t i = 0; i < __count; i++) {
169 SQLParam* p = &__params[i];
170 __paramMap[p->name()] = p;
171 }
172 }
173 r = (SQLParam*)(__paramMap[_name]);
174 }
175 else {
176 for(size_t i = 0; i < __count; i++) {
177 if (String::compare(__params[i].name(), _name) == 0) {
178 r = &__params[i];
179 break;
180 }
181 }
182 }
183
184 if (r == NULL) {
185 throw new InvalidIndexException(_name);
186 }
187
188 return *r;
189}
190
191static void __sql_transform__(
192 const String& _sql, wchar_t _placeholder,
193 String& _newsql, StringArray& _names
194)
195{
196 StringBuilder newsql(_sql.length());
197 const wchar_t* s = _sql.data();
198 const wchar_t* e = s + _sql.length();
199 const wchar_t* p = s;
200 while (p < e) {
201 // :: := 는 제외한다.
202 // : ? $ 는 1개의 문자만 있어도 포함한다.
203 if ((*p == L':' && !wcschr(L":=", *(p + 1)))
204 || *p == L'?' || *p == L'$') {
205 newsql.append(s, p);
206 if (_placeholder == L'?')
207 newsql.append(L'?');
208 else {
209 // L':', L'$'
210 // position은 1부터
211 newsql.format(L"%lc%zd", _placeholder, _names.size() + 1);
212 }
213 p++;
214 s = p;
215 while (p < e) {
216 // :; :name; :name::char
217 if (wcschr(L",);:", *p) || iswspace(*p)) {
218 break;
219 }
220 p++;
221 }
222 // s == p 이름이 없는 경우도 있다.
223 _names.add(String(s, p));
224 // __DCL_TRACE1(L"[%ls]\n", _names[_names.size() - 1].data());
225 s = p;
226 }
227 else if (*p == L'\'') {
228 p++;
229 while (p < e) {
230 if (*p++ == L'\'') {
231 break;
232 }
233 }
234 }
235 else {
236 p++;
237 }
238 }
239
240 if (s < p) {
241 newsql.append(s, p);
242 }
243
244 _newsql = newsql.toString();
245}
246
249
250void SQLQuery::initialize(SQLConnection* _conn) __DCL_THROWS1(SQLException*)
251{
252 __handle = NULL;
253 __connection = NULL;
254
255 __DCL_ASSERT(_conn != NULL);
256
257 SQL::Query* hQuery = NULL;
258 if (!_conn->handle()->createQueryInstance(&hQuery)) {
259 throw new SQLException(_conn, NULL);
260 }
261 __DCL_ASSERT(hQuery != NULL);
262
263 __handle = hQuery;
264 __connection = _conn;
265}
266
268{
269 initialize(_conn);
270}
271
273{
274 initialize(&_conn);
275}
276
278{
279 __connection->handle()->destroyQueryInstance(__handle);
280}
281
283{
284#ifdef __DCL_DEBUG
285 __sql = _sql;
286#endif
287
288 __params.clear();
289 __fields.clear();
290
291 String sql;
292 StringArray names;
293 __sql_transform__(_sql, __handle->placeholder(), sql, names);
294 // __DCL_TRACE2(L"[%zd][%ls]\n", names.size(), sql.data());
295
296 ByteString mbs;
297 try {
298 mbs = UTF8Encoder::encode(sql);
299 }
300 catch (CharsetConvertException* _cause) {
301 throw new SQLException(this, _cause);
302 }
303
304 if (!__handle->prepare(mbs, mbs.length(), names.size())) {
305#ifdef __DCL_DEBUG
306 throw new SQLException(this, __sql);
307#else
308 throw new SQLException(this, NULL);
309#endif
310 }
311
312 if (__handle->paramCount() > 0)
313 __params.initialize(this, names);
314}
315
317{
318 if (!__handle->execute()) {
319#ifdef __DCL_DEBUG
320 throw new SQLException(this, __sql);
321#else
322 throw new SQLException(this, NULL);
323#endif
324 }
325
326 if (__handle->fieldCount() > 0 && __fields.isEmpty())
327 __fields.initialize(this);
328}
329
331{
332 prepare(_sql);
333 execute();
334}
335
337{
338 if (!__handle->fetch()) {
339 throw new SQLException(this, NULL);
340 }
341}
342
344{
345 bool _moreResults = false;
346 if (!__handle->moreResults(&_moreResults)) {
347 throw new SQLException(this, NULL);
348 }
349
350 __fields.clear();
351 if (__handle->fieldCount() > 0) {
352 __fields.initialize(this);
353 }
354
355 return _moreResults;
356}
357
358__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define _CONST
Definition Config.h:325
#define __DCL_THROWS1(e)
Definition Config.h:152
IOException *size_t r
Definition MediaInfo.cpp:82
if(r==0)
Definition MediaInfo.cpp:83
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
Definition SQL.h:48
SQL::Field * __handle
Definition SQL.h:122
SQLQuery * __query
Definition SQL.h:123
void initialize(SQLQuery *_query)
Definition SQLQuery.cpp:53
_CONST SQLField & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:77
void clear()
Definition SQLQuery.cpp:42
friend class SQLQuery
Definition SQL.h:233
virtual ~SQLFields()
Definition SQLQuery.cpp:37
bool isEmpty() const
Definition SQL.inl:60
virtual ~SQLParams()
Definition SQLQuery.cpp:119
void initialize(SQLQuery *_query, const StringArray _names)
Definition SQLQuery.cpp:135
friend class SQLQuery
Definition SQL.h:261
void clear()
Definition SQLQuery.cpp:124
bool isEmpty() const
Definition SQL.inl:85
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:157
void prepare(const String &_sql) __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:282
SQLQuery(SQLConnection *_conn) __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:267
virtual ~SQLQuery()
Definition SQLQuery.cpp:277
SQL::Query * __handle
Definition SQL.h:301
void execute() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:316
SQLParams __params
Definition SQL.h:304
void fetch() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:336
SQL::Query * handle() const
Definition SQL.inl:111
SQLFields __fields
Definition SQL.h:303
bool moreResults() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:343
SQLConnection * __connection
Definition SQL.h:302