DCL 4.0
Loading...
Searching...
No Matches
SQLQuery.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2#if __DCL_WINDOWS
3#include <windows.h>
4#endif
5// 2005.01.26
6
7#include <wchar.h> // wcschr
8#include <wctype.h> // iswspace
9
10#include <dcl/Object.h>
11
12#if __DCL_HAVE_ALLOC_DEBUG
13#undef __DCL_ALLOC_LEVEL
14#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
15#endif
16
17#include <dcl/Charset.h>
18#include <dcl/SQL.h>
19
20#if __DCL_DEBUG
21#undef __THIS_FILE__
22static const char_t __THIS_FILE__[] = __T("dcl/SQLQuery.cpp");
23#endif
24
25__DCL_BEGIN_NAMESPACE
26
29
31{
32 __fields = NULL;
33 __count = 0;
34}
35
40
42{
43 if (__fields) {
44 __DCL_ASSERT(__count > 0);
45 delete[] __fields;
46 __fields = NULL;
47 __count = 0;
48 }
49 __fieldMap.clear();
50}
51
53
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);
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);
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__(const String& _sql,
192 wchar_t _placeholder, String& _newsql, StringArray& _names)
193{
194 StringBuilder newsql(_sql.length());
195 const wchar_t* s = _sql.data();
196 const wchar_t* e = s + _sql.length();
197 const wchar_t* p = s;
198 while (p < e) {
199 // :: := 는 제외한다.
200 // : ? 는 1개의 문자만 있어도 포함한다.
201 if ((*p == L':' && !wcschr(L":=", *(p + 1))) || *p == L'?') {
202 newsql.append(s, p);
203 if (_placeholder == L'?')
204 newsql.append(L'?');
205 else { // L':'
206 // Oracle에서 position은 1부터
207 newsql.format(L":%zd", _names.size() + 1);
208 }
209 p++;
210 s = p;
211 while (p < e) {
212 // :; :name; :name::char
213 if (wcschr(L",);:", *p) || iswspace(*p)) {
214 break;
215 }
216 p++;
217 }
218 // s == p 이름이 없는 경우도 있다.
219 _names.add(String(s, p));
220 // __DCL_TRACE1(L"[%ls]\n", _names[_names.size() - 1].data());
221 s = p;
222 }
223 else if (*p == L'\'') {
224 p++;
225 while (p < e) {
226 if (*p++ == L'\'') {
227 break;
228 }
229 }
230 }
231 else {
232 p++;
233 }
234 }
235
236 if (s < p) {
237 newsql.append(s, p);
238 }
239
240 _newsql = newsql.toString();
241}
242
245
246void SQLQuery::initialize(SQLConnection* _conn) __DCL_THROWS1(SQLException*)
247{
248 __handle = NULL;
249 __connection = NULL;
250
251 __DCL_ASSERT(_conn != NULL);
252
253 SQL::Query* hQuery = NULL;
254 if (!_conn->handle()->createQueryInstance(&hQuery)) {
255 throw new SQLException(_conn);
256 }
257 __DCL_ASSERT(hQuery != NULL);
258
259 __handle = hQuery;
260 __connection = _conn;
261}
262
264{
265 initialize(_conn);
266}
267
269{
270 initialize(&_conn);
271}
272
274{
275 __connection->handle()->destroyQueryInstance(__handle);
276}
277
279 const String& _sql
281{
282#ifdef __DCL_DEBUG
283 __sql = _sql;
284#endif
285
286 __params.clear();
287 __fields.clear();
288
289 String sql;
290 StringArray names;
291 __sql_transform__(_sql, __handle->placeholder(), sql, names);
292 //__DCL_TRACE2(L"[%zd][%ls]\n", names.size(), sql.data());
293
294 ByteString bstr = UTF8Encoder::encode(sql);
295 if (!__handle->prepare(bstr, bstr.length(), names.size())) {
296#ifdef __DCL_DEBUG
297 throw new SQLException(this, __sql);
298#else
299 throw new SQLException(this);
300#endif
301 }
302
303 if (__handle->paramCount() > 0)
304 __params.initialize(this, names);
305}
306
308{
309 if (!__handle->execute()) {
310#ifdef __DCL_DEBUG
311 throw new SQLException(this, __sql);
312#else
313 throw new SQLException(this);
314#endif
315 }
316
317 if (__handle->fieldCount() > 0 && __fields.isEmpty())
318 __fields.initialize(this);
319}
320
322 const String& _sql
324{
325 prepare(_sql);
327}
328
330{
331 if (!__handle->fetch()) {
332 throw new SQLException(this);
333 }
334}
335
337{
338 if (!__handle->nextResult()) {
339 throw new SQLException(this);
340 }
341
342 __fields.clear();
343 if (__handle->fieldCount() > 0)
344 __fields.initialize(this);
345
346 return !__handle->eof();
347}
348
349__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
wchar_t char_t
Definition Config.h:275
#define _CONST
Definition Config.h:353
#define __DCL_THROWS2(e1, e2)
Definition Config.h:168
#define __DCL_THROWS1(e)
Definition Config.h:167
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
ByteString r
if(!__handle->open(bs, bs.length()))
ByteString bstr
String sql
Definition SQLQuery.cpp:289
void CharsetConvertException * execute()
StringArray names
Definition SQLQuery.cpp:290
Definition SQL.h:48
SQL::Field * __handle
Definition SQL.h:117
SQLQuery * __query
Definition SQL.h:118
void initialize(SQLQuery *_query)
Definition SQLQuery.cpp:52
_CONST SQLField & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:77
void clear()
Definition SQLQuery.cpp:41
friend class SQLQuery
Definition SQL.h:222
virtual ~SQLFields()
Definition SQLQuery.cpp:36
bool isEmpty() const
Definition SQL.inl:98
virtual ~SQLParams()
Definition SQLQuery.cpp:119
void initialize(SQLQuery *_query, const StringArray _names)
Definition SQLQuery.cpp:135
friend class SQLQuery
Definition SQL.h:249
void clear()
Definition SQLQuery.cpp:124
bool isEmpty() const
Definition SQL.inl:123
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
Definition SQLQuery.cpp:157
SQLQuery(SQLConnection *_conn) __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:263
virtual ~SQLQuery()
Definition SQLQuery.cpp:273
SQL::Query * __handle
Definition SQL.h:294
void prepare(const String &_sql) __DCL_THROWS2(SQLException *
void CharsetConvertException *void execute() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:307
void CharsetConvertException *void fetch() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:329
SQL::Query * handle() const
Definition SQL.inl:149
SQLFields __fields
Definition SQL.h:296
bool nextResult() __DCL_THROWS1(SQLException *)
Definition SQLQuery.cpp:336
SQLConnection * __connection
Definition SQL.h:295