]> git.stg.codes - stg.git/blob - libs/ibpp/statement.cpp
Build and test in both Debug and Release mode.
[stg.git] / libs / ibpp / statement.cpp
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 //      File    : $Id: statement.cpp,v 1.2 2009/03/19 20:00:28 faust Exp $\r
4 //      Subject : IBPP, Service class implementation\r
5 //\r
6 ///////////////////////////////////////////////////////////////////////////////\r
7 //\r
8 //      (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)\r
9 //\r
10 //      The contents of this file are subject to the IBPP License (the "License");\r
11 //      you may not use this file except in compliance with the License.  You may\r
12 //      obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'\r
13 //      file which must have been distributed along with this file.\r
14 //\r
15 //      This software, distributed under the License, is distributed on an "AS IS"\r
16 //      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the\r
17 //      License for the specific language governing rights and limitations\r
18 //      under the License.\r
19 //\r
20 ///////////////////////////////////////////////////////////////////////////////\r
21 //\r
22 //      COMMENTS\r
23 //      * Tabulations should be set every four characters when editing this file.\r
24 //\r
25 ///////////////////////////////////////////////////////////////////////////////\r
26 \r
27 #ifdef _MSC_VER\r
28 #pragma warning(disable: 4786 4996)\r
29 #ifndef _DEBUG\r
30 #pragma warning(disable: 4702)\r
31 #endif\r
32 #endif\r
33 \r
34 #include "_ibpp.h"\r
35 \r
36 #ifdef HAS_HDRSTOP\r
37 #pragma hdrstop\r
38 #endif\r
39 \r
40 #include <cstring>\r
41 \r
42 using namespace ibpp_internals;\r
43 \r
44 //      (((((((( OBJECT INTERFACE IMPLEMENTATION ))))))))\r
45 \r
46 void StatementImpl::Prepare(const std::string& sql)\r
47 {\r
48         if (mDatabase == 0)\r
49                 throw LogicExceptionImpl("Statement::Prepare", _("An IDatabase must be attached."));\r
50         if (mDatabase->GetHandle() == 0)\r
51                 throw LogicExceptionImpl("Statement::Prepare", _("IDatabase must be connected."));\r
52         if (mTransaction == 0)\r
53                 throw LogicExceptionImpl("Statement::Prepare", _("An ITransaction must be attached."));\r
54         if (mTransaction->GetHandle() == 0)\r
55                 throw LogicExceptionImpl("Statement::Prepare", _("ITransaction must be started."));\r
56         if (sql.empty())\r
57                 throw LogicExceptionImpl("Statement::Prepare", _("SQL statement can't be 0."));\r
58 \r
59         // Saves the SQL sentence, only for reporting reasons in case of errors\r
60         mSql = sql;\r
61 \r
62         IBS status;\r
63 \r
64         // Free all resources currently attached to this Statement, then allocate\r
65         // a new statement descriptor.\r
66         Close();\r
67         (*gds.Call()->m_dsql_allocate_statement)(status.Self(), mDatabase->GetHandlePtr(), &mHandle);\r
68         if (status.Errors())\r
69                 throw SQLExceptionImpl(status, "Statement::Prepare",\r
70                         _("isc_dsql_allocate_statement failed"));\r
71 \r
72         // Empirical estimate of parameters count and output columns count.\r
73         // This is by far not an exact estimation, which would require parsing the\r
74         // SQL statement. If the SQL statement contains '?' and ',' in string\r
75         // constants, this count will obviously be wrong, but it will be exagerated.\r
76         // It won't hurt. We just try to not have to re-allocate those descriptors later.\r
77         // So we prefer to get them a little bit larger than needed than the other way.\r
78         int16_t inEstimate = 0;\r
79         int16_t outEstimate = 1;\r
80         for (size_t i = 0; i < strlen(sql.c_str()); i++)\r
81         {\r
82                 if (sql[i] == '?') ++inEstimate;\r
83                 if (sql[i] == ',') ++outEstimate;\r
84         }\r
85 \r
86         /*\r
87         DebugStream()<< "Prepare(\""<< sql<< "\")"<< fds;\r
88         DebugStream()<< _("Estimation: ")<< inEstimate<< _(" IN parameters and ")\r
89                         << outEstimate<< _(" OUT columns")<< fds;\r
90         */\r
91 \r
92         // Allocates output descriptor and prepares the statement\r
93         mOutRow = new RowImpl(mDatabase->Dialect(), outEstimate, mDatabase, mTransaction);\r
94         mOutRow->AddRef();\r
95 \r
96         status.Reset();\r
97         (*gds.Call()->m_dsql_prepare)(status.Self(), mTransaction->GetHandlePtr(),\r
98                 &mHandle, (short)sql.length(), const_cast<char*>(sql.c_str()),\r
99                         short(mDatabase->Dialect()), mOutRow->Self());\r
100         if (status.Errors())\r
101         {\r
102                 Close();\r
103                 std::string context = "Statement::Prepare( ";\r
104                 context.append(mSql).append(" )");\r
105                 throw SQLExceptionImpl(status, context.c_str(),\r
106                         _("isc_dsql_prepare failed"));\r
107         }\r
108 \r
109         // Read what kind of statement was prepared\r
110         status.Reset();\r
111         char itemsReq[] = {isc_info_sql_stmt_type};\r
112         char itemsRes[8];\r
113         (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq,\r
114                 sizeof(itemsRes), itemsRes);\r
115         if (status.Errors())\r
116         {\r
117                 Close();\r
118                 throw SQLExceptionImpl(status, "Statement::Prepare",\r
119                         _("isc_dsql_sql_info failed"));\r
120         }\r
121         if (itemsRes[0] == isc_info_sql_stmt_type)\r
122         {\r
123                 switch (itemsRes[3])\r
124                 {\r
125                         case isc_info_sql_stmt_select :         mType = IBPP::stSelect; break;\r
126                         case isc_info_sql_stmt_insert :         mType = IBPP::stInsert; break;\r
127                         case isc_info_sql_stmt_update :         mType = IBPP::stUpdate; break;\r
128                         case isc_info_sql_stmt_delete :         mType = IBPP::stDelete; break;\r
129                         case isc_info_sql_stmt_ddl :            mType = IBPP::stDDL; break;\r
130                         case isc_info_sql_stmt_exec_procedure : mType = IBPP::stExecProcedure; break;\r
131                         case isc_info_sql_stmt_select_for_upd : mType = IBPP::stSelectUpdate; break;\r
132                         case isc_info_sql_stmt_set_generator :  mType = IBPP::stSetGenerator; break;\r
133                         case isc_info_sql_stmt_savepoint :      mType = IBPP::stSavePoint; break;\r
134                         default : mType = IBPP::stUnsupported;\r
135                 }\r
136         }\r
137         if (mType == IBPP::stUnknown || mType == IBPP::stUnsupported)\r
138         {\r
139                 Close();\r
140                 throw LogicExceptionImpl("Statement::Prepare",\r
141                         _("Unknown or unsupported statement type"));\r
142         }\r
143 \r
144         if (mOutRow->Columns() == 0)\r
145         {\r
146                 // Get rid of the output descriptor, if it wasn't required (no output)\r
147                 mOutRow->Release();\r
148                 mOutRow = 0;\r
149                 /*\r
150                 DebugStream()<< _("Dropped output descriptor which was not required")<< fds;\r
151                 */\r
152         }\r
153         else if (mOutRow->Columns() > mOutRow->AllocatedSize())\r
154         {\r
155                 // Resize the output descriptor (which is too small).\r
156                 // The statement does not need to be prepared again, though the\r
157                 // output columns must be described again.\r
158 \r
159                 /*\r
160                 DebugStream()<< _("Resize output descriptor from ")\r
161                         << mOutRow->AllocatedSize()<< _(" to ")<< mOutRow->Columns()<< fds;\r
162                 */\r
163 \r
164                 mOutRow->Resize(mOutRow->Columns());\r
165                 status.Reset();\r
166                 (*gds.Call()->m_dsql_describe)(status.Self(), &mHandle, 1, mOutRow->Self());\r
167                 if (status.Errors())\r
168                 {\r
169                         Close();\r
170                         throw SQLExceptionImpl(status, "Statement::Prepare",\r
171                                 _("isc_dsql_describe failed"));\r
172                 }\r
173         }\r
174 \r
175         if (inEstimate > 0)\r
176         {\r
177                 // Ready an input descriptor\r
178                 mInRow = new RowImpl(mDatabase->Dialect(), inEstimate, mDatabase, mTransaction);\r
179                 mInRow->AddRef();\r
180 \r
181                 status.Reset();\r
182                 (*gds.Call()->m_dsql_describe_bind)(status.Self(), &mHandle, 1, mInRow->Self());\r
183                 if (status.Errors())\r
184                 {\r
185                         Close();\r
186                         throw SQLExceptionImpl(status, "Statement::Prepare",\r
187                                 _("isc_dsql_describe_bind failed"));\r
188                 }\r
189 \r
190                 if (mInRow->Columns() == 0)\r
191                 {\r
192                         // Get rid of the input descriptor, if it wasn't required (no parameters)\r
193                         mInRow->Release();\r
194                         mInRow = 0;\r
195                         /*\r
196                         DebugStream()<< _("Dropped input descriptor which was not required")<< fds;\r
197                         */\r
198                 }\r
199                 else if (mInRow->Columns() > mInRow->AllocatedSize())\r
200                 {\r
201                         // Resize the input descriptor (which is too small).\r
202                         // The statement does not need to be prepared again, though the\r
203                         // parameters must be described again.\r
204 \r
205                         /*\r
206                         DebugStream()<< _("Resize input descriptor from ")\r
207                                         << mInRow->AllocatedSize()<< _(" to ")\r
208                                         << mInRow->Columns()<< fds;\r
209                         */\r
210 \r
211                         mInRow->Resize(mInRow->Columns());\r
212                         status.Reset();\r
213                         (*gds.Call()->m_dsql_describe_bind)(status.Self(), &mHandle, 1, mInRow->Self());\r
214                         if (status.Errors())\r
215                         {\r
216                                 Close();\r
217                                 throw SQLExceptionImpl(status, "Statement::Prepare",\r
218                                         _("isc_dsql_describe_bind failed"));\r
219                         }\r
220                 }\r
221         }\r
222 \r
223         // Allocates variables of the input descriptor\r
224         if (mInRow != 0)\r
225         {\r
226                 // Turn on 'can be NULL' on each input parameter\r
227                 for (int i = 0; i < mInRow->Columns(); i++)\r
228                 {\r
229                         XSQLVAR* var = &(mInRow->Self()->sqlvar[i]);\r
230                         if (! (var->sqltype & 1)) var->sqltype += short(1);\r
231                 }\r
232                 mInRow->AllocVariables();\r
233         }\r
234 \r
235         // Allocates variables of the output descriptor\r
236         if (mOutRow != 0) mOutRow->AllocVariables();\r
237 }\r
238 \r
239 void StatementImpl::Plan(std::string& plan)\r
240 {\r
241         if (mHandle == 0)\r
242                 throw LogicExceptionImpl("Statement::Plan", _("No statement has been prepared."));\r
243         if (mDatabase == 0)\r
244                 throw LogicExceptionImpl("Statement::Plan", _("A Database must be attached."));\r
245         if (mDatabase->GetHandle() == 0)\r
246                 throw LogicExceptionImpl("Statement::Plan", _("Database must be connected."));\r
247 \r
248         IBS status;\r
249         RB result(4096);\r
250         char itemsReq[] = {isc_info_sql_get_plan};\r
251 \r
252         (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq,\r
253                                                                    result.Size(), result.Self());\r
254         if (status.Errors()) throw SQLExceptionImpl(status,\r
255                                                                 "Statement::Plan", _("isc_dsql_sql_info failed."));\r
256 \r
257         result.GetString(isc_info_sql_get_plan, plan);\r
258         if (plan[0] == '\n') plan.erase(0, 1);\r
259 }\r
260 \r
261 void StatementImpl::Execute(const std::string& sql)\r
262 {\r
263         if (! sql.empty()) Prepare(sql);\r
264 \r
265         if (mHandle == 0)\r
266                 throw LogicExceptionImpl("Statement::Execute",\r
267                         _("No statement has been prepared."));\r
268 \r
269         // Check that a value has been set for each input parameter\r
270         if (mInRow != 0 && mInRow->MissingValues())\r
271                 throw LogicExceptionImpl("Statement::Execute",\r
272                         _("All parameters must be specified."));\r
273 \r
274         CursorFree();   // Free a previous 'cursor' if any\r
275 \r
276         IBS status;\r
277         if (mType == IBPP::stSelect)\r
278         {\r
279                 // Could return a result set (none, single or multi rows)\r
280                 (*gds.Call()->m_dsql_execute)(status.Self(), mTransaction->GetHandlePtr(),\r
281                         &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self());\r
282                 if (status.Errors())\r
283                 {\r
284                         //Close();      Commented because Execute error should not free the statement\r
285                         std::string context = "Statement::Execute( ";\r
286                         context.append(mSql).append(" )");\r
287                         throw SQLExceptionImpl(status, context.c_str(),\r
288                                 _("isc_dsql_execute failed"));\r
289                 }\r
290                 if (mOutRow != 0)\r
291                 {\r
292                         mResultSetAvailable = true;\r
293                         mCursorOpened = true;\r
294                 }\r
295         }\r
296         else\r
297         {\r
298                 // Should return at most a single row\r
299                 (*gds.Call()->m_dsql_execute2)(status.Self(), mTransaction->GetHandlePtr(),\r
300                         &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self(),\r
301                         mOutRow == 0 ? 0 : mOutRow->Self());\r
302                 if (status.Errors())\r
303                 {\r
304                         //Close();      Commented because Execute error should not free the statement\r
305                         std::string context = "Statement::Execute( ";\r
306                         context.append(mSql).append(" )");\r
307                         throw SQLExceptionImpl(status, context.c_str(),\r
308                                 _("isc_dsql_execute2 failed"));\r
309                 }\r
310         }\r
311 }\r
312 \r
313 void StatementImpl::CursorExecute(const std::string& cursor, const std::string& sql)\r
314 {\r
315         if (cursor.empty())\r
316                 throw LogicExceptionImpl("Statement::CursorExecute", _("Cursor name can't be 0."));\r
317 \r
318         if (! sql.empty()) Prepare(sql);\r
319 \r
320         if (mHandle == 0)\r
321                 throw LogicExceptionImpl("Statement::CursorExecute", _("No statement has been prepared."));\r
322         if (mType != IBPP::stSelectUpdate)\r
323                 throw LogicExceptionImpl("Statement::CursorExecute", _("Statement must be a SELECT FOR UPDATE."));\r
324         if (mOutRow == 0)\r
325                 throw LogicExceptionImpl("Statement::CursorExecute", _("Statement would return no rows."));\r
326 \r
327         // Check that a value has been set for each input parameter\r
328         if (mInRow != 0 && mInRow->MissingValues())\r
329                 throw LogicExceptionImpl("Statement::CursorExecute",\r
330                         _("All parameters must be specified."));\r
331 \r
332         CursorFree();   // Free a previous 'cursor' if any\r
333 \r
334         IBS status;\r
335         (*gds.Call()->m_dsql_execute)(status.Self(), mTransaction->GetHandlePtr(),\r
336                 &mHandle, 1, mInRow == 0 ? 0 : mInRow->Self());\r
337         if (status.Errors())\r
338         {\r
339                 //Close();      Commented because Execute error should not free the statement\r
340                 std::string context = "Statement::CursorExecute( ";\r
341                 context.append(mSql).append(" )");\r
342                 throw SQLExceptionImpl(status, context.c_str(),\r
343                         _("isc_dsql_execute failed"));\r
344         }\r
345 \r
346         status.Reset();\r
347         (*gds.Call()->m_dsql_set_cursor_name)(status.Self(), &mHandle, const_cast<char*>(cursor.c_str()), 0);\r
348         if (status.Errors())\r
349         {\r
350                 //Close();      Commented because Execute error should not free the statement\r
351                 throw SQLExceptionImpl(status, "Statement::CursorExecute",\r
352                         _("isc_dsql_set_cursor_name failed"));\r
353         }\r
354 \r
355         mResultSetAvailable = true;\r
356         mCursorOpened = true;\r
357 }\r
358 \r
359 void StatementImpl::ExecuteImmediate(const std::string& sql)\r
360 {\r
361         if (mDatabase == 0)\r
362                 throw LogicExceptionImpl("Statement::ExecuteImmediate", _("An IDatabase must be attached."));\r
363         if (mDatabase->GetHandle() == 0)\r
364                 throw LogicExceptionImpl("Statement::ExecuteImmediate", _("IDatabase must be connected."));\r
365         if (mTransaction == 0)\r
366                 throw LogicExceptionImpl("Statement::ExecuteImmediate", _("An ITransaction must be attached."));\r
367         if (mTransaction->GetHandle() == 0)\r
368                 throw LogicExceptionImpl("Statement::ExecuteImmediate", _("ITransaction must be started."));\r
369         if (sql.empty())\r
370                 throw LogicExceptionImpl("Statement::ExecuteImmediate", _("SQL statement can't be 0."));\r
371 \r
372         IBS status;\r
373         Close();\r
374     (*gds.Call()->m_dsql_execute_immediate)(status.Self(), mDatabase->GetHandlePtr(),\r
375         mTransaction->GetHandlePtr(), 0, const_cast<char*>(sql.c_str()),\r
376                 short(mDatabase->Dialect()), 0);\r
377     if (status.Errors())\r
378         {\r
379                 std::string context = "Statement::ExecuteImmediate( ";\r
380                 context.append(sql).append(" )");\r
381                 throw SQLExceptionImpl(status, context.c_str(),\r
382                         _("isc_dsql_execute_immediate failed"));\r
383         }\r
384 }\r
385 \r
386 int StatementImpl::AffectedRows()\r
387 {\r
388         if (mHandle == 0)\r
389                 throw LogicExceptionImpl("Statement::AffectedRows", _("No statement has been prepared."));\r
390         if (mDatabase == 0)\r
391                 throw LogicExceptionImpl("Statement::AffectedRows", _("A Database must be attached."));\r
392         if (mDatabase->GetHandle() == 0)\r
393                 throw LogicExceptionImpl("Statement::AffectedRows", _("Database must be connected."));\r
394 \r
395         int count;\r
396         IBS status;\r
397         RB result;\r
398         char itemsReq[] = {isc_info_sql_records};\r
399 \r
400         (*gds.Call()->m_dsql_sql_info)(status.Self(), &mHandle, 1, itemsReq,\r
401                 result.Size(), result.Self());\r
402         if (status.Errors()) throw SQLExceptionImpl(status,\r
403                         "Statement::AffectedRows", _("isc_dsql_sql_info failed."));\r
404 \r
405         if (mType == IBPP::stInsert)\r
406                         count = result.GetValue(isc_info_sql_records, isc_info_req_insert_count);\r
407         else if (mType == IBPP::stUpdate)\r
408                         count = result.GetValue(isc_info_sql_records, isc_info_req_update_count);\r
409         else if (mType == IBPP::stDelete)\r
410                         count = result.GetValue(isc_info_sql_records, isc_info_req_delete_count);\r
411         else if (mType == IBPP::stSelect)\r
412                         count = result.GetValue(isc_info_sql_records, isc_info_req_select_count);\r
413         else    count = 0;      // Returns zero count for unknown cases\r
414 \r
415         return count;\r
416 }\r
417 \r
418 bool StatementImpl::Fetch()\r
419 {\r
420         if (! mResultSetAvailable)\r
421                 throw LogicExceptionImpl("Statement::Fetch",\r
422                         _("No statement has been executed or no result set available."));\r
423 \r
424         IBS status;\r
425         ISC_STATUS code = (*gds.Call()->m_dsql_fetch)(status.Self(), &mHandle, 1, mOutRow->Self());\r
426         if (code == 100)        // This special code means "no more rows"\r
427         {\r
428                 mResultSetAvailable = false;\r
429                 // Oddly enough, fetching rows up to the last one seems to open\r
430                 // an 'implicit' cursor that needs to be closed.\r
431                 mCursorOpened = true;\r
432                 CursorFree();   // Free the explicit or implicit cursor/result-set\r
433                 return false;\r
434         }\r
435         if (status.Errors())\r
436         {\r
437                 Close();\r
438                 throw SQLExceptionImpl(status, "Statement::Fetch",\r
439                         _("isc_dsql_fetch failed."));\r
440         }\r
441 \r
442         return true;\r
443 }\r
444 \r
445 bool StatementImpl::Fetch(IBPP::Row& row)\r
446 {\r
447         if (! mResultSetAvailable)\r
448                 throw LogicExceptionImpl("Statement::Fetch(row)",\r
449                         _("No statement has been executed or no result set available."));\r
450 \r
451         RowImpl* rowimpl = new RowImpl(*mOutRow);\r
452         row = rowimpl;\r
453 \r
454         IBS status;\r
455         ISC_STATUS code = (*gds.Call()->m_dsql_fetch)(status.Self(), &mHandle, 1,\r
456                                         rowimpl->Self());\r
457         if (code == 100)        // This special code means "no more rows"\r
458         {\r
459                 mResultSetAvailable = false;\r
460                 // Oddly enough, fetching rows up to the last one seems to open\r
461                 // an 'implicit' cursor that needs to be closed.\r
462                 mCursorOpened = true;\r
463                 CursorFree();   // Free the explicit or implicit cursor/result-set\r
464                 row.clear();\r
465                 return false;\r
466         }\r
467         if (status.Errors())\r
468         {\r
469                 Close();\r
470                 row.clear();\r
471                 throw SQLExceptionImpl(status, "Statement::Fetch(row)",\r
472                         _("isc_dsql_fetch failed."));\r
473         }\r
474 \r
475         return true;\r
476 }\r
477 \r
478 void StatementImpl::Close()\r
479 {\r
480         // Free all statement resources.\r
481         // Used before preparing a new statement or from destructor.\r
482 \r
483         if (mInRow != 0) { mInRow->Release(); mInRow = 0; }\r
484         if (mOutRow != 0) { mOutRow->Release(); mOutRow = 0; }\r
485 \r
486         mResultSetAvailable = false;\r
487         mCursorOpened = false;\r
488         mType = IBPP::stUnknown;\r
489 \r
490         if (mHandle != 0)\r
491         {\r
492                 IBS status;\r
493                 (*gds.Call()->m_dsql_free_statement)(status.Self(), &mHandle, DSQL_drop);\r
494                 mHandle = 0;\r
495                 if (status.Errors())\r
496                         throw SQLExceptionImpl(status, "Statement::Close(DSQL_drop)",\r
497                                 _("isc_dsql_free_statement failed."));\r
498         }\r
499 }\r
500 \r
501 void StatementImpl::SetNull(int param)\r
502 {\r
503         if (mHandle == 0)\r
504                 throw LogicExceptionImpl("Statement::SetNull", _("No statement has been prepared."));\r
505         if (mInRow == 0)\r
506                 throw LogicExceptionImpl("Statement::SetNull", _("The statement does not take parameters."));\r
507 \r
508         mInRow->SetNull(param);\r
509 }\r
510 \r
511 void StatementImpl::Set(int param, bool value)\r
512 {\r
513         if (mHandle == 0)\r
514                 throw LogicExceptionImpl("Statement::Set[bool]", _("No statement has been prepared."));\r
515         if (mInRow == 0)\r
516                 throw LogicExceptionImpl("Statement::Set[bool]", _("The statement does not take parameters."));\r
517 \r
518         mInRow->Set(param, value);\r
519 }\r
520 \r
521 void StatementImpl::Set(int param, const char* cstring)\r
522 {\r
523         if (mHandle == 0)\r
524                 throw LogicExceptionImpl("Statement::Set[char*]", _("No statement has been prepared."));\r
525         if (mInRow == 0)\r
526                 throw LogicExceptionImpl("Statement::Set[char*]", _("The statement does not take parameters."));\r
527 \r
528         mInRow->Set(param, cstring);\r
529 }\r
530 \r
531 void StatementImpl::Set(int param, const void* bindata, int len)\r
532 {\r
533         if (mHandle == 0)\r
534                 throw LogicExceptionImpl("Statement::Set[void*]", _("No statement has been prepared."));\r
535         if (mInRow == 0)\r
536                 throw LogicExceptionImpl("Statement::Set[void*]", _("The statement does not take parameters."));\r
537 \r
538         mInRow->Set(param, bindata, len);\r
539 }\r
540 \r
541 void StatementImpl::Set(int param, const std::string& s)\r
542 {\r
543         if (mHandle == 0)\r
544                 throw LogicExceptionImpl("Statement::Set[string]", _("No statement has been prepared."));\r
545         if (mInRow == 0)\r
546                 throw LogicExceptionImpl("Statement::Set[string]", _("The statement does not take parameters."));\r
547 \r
548         mInRow->Set(param, s);\r
549 }\r
550 \r
551 void StatementImpl::Set(int param, int16_t value)\r
552 {\r
553         if (mHandle == 0)\r
554                 throw LogicExceptionImpl("Statement::Set[int16_t]", _("No statement has been prepared."));\r
555         if (mInRow == 0)\r
556                 throw LogicExceptionImpl("Statement::Set[int16_t]", _("The statement does not take parameters."));\r
557 \r
558         mInRow->Set(param, value);\r
559 }\r
560 \r
561 void StatementImpl::Set(int param, int32_t value)\r
562 {\r
563         if (mHandle == 0)\r
564                 throw LogicExceptionImpl("Statement::Set[int32_t]", _("No statement has been prepared."));\r
565         if (mInRow == 0)\r
566                 throw LogicExceptionImpl("Statement::Set[int32_t]", _("The statement does not take parameters."));\r
567 \r
568         mInRow->Set(param, value);\r
569 }\r
570 \r
571 void StatementImpl::Set(int param, int64_t value)\r
572 {\r
573         if (mHandle == 0)\r
574                 throw LogicExceptionImpl("Statement::Set[int64_t]", _("No statement has been prepared."));\r
575         if (mInRow == 0)\r
576                 throw LogicExceptionImpl("Statement::Set[int64_t]", _("The statement does not take parameters."));\r
577 \r
578         mInRow->Set(param, value);\r
579 }\r
580 \r
581 void StatementImpl::Set(int param, float value)\r
582 {\r
583         if (mHandle == 0)\r
584                 throw LogicExceptionImpl("Statement::Set[float]", _("No statement has been prepared."));\r
585         if (mInRow == 0)\r
586                 throw LogicExceptionImpl("Statement::Set[float]", _("The statement does not take parameters."));\r
587 \r
588         mInRow->Set(param, value);\r
589 }\r
590 \r
591 void StatementImpl::Set(int param, double value)\r
592 {\r
593         if (mHandle == 0)\r
594                 throw LogicExceptionImpl("Statement::Set[double]", _("No statement has been prepared."));\r
595         if (mInRow == 0)\r
596                 throw LogicExceptionImpl("Statement::Set[double]", _("The statement does not take parameters."));\r
597 \r
598         mInRow->Set(param, value);\r
599 }\r
600 \r
601 void StatementImpl::Set(int param, const IBPP::Timestamp& value)\r
602 {\r
603         if (mHandle == 0)\r
604                 throw LogicExceptionImpl("Statement::Set[Timestamp]", _("No statement has been prepared."));\r
605         if (mInRow == 0)\r
606                 throw LogicExceptionImpl("Statement::Set[Timestamp]", _("The statement does not take parameters."));\r
607 \r
608         mInRow->Set(param, value);\r
609 }\r
610 \r
611 void StatementImpl::Set(int param, const IBPP::Date& value)\r
612 {\r
613         if (mHandle == 0)\r
614                 throw LogicExceptionImpl("Statement::Set[Date]", _("No statement has been prepared."));\r
615         if (mInRow == 0)\r
616                 throw LogicExceptionImpl("Statement::Set[Date]", _("The statement does not take parameters."));\r
617 \r
618         mInRow->Set(param, value);\r
619 }\r
620 \r
621 void StatementImpl::Set(int param, const IBPP::Time& value)\r
622 {\r
623         if (mHandle == 0)\r
624                 throw LogicExceptionImpl("Statement::Set[Time]", _("No statement has been prepared."));\r
625         if (mInRow == 0)\r
626                 throw LogicExceptionImpl("Statement::Set[Time]", _("The statement does not take parameters."));\r
627 \r
628         mInRow->Set(param, value);\r
629 }\r
630 \r
631 void StatementImpl::Set(int param, const IBPP::Blob& blob)\r
632 {\r
633         if (mHandle == 0)\r
634                 throw LogicExceptionImpl("Statement::Set[Blob]", _("No statement has been prepared."));\r
635         if (mInRow == 0)\r
636                 throw LogicExceptionImpl("Statement::Set[Blob]", _("The statement does not take parameters."));\r
637 \r
638         mInRow->Set(param, blob);\r
639 }\r
640 \r
641 void StatementImpl::Set(int param, const IBPP::Array& array)\r
642 {\r
643         if (mHandle == 0)\r
644                 throw LogicExceptionImpl("Statement::Set[Array]", _("No statement has been prepared."));\r
645         if (mInRow == 0)\r
646                 throw LogicExceptionImpl("Statement::Set[Array]", _("The statement does not take parameters."));\r
647 \r
648         mInRow->Set(param, array);\r
649 }\r
650 \r
651 void StatementImpl::Set(int param, const IBPP::DBKey& key)\r
652 {\r
653         if (mHandle == 0)\r
654                 throw LogicExceptionImpl("Statement::Set[DBKey]", _("No statement has been prepared."));\r
655         if (mInRow == 0)\r
656                 throw LogicExceptionImpl("Statement::Set[DBKey]", _("The statement does not take parameters."));\r
657 \r
658         mInRow->Set(param, key);\r
659 }\r
660 \r
661 /*\r
662 void StatementImpl::Set(int param, const IBPP::Value& value)\r
663 {\r
664         if (mHandle == 0)\r
665                 throw LogicExceptionImpl("Statement::Set[Value]", _("No statement has been prepared."));\r
666         if (mInRow == 0)\r
667                 throw LogicExceptionImpl("Statement::Set[Value]", _("The statement does not take parameters."));\r
668 \r
669         mInRow->Set(param, value);\r
670 }\r
671 */\r
672 \r
673 bool StatementImpl::IsNull(int column)\r
674 {\r
675         if (mOutRow == 0)\r
676                 throw LogicExceptionImpl("Statement::IsNull", _("The row is not initialized."));\r
677 \r
678         return mOutRow->IsNull(column);\r
679 }\r
680 \r
681 bool StatementImpl::Get(int column, bool* retvalue)\r
682 {\r
683         if (mOutRow == 0)\r
684                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
685         if (retvalue == 0)\r
686                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
687 \r
688         return mOutRow->Get(column, *retvalue);\r
689 }\r
690 \r
691 bool StatementImpl::Get(int column, bool& retvalue)\r
692 {\r
693         if (mOutRow == 0)\r
694                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
695 \r
696         return mOutRow->Get(column, retvalue);\r
697 }\r
698 \r
699 bool StatementImpl::Get(int column, char* retvalue)\r
700 {\r
701         if (mOutRow == 0)\r
702                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
703 \r
704         return mOutRow->Get(column, retvalue);\r
705 }\r
706 \r
707 bool StatementImpl::Get(int column, void* bindata, int& userlen)\r
708 {\r
709         if (mOutRow == 0)\r
710                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
711 \r
712         return mOutRow->Get(column, bindata, userlen);\r
713 }\r
714 \r
715 bool StatementImpl::Get(int column, std::string& retvalue)\r
716 {\r
717         if (mOutRow == 0)\r
718                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
719 \r
720         return mOutRow->Get(column, retvalue);\r
721 }\r
722 \r
723 bool StatementImpl::Get(int column, int16_t* retvalue)\r
724 {\r
725         if (mOutRow == 0)\r
726                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
727         if (retvalue == 0)\r
728                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
729 \r
730         return mOutRow->Get(column, *retvalue);\r
731 }\r
732 \r
733 bool StatementImpl::Get(int column, int16_t& retvalue)\r
734 {\r
735         if (mOutRow == 0)\r
736                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
737 \r
738         return mOutRow->Get(column, retvalue);\r
739 }\r
740 \r
741 bool StatementImpl::Get(int column, int32_t* retvalue)\r
742 {\r
743         if (mOutRow == 0)\r
744                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
745         if (retvalue == 0)\r
746                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
747 \r
748         return mOutRow->Get(column, *retvalue);\r
749 }\r
750 \r
751 bool StatementImpl::Get(int column, int32_t& retvalue)\r
752 {\r
753         if (mOutRow == 0)\r
754                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
755 \r
756         return mOutRow->Get(column, retvalue);\r
757 }\r
758 \r
759 bool StatementImpl::Get(int column, int64_t* retvalue)\r
760 {\r
761         if (mOutRow == 0)\r
762                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
763         if (retvalue == 0)\r
764                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
765 \r
766         return mOutRow->Get(column, *retvalue);\r
767 }\r
768 \r
769 bool StatementImpl::Get(int column, int64_t& retvalue)\r
770 {\r
771         if (mOutRow == 0)\r
772                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
773 \r
774         return mOutRow->Get(column, retvalue);\r
775 }\r
776 \r
777 bool StatementImpl::Get(int column, float* retvalue)\r
778 {\r
779         if (mOutRow == 0)\r
780                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
781         if (retvalue == 0)\r
782                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
783 \r
784         return mOutRow->Get(column, *retvalue);\r
785 }\r
786 \r
787 bool StatementImpl::Get(int column, float& retvalue)\r
788 {\r
789         if (mOutRow == 0)\r
790                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
791 \r
792         return mOutRow->Get(column, retvalue);\r
793 }\r
794 \r
795 bool StatementImpl::Get(int column, double* retvalue)\r
796 {\r
797         if (mOutRow == 0)\r
798                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
799         if (retvalue == 0)\r
800                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
801 \r
802         return mOutRow->Get(column, *retvalue);\r
803 }\r
804 \r
805 bool StatementImpl::Get(int column, double& retvalue)\r
806 {\r
807         if (mOutRow == 0)\r
808                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
809 \r
810         return mOutRow->Get(column, retvalue);\r
811 }\r
812 \r
813 bool StatementImpl::Get(int column, IBPP::Timestamp& timestamp)\r
814 {\r
815         if (mOutRow == 0)\r
816                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
817 \r
818         return mOutRow->Get(column, timestamp);\r
819 }\r
820 \r
821 bool StatementImpl::Get(int column, IBPP::Date& date)\r
822 {\r
823         if (mOutRow == 0)\r
824                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
825 \r
826         return mOutRow->Get(column, date);\r
827 }\r
828 \r
829 bool StatementImpl::Get(int column, IBPP::Time& time)\r
830 {\r
831         if (mOutRow == 0)\r
832                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
833 \r
834         return mOutRow->Get(column, time);\r
835 }\r
836 \r
837 bool StatementImpl::Get(int column, IBPP::Blob& blob)\r
838 {\r
839         if (mOutRow == 0)\r
840                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
841 \r
842         return mOutRow->Get(column, blob);\r
843 }\r
844 \r
845 bool StatementImpl::Get(int column, IBPP::DBKey& key)\r
846 {\r
847         if (mOutRow == 0)\r
848                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
849 \r
850         return mOutRow->Get(column, key);\r
851 }\r
852 \r
853 bool StatementImpl::Get(int column, IBPP::Array& array)\r
854 {\r
855         if (mOutRow == 0)\r
856                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
857 \r
858         return mOutRow->Get(column, array);\r
859 }\r
860 \r
861 /*\r
862 const IBPP::Value StatementImpl::Get(int column)\r
863 {\r
864         if (mOutRow == 0)\r
865                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
866 \r
867         return mOutRow->Get(column);\r
868 }\r
869 */\r
870 \r
871 bool StatementImpl::IsNull(const std::string& name)\r
872 {\r
873         if (mOutRow == 0)\r
874                 throw LogicExceptionImpl("Statement::IsNull", _("The row is not initialized."));\r
875 \r
876         return mOutRow->IsNull(name);\r
877 }\r
878 \r
879 bool StatementImpl::Get(const std::string& name, bool* retvalue)\r
880 {\r
881         if (mOutRow == 0)\r
882                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
883         if (retvalue == 0)\r
884                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
885 \r
886         return mOutRow->Get(name, *retvalue);\r
887 }\r
888 \r
889 bool StatementImpl::Get(const std::string& name, bool& retvalue)\r
890 {\r
891         if (mOutRow == 0)\r
892                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
893 \r
894         return mOutRow->Get(name, retvalue);\r
895 }\r
896 \r
897 bool StatementImpl::Get(const std::string& name, char* retvalue)\r
898 {\r
899         if (mOutRow == 0)\r
900                 throw LogicExceptionImpl("Statement::Get[char*]", _("The row is not initialized."));\r
901 \r
902         return mOutRow->Get(name, retvalue);\r
903 }\r
904 \r
905 bool StatementImpl::Get(const std::string& name, void* retvalue, int& count)\r
906 {\r
907         if (mOutRow == 0)\r
908                 throw LogicExceptionImpl("Statement::Get[void*,int]", _("The row is not initialized."));\r
909 \r
910         return mOutRow->Get(name, retvalue, count);\r
911 }\r
912 \r
913 bool StatementImpl::Get(const std::string& name, std::string& retvalue)\r
914 {\r
915         if (mOutRow == 0)\r
916                 throw LogicExceptionImpl("Statement::GetString", _("The row is not initialized."));\r
917 \r
918         return mOutRow->Get(name, retvalue);\r
919 }\r
920 \r
921 bool StatementImpl::Get(const std::string& name, int16_t* retvalue)\r
922 {\r
923         if (mOutRow == 0)\r
924                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
925         if (retvalue == 0)\r
926                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
927 \r
928         return mOutRow->Get(name, *retvalue);\r
929 }\r
930 \r
931 bool StatementImpl::Get(const std::string& name, int16_t& retvalue)\r
932 {\r
933         if (mOutRow == 0)\r
934                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
935 \r
936         return mOutRow->Get(name, retvalue);\r
937 }\r
938 \r
939 bool StatementImpl::Get(const std::string& name, int32_t* retvalue)\r
940 {\r
941         if (mOutRow == 0)\r
942                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
943         if (retvalue == 0)\r
944                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
945 \r
946         return mOutRow->Get(name, *retvalue);\r
947 }\r
948 \r
949 bool StatementImpl::Get(const std::string& name, int32_t& retvalue)\r
950 {\r
951         if (mOutRow == 0)\r
952                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
953 \r
954         return mOutRow->Get(name, retvalue);\r
955 }\r
956 \r
957 bool StatementImpl::Get(const std::string& name, int64_t* retvalue)\r
958 {\r
959         if (mOutRow == 0)\r
960                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
961         if (retvalue == 0)\r
962                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
963 \r
964         return mOutRow->Get(name, *retvalue);\r
965 }\r
966 \r
967 bool StatementImpl::Get(const std::string& name, int64_t& retvalue)\r
968 {\r
969         if (mOutRow == 0)\r
970                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
971 \r
972         return mOutRow->Get(name, retvalue);\r
973 }\r
974 \r
975 bool StatementImpl::Get(const std::string& name, float* retvalue)\r
976 {\r
977         if (mOutRow == 0)\r
978                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
979         if (retvalue == 0)\r
980                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
981 \r
982         return mOutRow->Get(name, *retvalue);\r
983 }\r
984 \r
985 bool StatementImpl::Get(const std::string& name, float& retvalue)\r
986 {\r
987         if (mOutRow == 0)\r
988                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
989 \r
990         return mOutRow->Get(name, retvalue);\r
991 }\r
992 \r
993 bool StatementImpl::Get(const std::string& name, double* retvalue)\r
994 {\r
995         if (mOutRow == 0)\r
996                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
997         if (retvalue == 0)\r
998                 throw LogicExceptionImpl("Statement::Get", _("Null pointer detected"));\r
999 \r
1000         return mOutRow->Get(name, *retvalue);\r
1001 }\r
1002 \r
1003 bool StatementImpl::Get(const std::string& name, double& retvalue)\r
1004 {\r
1005         if (mOutRow == 0)\r
1006                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1007 \r
1008         return mOutRow->Get(name, retvalue);\r
1009 }\r
1010 \r
1011 bool StatementImpl::Get(const std::string& name, IBPP::Timestamp& retvalue)\r
1012 {\r
1013         if (mOutRow == 0)\r
1014                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1015 \r
1016         return mOutRow->Get(name, retvalue);\r
1017 }\r
1018 \r
1019 bool StatementImpl::Get(const std::string& name, IBPP::Date& retvalue)\r
1020 {\r
1021         if (mOutRow == 0)\r
1022                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1023 \r
1024         return mOutRow->Get(name, retvalue);\r
1025 }\r
1026 \r
1027 bool StatementImpl::Get(const std::string& name, IBPP::Time& retvalue)\r
1028 {\r
1029         if (mOutRow == 0)\r
1030                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1031 \r
1032         return mOutRow->Get(name, retvalue);\r
1033 }\r
1034 \r
1035 bool StatementImpl::Get(const std::string&name, IBPP::Blob& retblob)\r
1036 {\r
1037         if (mOutRow == 0)\r
1038                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1039 \r
1040         return mOutRow->Get(name, retblob);\r
1041 }\r
1042 \r
1043 bool StatementImpl::Get(const std::string& name, IBPP::DBKey& retvalue)\r
1044 {\r
1045         if (mOutRow == 0)\r
1046                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1047 \r
1048         return mOutRow->Get(name, retvalue);\r
1049 }\r
1050 \r
1051 bool StatementImpl::Get(const std::string& name, IBPP::Array& retarray)\r
1052 {\r
1053         if (mOutRow == 0)\r
1054                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1055 \r
1056         return mOutRow->Get(name, retarray);\r
1057 }\r
1058 \r
1059 /*\r
1060 const IBPP::Value StatementImpl::Get(const std::string& name)\r
1061 {\r
1062         if (mOutRow == 0)\r
1063                 throw LogicExceptionImpl("Statement::Get", _("The row is not initialized."));\r
1064 \r
1065         return mOutRow->Get(name);\r
1066 }\r
1067 */\r
1068 \r
1069 int StatementImpl::Columns()\r
1070 {\r
1071         if (mOutRow == 0)\r
1072                 throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized."));\r
1073 \r
1074         return mOutRow->Columns();\r
1075 }\r
1076 \r
1077 int StatementImpl::ColumnNum(const std::string& name)\r
1078 {\r
1079         if (mOutRow == 0)\r
1080                 throw LogicExceptionImpl("Statement::ColumnNum", _("The row is not initialized."));\r
1081 \r
1082         return mOutRow->ColumnNum(name);\r
1083 }\r
1084 \r
1085 const char* StatementImpl::ColumnName(int varnum)\r
1086 {\r
1087         if (mOutRow == 0)\r
1088                 throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized."));\r
1089 \r
1090         return mOutRow->ColumnName(varnum);\r
1091 }\r
1092 \r
1093 const char* StatementImpl::ColumnAlias(int varnum)\r
1094 {\r
1095         if (mOutRow == 0)\r
1096                 throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized."));\r
1097 \r
1098         return mOutRow->ColumnAlias(varnum);\r
1099 }\r
1100 \r
1101 const char* StatementImpl::ColumnTable(int varnum)\r
1102 {\r
1103         if (mOutRow == 0)\r
1104                 throw LogicExceptionImpl("Statement::Columns", _("The row is not initialized."));\r
1105 \r
1106         return mOutRow->ColumnTable(varnum);\r
1107 }\r
1108 \r
1109 IBPP::SDT StatementImpl::ColumnType(int varnum)\r
1110 {\r
1111         if (mHandle == 0)\r
1112                 throw LogicExceptionImpl("Statement::ColumnType", _("No statement has been prepared."));\r
1113         if (mOutRow == 0)\r
1114                 throw LogicExceptionImpl("Statement::ColumnType", _("The statement does not return results."));\r
1115 \r
1116     return mOutRow->ColumnType(varnum);\r
1117 }\r
1118 \r
1119 int StatementImpl::ColumnSubtype(int varnum)\r
1120 {\r
1121         if (mHandle == 0)\r
1122                 throw LogicExceptionImpl("Statement::ColumnSubtype", _("No statement has been prepared."));\r
1123         if (mOutRow == 0)\r
1124                 throw LogicExceptionImpl("Statement::ColumnSubtype", _("The statement does not return results."));\r
1125 \r
1126     return mOutRow->ColumnSubtype(varnum);\r
1127 }\r
1128 \r
1129 int StatementImpl::ColumnSize(int varnum)\r
1130 {\r
1131         if (mHandle == 0)\r
1132                 throw LogicExceptionImpl("Statement::ColumnSize", _("No statement has been prepared."));\r
1133         if (mOutRow == 0)\r
1134                 throw LogicExceptionImpl("Statement::ColumnSize", _("The row is not initialized."));\r
1135 \r
1136         return mOutRow->ColumnSize(varnum);\r
1137 }\r
1138 \r
1139 int StatementImpl::ColumnScale(int varnum)\r
1140 {\r
1141         if (mHandle == 0)\r
1142                 throw LogicExceptionImpl("Statement::ColumnScale", _("No statement has been prepared."));\r
1143         if (mOutRow == 0)\r
1144                 throw LogicExceptionImpl("Statement::ColumnScale", _("The row is not initialized."));\r
1145 \r
1146         return mOutRow->ColumnScale(varnum);\r
1147 }\r
1148 \r
1149 int StatementImpl::Parameters()\r
1150 {\r
1151         if (mHandle == 0)\r
1152                 throw LogicExceptionImpl("Statement::Parameters", _("No statement has been prepared."));\r
1153         if (mInRow == 0)\r
1154                 throw LogicExceptionImpl("Statement::Parameters", _("The statement uses no parameters."));\r
1155 \r
1156         return mInRow->Columns();\r
1157 }\r
1158 \r
1159 IBPP::SDT StatementImpl::ParameterType(int varnum)\r
1160 {\r
1161         if (mHandle == 0)\r
1162                 throw LogicExceptionImpl("Statement::ParameterType", _("No statement has been prepared."));\r
1163         if (mInRow == 0)\r
1164                 throw LogicExceptionImpl("Statement::ParameterType", _("The statement uses no parameters."));\r
1165 \r
1166     return mInRow->ColumnType(varnum);\r
1167 }\r
1168 \r
1169 int StatementImpl::ParameterSubtype(int varnum)\r
1170 {\r
1171         if (mHandle == 0)\r
1172                 throw LogicExceptionImpl("Statement::ParameterSubtype", _("No statement has been prepared."));\r
1173         if (mInRow == 0)\r
1174                 throw LogicExceptionImpl("Statement::ParameterSubtype", _("The statement uses no parameters."));\r
1175 \r
1176     return mInRow->ColumnSubtype(varnum);\r
1177 }\r
1178 \r
1179 int StatementImpl::ParameterSize(int varnum)\r
1180 {\r
1181         if (mHandle == 0)\r
1182                 throw LogicExceptionImpl("Statement::ParameterSize", _("No statement has been prepared."));\r
1183         if (mInRow == 0)\r
1184                 throw LogicExceptionImpl("Statement::ParameterSize", _("The statement uses no parameters."));\r
1185 \r
1186         return mInRow->ColumnSize(varnum);\r
1187 }\r
1188 \r
1189 int StatementImpl::ParameterScale(int varnum)\r
1190 {\r
1191         if (mHandle == 0)\r
1192                 throw LogicExceptionImpl("Statement::ParameterScale", _("No statement has been prepared."));\r
1193         if (mInRow == 0)\r
1194                 throw LogicExceptionImpl("Statement::ParameterScale", _("The statement uses no parameters."));\r
1195 \r
1196         return mInRow->ColumnScale(varnum);\r
1197 }\r
1198 \r
1199 IBPP::Database StatementImpl::DatabasePtr() const\r
1200 {\r
1201         return mDatabase;\r
1202 }\r
1203 \r
1204 IBPP::Transaction StatementImpl::TransactionPtr() const\r
1205 {\r
1206         return mTransaction;\r
1207 }\r
1208 \r
1209 IBPP::IStatement* StatementImpl::AddRef()\r
1210 {\r
1211         ASSERTION(mRefCount >= 0);\r
1212         ++mRefCount;\r
1213 \r
1214         return this;\r
1215 }\r
1216 \r
1217 void StatementImpl::Release()\r
1218 {\r
1219         // Release cannot throw, except in DEBUG builds on assertion\r
1220         ASSERTION(mRefCount >= 0);\r
1221         --mRefCount;\r
1222         try { if (mRefCount <= 0) delete this; }\r
1223                 catch (...) { }\r
1224 }\r
1225 \r
1226 //      (((((((( OBJECT INTERNAL METHODS ))))))))\r
1227 \r
1228 void StatementImpl::AttachDatabaseImpl(DatabaseImpl* database)\r
1229 {\r
1230         if (database == 0)\r
1231                 throw LogicExceptionImpl("Statement::AttachDatabase",\r
1232                         _("Can't attach a 0 IDatabase object."));\r
1233 \r
1234         if (mDatabase != 0) mDatabase->DetachStatementImpl(this);\r
1235         mDatabase = database;\r
1236         mDatabase->AttachStatementImpl(this);\r
1237 }\r
1238 \r
1239 void StatementImpl::DetachDatabaseImpl()\r
1240 {\r
1241         if (mDatabase == 0) return;\r
1242 \r
1243         Close();\r
1244         mDatabase->DetachStatementImpl(this);\r
1245         mDatabase = 0;\r
1246 }\r
1247 \r
1248 void StatementImpl::AttachTransactionImpl(TransactionImpl* transaction)\r
1249 {\r
1250         if (transaction == 0)\r
1251                 throw LogicExceptionImpl("Statement::AttachTransaction",\r
1252                         _("Can't attach a 0 ITransaction object."));\r
1253 \r
1254         if (mTransaction != 0) mTransaction->DetachStatementImpl(this);\r
1255         mTransaction = transaction;\r
1256         mTransaction->AttachStatementImpl(this);\r
1257 }\r
1258 \r
1259 void StatementImpl::DetachTransactionImpl()\r
1260 {\r
1261         if (mTransaction == 0) return;\r
1262 \r
1263         Close();\r
1264         mTransaction->DetachStatementImpl(this);\r
1265         mTransaction = 0;\r
1266 }\r
1267 \r
1268 void StatementImpl::CursorFree()\r
1269 {\r
1270         if (mCursorOpened)\r
1271         {\r
1272                 mCursorOpened = false;\r
1273                 if (mHandle != 0)\r
1274                 {\r
1275                         IBS status;\r
1276                         (*gds.Call()->m_dsql_free_statement)(status.Self(), &mHandle, DSQL_close);\r
1277                         if (status.Errors())\r
1278                                 throw SQLExceptionImpl(status, "StatementImpl::CursorFree(DSQL_close)",\r
1279                                         _("isc_dsql_free_statement failed."));\r
1280                 }\r
1281         }\r
1282 }\r
1283 \r
1284 StatementImpl::StatementImpl(DatabaseImpl* database, TransactionImpl* transaction,\r
1285         const std::string& sql)\r
1286         : mRefCount(0), mHandle(0), mDatabase(0), mTransaction(0),\r
1287         mInRow(0), mOutRow(0),\r
1288         mResultSetAvailable(false), mCursorOpened(false), mType(IBPP::stUnknown)\r
1289 {\r
1290         AttachDatabaseImpl(database);\r
1291         if (transaction != 0) AttachTransactionImpl(transaction);\r
1292         if (! sql.empty()) Prepare(sql);\r
1293 }\r
1294 \r
1295 StatementImpl::~StatementImpl()\r
1296 {\r
1297         try { Close(); }\r
1298                 catch (...) { }\r
1299         try { if (mTransaction != 0) mTransaction->DetachStatementImpl(this); }\r
1300                 catch (...) { }\r
1301         try { if (mDatabase != 0) mDatabase->DetachStatementImpl(this); }\r
1302                 catch (...) { }\r
1303 }\r
1304 \r
1305 //\r
1306 //      EOF\r
1307 //\r