sqlanywhere 0.1.6-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/ext/sacapidll.o ADDED
Binary file
@@ -0,0 +1,2 @@
1
+ EXPORTS
2
+ Init_sqlanywhere
data/ext/sqlanywhere.c ADDED
@@ -0,0 +1,1753 @@
1
+ /*====================================================
2
+ *
3
+ * Copyright 2008-2010 iAnywhere Solutions, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ *
19
+ * While not a requirement of the license, if you do modify this file, we
20
+ * would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
21
+ *:
22
+ *
23
+ *====================================================*/
24
+ #include "ruby.h"
25
+
26
+ #define _SACAPI_VERSION 2
27
+
28
+ #include "sacapidll.h"
29
+
30
+ #define IS_SACAPI_V2(api) ((api.sqlany_init_ex) != NULL)
31
+
32
+ const char* VERSION = "0.1.6";
33
+
34
+ typedef struct imp_drh_st {
35
+ SQLAnywhereInterface api;
36
+ void *sacapi_context;
37
+ } imp_drh_st;
38
+
39
+ // Defining the Ruby Modules
40
+ static VALUE mSQLAnywhere;
41
+ static VALUE mAPI;
42
+ static VALUE cSQLAnywhereInterface;
43
+
44
+ // Defining binder for DBCAPI types
45
+ static VALUE cA_sqlany_connection;
46
+ static VALUE cA_sqlany_data_value;
47
+ static VALUE cA_sqlany_stmt;
48
+ static VALUE cA_sqlany_bind_param;
49
+ static VALUE cA_sqlany_bind_param_info;
50
+
51
+ // This function is called when the module is first loaded by ruby.
52
+ // The name of this function MUST match be Init_<modulename>.
53
+ void Init_sqlanywhere();
54
+
55
+ // Wrapper functions for the DBICAPI functions
56
+
57
+ static VALUE
58
+ static_API_sqlany_initialize_interface(VALUE module, VALUE imp_drh);
59
+
60
+ static VALUE
61
+ static_API_sqlany_finalize_interface(VALUE module, VALUE imp_drh);
62
+
63
+ static VALUE
64
+ static_SQLAnywhereInterface_alloc(VALUE class);
65
+
66
+ static VALUE
67
+ static_SQLAnywhereInterface_sqlany_init(VALUE class);
68
+
69
+ static VALUE
70
+ static_SQLAnywhereInterface_sqlany_new_connection(VALUE class);
71
+
72
+ static VALUE
73
+ static_SQLAnywhereInterface_sqlany_client_version(VALUE imp_drh);
74
+
75
+ static VALUE
76
+ static_SQLAnywhereInterface_sqlany_connect(VALUE imp_drh, VALUE sqlany_conn, VALUE str);
77
+
78
+ static VALUE
79
+ static_SQLAnywhereInterface_sqlany_disconnect(VALUE imp_drh, VALUE sqlany_conn);
80
+
81
+ static VALUE
82
+ static_SQLAnywhereInterface_sqlany_free_connection(VALUE imp_drh, VALUE sqlany_conn);
83
+
84
+ static VALUE
85
+ static_SQLAnywhereInterface_sqlany_fini(VALUE imp_drh);
86
+
87
+ static VALUE
88
+ static_SQLAnywhereInterface_sqlany_error(VALUE imp_drh, VALUE sqlany_conn);
89
+
90
+ static VALUE
91
+ static_SQLAnywhereInterface_sqlany_execute_immediate(VALUE imp_drh, VALUE sqlany_conn, VALUE sql);
92
+
93
+ static VALUE
94
+ static_SQLAnywhereInterface_sqlany_execute_direct(VALUE imp_drh, VALUE sqlany_conn, VALUE sql);
95
+
96
+ static VALUE
97
+ static_SQLAnywhereInterface_sqlany_num_cols(VALUE imp_drh, VALUE sqlany_stmt);
98
+
99
+ static VALUE
100
+ static_SQLAnywhereInterface_sqlany_num_rows(VALUE imp_drh, VALUE sqlany_stmt);
101
+
102
+ static VALUE
103
+ static_SQLAnywhereInterface_sqlany_get_column(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num);
104
+
105
+ static VALUE
106
+ static_SQLAnywhereInterface_sqlany_fetch_next(VALUE imp_drh, VALUE sqlany_stmt);
107
+
108
+ static VALUE
109
+ static_SQLAnywhereInterface_sqlany_get_column_info(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num);
110
+
111
+ static VALUE
112
+ static_SQLAnywhereInterface_sqlany_commit(VALUE imp_drh, VALUE sqlany_conn);
113
+
114
+ static VALUE
115
+ static_SQLAnywhereInterface_sqlany_rollback(VALUE imp_drh, VALUE sqlany_conn);
116
+
117
+ static VALUE
118
+ static_SQLAnywhereInterface_sqlany_prepare(VALUE imp_drh, VALUE sqlany_conn, VALUE sql);
119
+
120
+ static VALUE
121
+ static_SQLAnywhereInterface_sqlany_free_stmt(VALUE imp_drh, VALUE sqlany_stmt);
122
+
123
+ static VALUE
124
+ static_SQLAnywhereInterface_sqlany_reset(VALUE imp_drh, VALUE sqlany_stmt);
125
+
126
+ static VALUE
127
+ static_SQLAnywhereInterface_sqlany_execute(VALUE imp_drh, VALUE sqlany_stmt);
128
+
129
+ static VALUE
130
+ static_SQLAnywhereInterface_sqlany_affected_rows(VALUE imp_drh, VALUE sqlany_stmt);
131
+
132
+ static VALUE
133
+ static_SQLAnywhereInterface_sqlany_describe_bind_param(VALUE imp_drh, VALUE sqlany_stmt, VALUE index);
134
+
135
+ /*
136
+ * C to Ruby Data conversion function to convert DBCAPI column type into the correct Ruby type
137
+ */
138
+ static VALUE C2RB(a_sqlany_data_value* value)
139
+ {
140
+ VALUE tdata;
141
+
142
+ if( value == NULL || value->buffer == NULL || value->is_null == NULL ) {
143
+ rb_raise(rb_eTypeError, "Operation not allowed. Has no value.");
144
+ }
145
+ else if ( *value->is_null ) {
146
+ tdata = Qnil;
147
+ }
148
+ else {
149
+ switch( value->type ) {
150
+ case A_BINARY:
151
+ tdata = rb_str_new(value->buffer, *value->length);
152
+ break;
153
+ case A_STRING:
154
+ tdata = rb_str_new(value->buffer, *value->length);
155
+ break;
156
+ case A_DOUBLE:
157
+ tdata = rb_float_new(*(double*) value->buffer);
158
+ break;
159
+ case A_VAL64:
160
+ tdata = LL2NUM(*(LONG_LONG*)value->buffer);
161
+ break;
162
+ case A_UVAL64:
163
+ tdata = ULL2NUM(*(unsigned LONG_LONG*)value->buffer);
164
+ break;
165
+ case A_VAL32:
166
+ tdata = INT2NUM(*(int *)value->buffer);
167
+ break;
168
+ case A_UVAL32:
169
+ tdata = UINT2NUM(*(unsigned int *)value->buffer);
170
+ break;
171
+ case A_VAL16:
172
+ tdata = INT2NUM(*(short *)value->buffer);
173
+ break;
174
+ case A_UVAL16:
175
+ tdata = UINT2NUM(*( unsigned short *)value->buffer);
176
+ break;
177
+ case A_VAL8:
178
+ tdata = CHR2FIX(*(unsigned char *)value->buffer);
179
+ break;
180
+ case A_UVAL8:
181
+ tdata = CHR2FIX(*(unsigned char *)value->buffer);
182
+ break;
183
+ default:
184
+ rb_raise(rb_eTypeError, "Invalid Data Type");
185
+ tdata = Qnil;
186
+ break;
187
+ }
188
+ }
189
+
190
+ return tdata;
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * sqlany_initialize_interface(VALUE imp_drh) -> int result
196
+ *
197
+ * Initializes the SQLAnywhereInterface object and loads the DLL dynamically.
198
+ *
199
+ * This function attempts to load the SQL Anywhere C API DLL dynamically and
200
+ * looks up all the entry points of the DLL.
201
+ *
202
+ * <b>Parameters</b>:
203
+ * - <tt>VALUE imp_drh</tt> -- An API structure to initialize.
204
+ *
205
+ * <b>Returns</b>:
206
+ * - <tt>result</tt>: <tt>1</tt> on successful initialization, <tt>0</tt> on failure.
207
+ *
208
+ */
209
+ static VALUE
210
+ static_API_sqlany_initialize_interface(VALUE module, VALUE imp_drh)
211
+ {
212
+ imp_drh_st* s_imp_drh;
213
+ int result;
214
+
215
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
216
+
217
+ result = sqlany_initialize_interface( &(s_imp_drh->api), NULL );
218
+
219
+ return( INT2NUM(result) );
220
+ }
221
+
222
+ /*
223
+ * call-seq:
224
+ * sqlany_finalize_interface(VALUE imp_drh) -> nil
225
+ *
226
+ * Finalize and free resources associated with the SQL Anywhere C API DLL.
227
+ *
228
+ * This function will unload the library and uninitialize the supplied
229
+ * SQLAnywhereInterface structure.
230
+ *
231
+ * <b>Parameters</b>:
232
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
233
+ *
234
+ * <b>Returns</b>:
235
+ * - <tt>nil</tt>.
236
+ *
237
+ */
238
+ static VALUE
239
+ static_API_sqlany_finalize_interface(VALUE module, VALUE imp_drh)
240
+ {
241
+ imp_drh_st* s_imp_drh;
242
+
243
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
244
+
245
+ sqlany_finalize_interface(&(s_imp_drh->api));
246
+
247
+ free(&(s_imp_drh->api));
248
+
249
+ return( Qnil );
250
+ }
251
+
252
+ static VALUE
253
+ static_SQLAnywhereInterface_alloc(VALUE class)
254
+ {
255
+ imp_drh_st *imp_drh = NULL;
256
+ VALUE tdata;
257
+
258
+ imp_drh = malloc( sizeof(imp_drh_st) );
259
+ memset( imp_drh, 0, sizeof(imp_drh_st));
260
+
261
+ tdata = Data_Wrap_Struct(class, 0, 0, imp_drh);
262
+ return tdata;
263
+ }
264
+
265
+ /*
266
+ * call-seq:
267
+ * sqlany_init(VALUE imp_drh) -> [VALUE result, VALUE version]
268
+ *
269
+ * Initializes the interface.
270
+ *
271
+ * <b>Parameters</b>:
272
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
273
+ *
274
+ * <b>Returns</b>:
275
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success, <tt>0</tt> on failure.
276
+ * - <tt>VALUE version</tt>: The maximum API version that is supported.
277
+ *
278
+ */
279
+ static VALUE
280
+ static_SQLAnywhereInterface_sqlany_init(VALUE imp_drh)
281
+ {
282
+ imp_drh_st* s_imp_drh;
283
+ sacapi_bool result;
284
+ sacapi_u32 s_version_available;
285
+ VALUE multi_result;
286
+
287
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
288
+
289
+ multi_result = rb_ary_new();
290
+
291
+ if( &(s_imp_drh->api) == NULL ) {
292
+ rb_ary_push(multi_result, INT2NUM(0));
293
+ rb_ary_push(multi_result, Qnil );
294
+ } else {
295
+ if (IS_SACAPI_V2(s_imp_drh->api)) {
296
+ s_imp_drh->sacapi_context = s_imp_drh->api.sqlany_init_ex("RUBY", SQLANY_API_VERSION_2 , &s_version_available );
297
+ if ( s_imp_drh->sacapi_context == NULL ) {
298
+ rb_ary_push(multi_result, INT2NUM(0));
299
+ }
300
+ else {
301
+ rb_ary_push(multi_result, INT2NUM(1));
302
+ }
303
+ rb_ary_push(multi_result, INT2NUM(s_version_available));
304
+ }
305
+ else {
306
+ result = s_imp_drh->api.sqlany_init("RUBY", SQLANY_API_VERSION_1 , &s_version_available );
307
+ rb_ary_push(multi_result, INT2NUM(result));
308
+ rb_ary_push(multi_result, INT2NUM(s_version_available));
309
+ }
310
+ }
311
+
312
+ return( multi_result );
313
+ }
314
+
315
+ /*
316
+ * call-seq:
317
+ * sqlany_new_connection(VALUE imp_drh) -> VALUE connection
318
+ *
319
+ * Creates a connection object.
320
+ *
321
+ * An API connection object needs to be created before a database connection
322
+ * is established. Errors can be retrieved from the connection object. Only
323
+ * one request can be processed on a connection at a time.
324
+ *
325
+ * <b>Parameters</b>:
326
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
327
+ *
328
+ * <b>Returns</b>:
329
+ * - <tt>VALUE connection</tt>: A connection object.
330
+ *
331
+ */
332
+ static VALUE
333
+ static_SQLAnywhereInterface_sqlany_new_connection(VALUE imp_drh)
334
+ {
335
+ imp_drh_st* s_imp_drh;
336
+ a_sqlany_connection* ptr;
337
+ VALUE tdata;
338
+
339
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
340
+ ptr = s_imp_drh->api.sqlany_new_connection();
341
+
342
+ tdata = Data_Wrap_Struct(cA_sqlany_connection, 0, 0, ptr);
343
+
344
+ return (tdata);
345
+ }
346
+
347
+ /*
348
+ * call-seq:
349
+ * sqlany_client_version(VALUE imp_drh) -> [VALUE verstr]
350
+ *
351
+ * Retrieves the client version as a string.
352
+ *
353
+ * This function can be used to retrieve the client version.
354
+ *
355
+ * <b>Parameters</b>:
356
+ * - <tt>VALUE imp_drh</tt> -- an initialized API structure to finalize
357
+ *
358
+ * <b>Returns</b>:
359
+ * - <tt>VALUE verstr</tt>: The client version string.
360
+ *
361
+ */
362
+
363
+ static VALUE
364
+ static_SQLAnywhereInterface_sqlany_client_version(VALUE imp_drh)
365
+ {
366
+ imp_drh_st* s_imp_drh;
367
+ size_t s_size;
368
+ char s_buffer[255];
369
+
370
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
371
+
372
+ s_imp_drh->api.sqlany_client_version(s_buffer, 255);
373
+
374
+ return (rb_str_new2(s_buffer));
375
+ }
376
+
377
+ /*
378
+ * call-seq:
379
+ * sqlany_connect(VALUE imp_drh, VALUE sqlany_conn, VALUE str) -> VALUE result
380
+ *
381
+ * Creates a connection object.
382
+ *
383
+ * An API connection object needs to be created before a database connection
384
+ * is established. Errors can be retrieved from the connection object. Only
385
+ * one request can be processed on a connection at a time.
386
+ *
387
+ * <b>Parameters</b>:
388
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
389
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was created by sqlany_new_connection().
390
+ * - <tt>VALUE str</tt> -- A SQL Anywhere connection string.
391
+ *
392
+ * <b>Returns</b>:
393
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success, <tt>0</tt> on failure.
394
+ *
395
+ */
396
+ static VALUE
397
+ static_SQLAnywhereInterface_sqlany_connect(VALUE imp_drh, VALUE sqlany_conn, VALUE str)
398
+ {
399
+ imp_drh_st* s_imp_drh;
400
+ a_sqlany_connection* s_sqlany_conn;
401
+ char* s_str;
402
+ sacapi_bool result;
403
+
404
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
405
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
406
+
407
+ s_str = StringValueCStr( str );
408
+
409
+ result = s_imp_drh->api.sqlany_connect( s_sqlany_conn, s_str );
410
+
411
+ return( INT2NUM(result) );
412
+ }
413
+
414
+ /*
415
+ * call-seq:
416
+ * sqlany_disconnect(VALUE imp_drh, VALUE sqlany_conn) -> nil
417
+ *
418
+ * Disconnect an already established connection.
419
+ *
420
+ * This function disconnects a SQL Anywhere connection. Any
421
+ * uncommitted transactions will be rolled back.
422
+ *
423
+ * <b>Parameters</b>:
424
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
425
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
426
+ *
427
+ * <b>Returns</b>:
428
+ * - <tt>nil</tt>.
429
+ *
430
+ */
431
+ static VALUE
432
+ static_SQLAnywhereInterface_sqlany_disconnect(VALUE imp_drh, VALUE sqlany_conn)
433
+ {
434
+ imp_drh_st* s_imp_drh;
435
+ a_sqlany_connection* s_sqlany_conn;
436
+
437
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
438
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
439
+
440
+
441
+ s_imp_drh->api.sqlany_disconnect( s_sqlany_conn );
442
+
443
+ return( Qnil );
444
+ }
445
+
446
+ /*
447
+ * call-seq:
448
+ * sqlany_free_connection(VALUE imp_drh, VALUE sqlany_conn) -> nil
449
+ *
450
+ * Frees the resources associated with a connection object.
451
+ *
452
+ * <b>Parameters</b>:
453
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
454
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was disconnected by sqlany_disconnect().
455
+ *
456
+ * <b>Returns</b>:
457
+ * - <tt>nil</tt>.
458
+ *
459
+ */
460
+ static VALUE
461
+ static_SQLAnywhereInterface_sqlany_free_connection(VALUE imp_drh, VALUE sqlany_conn)
462
+ {
463
+ imp_drh_st* s_imp_drh;
464
+ a_sqlany_connection* s_sqlany_conn;
465
+
466
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
467
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
468
+
469
+
470
+ s_imp_drh->api.sqlany_free_connection( s_sqlany_conn );
471
+
472
+ return( Qnil );
473
+ }
474
+
475
+ /*
476
+ * call-seq:
477
+ * sqlany_fini(VALUE imp_drh) -> nil
478
+ *
479
+ * Finalizes the interface.
480
+ *
481
+ * Thus function frees any resources allocated by the API.
482
+ *
483
+ * <b>Parameters</b>:
484
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
485
+ *
486
+ * <b>Returns</b>:
487
+ * - <tt>nil</tt>.
488
+ *
489
+ */
490
+ static VALUE
491
+ static_SQLAnywhereInterface_sqlany_fini(VALUE imp_drh)
492
+ {
493
+ imp_drh_st* s_imp_drh;
494
+
495
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
496
+
497
+ if( IS_SACAPI_V2(s_imp_drh->api) ) {
498
+ s_imp_drh->api.sqlany_fini_ex(s_imp_drh->sacapi_context);
499
+ s_imp_drh->sacapi_context = NULL;
500
+ }
501
+ else {
502
+ s_imp_drh->api.sqlany_fini();
503
+ }
504
+
505
+ return( Qnil );
506
+ }
507
+
508
+ /*
509
+ * call-seq:
510
+ * sqlany_error(VALUE imp_drh, VALUE sqlany_conn) -> [VALUE result, VALUE errstr]
511
+ *
512
+ * Retrieves the last error code and message.
513
+ *
514
+ * This function can be used to retrieve the last error code and message
515
+ * stored in the connection object.
516
+ *
517
+ * <b>Parameters</b>:
518
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
519
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
520
+ *
521
+ * <b>Returns</b>:
522
+ * - <tt>VALUE result</tt>: The last error code. Positive values are warnings, negative values are errors, and <tt>0</tt> is success.
523
+ * - <tt>VALUE errstr</tt>: The error message corresponding to the error code.
524
+ *
525
+ */
526
+
527
+ static VALUE
528
+ static_SQLAnywhereInterface_sqlany_error(VALUE imp_drh, VALUE sqlany_conn)
529
+ {
530
+ imp_drh_st* s_imp_drh;
531
+ a_sqlany_connection* s_sqlany_conn;
532
+ size_t s_size;
533
+ char s_buffer[255];
534
+ sacapi_i32 result;
535
+ VALUE multi_result;
536
+
537
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
538
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
539
+
540
+ result = s_imp_drh->api.sqlany_error(s_sqlany_conn, s_buffer, 255);
541
+
542
+ multi_result = rb_ary_new();
543
+
544
+ rb_ary_push(multi_result, INT2NUM(result));
545
+ rb_ary_push(multi_result, rb_str_new2(s_buffer));
546
+
547
+ return( multi_result );
548
+ }
549
+
550
+ /*
551
+ * call-seq:
552
+ * sqlany_execute_immediate(VALUE imp_drh, VALUE sqlany_conn, VALUE sql) -> VALUE result
553
+ *
554
+ * Executes a SQL statement immediately without returning a result set.
555
+ *
556
+ * This function executes the specified SQL statement immediately. It is
557
+ * useful for SQL statements that do not return a result set.
558
+ *
559
+ *
560
+ * <b>Parameters</b>:
561
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
562
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
563
+ * - <tt>VALUE sql</tt> -- A SQL query string.
564
+ *
565
+ * <b>Returns</b>:
566
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success, <tt>0</tt> on failure.
567
+ *
568
+ */
569
+ static VALUE
570
+ static_SQLAnywhereInterface_sqlany_execute_immediate(VALUE imp_drh, VALUE sqlany_conn, VALUE sql)
571
+ {
572
+ imp_drh_st* s_imp_drh;
573
+ a_sqlany_connection* s_sqlany_conn;
574
+ char* s_sql;
575
+ sacapi_bool result;
576
+
577
+ s_sql = StringValueCStr( sql );
578
+
579
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
580
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
581
+
582
+ result = s_imp_drh->api.sqlany_execute_immediate(s_sqlany_conn, s_sql);
583
+
584
+ return( INT2NUM(result) );
585
+ }
586
+
587
+ /*
588
+ * call-seq:
589
+ * sqlany_execute_direct(VALUE imp_drh, VALUE sqlany_conn, VALUE sql) -> VALUE resultset
590
+ *
591
+ * Executes a SQL statement and possibly returns a result set.
592
+ *
593
+ * This function executes the SQL statement specified by the string argument.
594
+ * This function is suitable if you want to prepare and then execute a
595
+ * statement, and can be used instead of calling sqlany_prepare() followed
596
+ * by sqlany_execute().
597
+ *
598
+ * This function cannot be used for executing a SQL statement with
599
+ * parameters.
600
+ *
601
+ * <b>Parameters</b>:
602
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
603
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
604
+ * - <tt>VALUE sql</tt> -- A SQL query string.
605
+ *
606
+ * <b>Returns</b>:
607
+ * - <tt>VALUE result</tt>: A query result set if successful, nil if failed.
608
+ *
609
+ */
610
+ static VALUE
611
+ static_SQLAnywhereInterface_sqlany_execute_direct(VALUE imp_drh, VALUE sqlany_conn, VALUE sql)
612
+ {
613
+ imp_drh_st* s_imp_drh;
614
+ a_sqlany_connection* s_sqlany_conn;
615
+ a_sqlany_stmt* resultset = NULL;
616
+ char* s_sql;
617
+ VALUE tdata;
618
+
619
+ s_sql = StringValueCStr( sql );
620
+
621
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
622
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
623
+
624
+ resultset = s_imp_drh->api.sqlany_execute_direct(s_sqlany_conn, s_sql);
625
+
626
+ if (resultset)
627
+ {
628
+ tdata = Data_Wrap_Struct(cA_sqlany_stmt, 0, 0, resultset);
629
+ }
630
+ else
631
+ {
632
+ tdata = Qnil;
633
+ }
634
+
635
+ return (tdata);
636
+ }
637
+
638
+ /*
639
+ * call-seq:
640
+ * sqlany_num_cols(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE num_cols
641
+ *
642
+ * Returns number of columns in the result set.
643
+ *
644
+ * <b>Parameters</b>:
645
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
646
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
647
+ *
648
+ * <b>Returns</b>:
649
+ * - <tt>VALUE num_cols</tt>: The number of columns in the result set or <tt>-1</tt> on a failure.
650
+ *
651
+ */
652
+ static VALUE
653
+ static_SQLAnywhereInterface_sqlany_num_cols(VALUE imp_drh, VALUE sqlany_stmt)
654
+ {
655
+ imp_drh_st* s_imp_drh;
656
+ a_sqlany_stmt* s_stmt;
657
+ sacapi_i32 result;
658
+
659
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
660
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_stmt);
661
+
662
+ result = s_imp_drh->api.sqlany_num_cols(s_stmt);
663
+
664
+ return( INT2NUM(result) );
665
+ }
666
+
667
+ /*
668
+ * call-seq:
669
+ * sqlany_num_rows(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE num_rows
670
+ *
671
+ * Returns number of rows in the result set.
672
+ *
673
+ * By default, this function only returns an estimate. To return an exact
674
+ * count, users must set the ROW_COUNTS option on the connection.
675
+ * Refer to SQL Anywhere documentation for the SQL syntax to set this option.
676
+ *
677
+ * <b>Parameters</b>:
678
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
679
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
680
+ *
681
+ * <b>Returns</b>:
682
+ * - <tt>VALUE num_rows</tt>: The number of rows in the result set or <tt>-1</tt> on a failure.
683
+ *
684
+ */
685
+ static VALUE
686
+ static_SQLAnywhereInterface_sqlany_num_rows(VALUE imp_drh, VALUE sqlany_stmt)
687
+ {
688
+ imp_drh_st* s_imp_drh;
689
+ a_sqlany_stmt* s_stmt;
690
+ sacapi_i32 result;
691
+
692
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
693
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_stmt);
694
+
695
+ result = s_imp_drh->api.sqlany_num_rows(s_stmt);
696
+
697
+ return( INT2NUM(result) );
698
+ }
699
+
700
+ /*
701
+ * call-seq:
702
+ * sqlany_get_column(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num) -> [VALUE result, VALUE column_value]
703
+ *
704
+ * Retrieves the data fetched for the specified column.
705
+ *
706
+ * <b>Parameters</b>:
707
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
708
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
709
+ * - <tt>VALUE col_num</tt> -- The number of the column to be retrieved. A column number is between 0 and sqlany_num_cols() - 1.
710
+ *
711
+ * <b>Returns</b>:
712
+ * - <tt>VALUE column_value</tt>: The value of the column. nil is returned if the value was NULL.
713
+ *
714
+ */
715
+ static VALUE
716
+ static_SQLAnywhereInterface_sqlany_get_column(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num)
717
+ {
718
+ imp_drh_st* s_imp_drh;
719
+ a_sqlany_stmt* s_stmt;
720
+ sacapi_u32 s_col_num;
721
+ a_sqlany_data_value value;
722
+ sacapi_bool result;
723
+ VALUE multi_result;
724
+
725
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
726
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_stmt);
727
+ s_col_num = NUM2INT(col_num);
728
+
729
+ result = s_imp_drh->api.sqlany_get_column(s_stmt, s_col_num, &value );
730
+
731
+ multi_result = rb_ary_new();
732
+ rb_ary_push(multi_result, INT2NUM(result));
733
+
734
+ if( !result ) {
735
+ rb_ary_push(multi_result, Qnil);
736
+ }
737
+ else
738
+ {
739
+ if( *value.is_null )
740
+ {
741
+ rb_ary_push(multi_result, Qnil);
742
+ }
743
+ else
744
+ {
745
+ rb_ary_push(multi_result, C2RB(&value));
746
+ }
747
+ }
748
+
749
+ return( multi_result );
750
+ }
751
+
752
+ /*
753
+ * call-seq:
754
+ * sqlany_fetch_next(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
755
+ *
756
+ * Fetches the next row from the result set.
757
+ *
758
+ * This function fetches the next row from the result set. When the result
759
+ * object is first created, the current row pointer is set to point before
760
+ * the first row (that is, row 0).
761
+ * This function advances the row pointer first and then fetches the data
762
+ * at the new row.
763
+ *
764
+ * <b>Parameters</b>:
765
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
766
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
767
+ *
768
+ * <b>Returns</b>:
769
+ * - <tt>VALUE result</tt>: <tt>1</tt> on successful fetch, <tt>0</tt> otherwise.
770
+ *
771
+ */
772
+ static VALUE
773
+ static_SQLAnywhereInterface_sqlany_fetch_next(VALUE imp_drh, VALUE sqlany_stmt)
774
+ {
775
+ imp_drh_st* s_imp_drh;
776
+ a_sqlany_stmt* s_stmt;
777
+ sacapi_bool result;
778
+
779
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
780
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_stmt);
781
+
782
+ result = s_imp_drh->api.sqlany_fetch_next(s_stmt);
783
+
784
+ return( INT2NUM(result) );
785
+ }
786
+
787
+ /*
788
+ * call-seq:
789
+ * sqlany_get_column_info(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num) -> [VALUE result, VALUE col_num, VALUE name, VALUE type, VALUE max_size]
790
+ *
791
+ * Fetches the next row from the result set.
792
+ *
793
+ * This function fetches the next row from the result set. When the result
794
+ * object is first created, the current row pointer is set to point before
795
+ * the first row (that is, row 0).
796
+ * This function advances the row pointer first and then fetches the data
797
+ * at the new row.
798
+ *
799
+ * <b>Parameters</b>:
800
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
801
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
802
+ * - <tt>VALUE col_num</tt> -- The number of the column to be retrieved. A column number is between 0 and sqlany_num_cols() - 1.
803
+ *
804
+ * <b>Returns</b>:
805
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success. Returns <tt>0</tt> if the column index is out of range, or if the statement does not return a result set.
806
+ * - <tt>VALUE col_num</tt>: The number of the column retrieved.
807
+ * - <tt>VALUE name</tt>: The name of the column.
808
+ * - <tt>VALUE type</tt>: The type of the column data.
809
+ * - <tt>VALUE native_type</tt>: The SQL Anywhere native type of the column data.
810
+ * - <tt>VALUE precision</tt>: The precision of the column.
811
+ * - <tt>VALUE scale</tt>: The scale of the column.
812
+ * - <tt>VALUE max_size</tt>: The maximum size a data value in this column can take.
813
+ * - <tt>VALUE nullable</tt>: The nullability of the column.
814
+ *
815
+ */
816
+ static VALUE
817
+ static_SQLAnywhereInterface_sqlany_get_column_info(VALUE imp_drh, VALUE sqlany_stmt, VALUE col_num)
818
+ {
819
+ imp_drh_st* s_imp_drh;
820
+ a_sqlany_stmt* s_stmt;
821
+ sacapi_u32 s_col_num;
822
+ a_sqlany_column_info info;
823
+ sacapi_bool result;
824
+ VALUE multi_result;
825
+
826
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
827
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_stmt);
828
+ s_col_num = NUM2INT(col_num);
829
+
830
+ result = s_imp_drh->api.sqlany_get_column_info(s_stmt, s_col_num, &info );
831
+
832
+ multi_result = rb_ary_new();
833
+ rb_ary_push(multi_result, INT2NUM(result));
834
+ rb_ary_push(multi_result, col_num );
835
+ rb_ary_push(multi_result, rb_str_new2(info.name));
836
+ rb_ary_push(multi_result, INT2NUM(info.type));
837
+ rb_ary_push(multi_result, INT2NUM(info.native_type));
838
+ rb_ary_push(multi_result, INT2NUM(info.precision));
839
+ rb_ary_push(multi_result, INT2NUM(info.scale));
840
+ rb_ary_push(multi_result, INT2NUM(info.max_size));
841
+ rb_ary_push(multi_result, INT2NUM(info.nullable));
842
+
843
+ return( multi_result );
844
+ }
845
+
846
+ /*
847
+ * call-seq:
848
+ * sqlany_commit(VALUE imp_drh, VALUE sqlany_conn) -> VALUE result
849
+ *
850
+ * Commits the current transaction.
851
+ *
852
+ * <b>Parameters</b>:
853
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
854
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
855
+ *
856
+ * <b>Returns</b>:
857
+ * - <tt>VALUE result</tt>: <tt>1</tt> on successful commit, <tt>0</tt> otherwise.
858
+ *
859
+ */
860
+ static VALUE
861
+ static_SQLAnywhereInterface_sqlany_commit(VALUE imp_drh, VALUE sqlany_conn)
862
+ {
863
+ imp_drh_st* s_imp_drh;
864
+ a_sqlany_connection* s_sqlany_conn;
865
+ sacapi_bool result;
866
+
867
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
868
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
869
+
870
+ result = s_imp_drh->api.sqlany_commit(s_sqlany_conn);
871
+
872
+ return( INT2NUM(result) );
873
+ }
874
+
875
+
876
+ /*
877
+ * call-seq:
878
+ * sqlany_rollback(VALUE imp_drh, VALUE sqlany_conn) -> VALUE result
879
+ *
880
+ * Rolls back the current transaction.
881
+ *
882
+ * <b>Parameters</b>:
883
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
884
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
885
+ *
886
+ * <b>Returns</b>:
887
+ * - <tt>VALUE result</tt>: <tt>1</tt> on successful rollback, <tt>0</tt> otherwise.
888
+ *
889
+ */
890
+ static VALUE
891
+ static_SQLAnywhereInterface_sqlany_rollback(VALUE imp_drh, VALUE sqlany_conn)
892
+ {
893
+ imp_drh_st* s_imp_drh;
894
+ a_sqlany_connection* s_sqlany_conn;
895
+ sacapi_bool result;
896
+
897
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
898
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
899
+
900
+ result = s_imp_drh->api.sqlany_rollback(s_sqlany_conn);
901
+
902
+ return( INT2NUM(result) );
903
+ }
904
+
905
+ /*
906
+ * call-seq:
907
+ * sqlany_prepare(VALUE imp_drh, VALUE sqlany_conn, VALUE sql) -> VALUE stmt
908
+ *
909
+ * Prepares a SQL statement.
910
+ *
911
+ * This function prepares the supplied SQL string. Execution does not
912
+ * happen until sqlany_execute() is called. The returned statement object
913
+ * should be freed using sqlany_free_stmt().
914
+ *
915
+ *
916
+ * <b>Parameters</b>:
917
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
918
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
919
+ * - <tt>VALUE sql</tt> -- SQL query to prepare.
920
+ *
921
+ * <b>Returns</b>:
922
+ * - <tt>VALUE stmt</tt>: A statement object, or nil on failure. The statement object can be used by sqlany_execute() to execute the statement.
923
+ *
924
+ */
925
+ static VALUE
926
+ static_SQLAnywhereInterface_sqlany_prepare(VALUE imp_drh, VALUE sqlany_conn, VALUE sql)
927
+ {
928
+ imp_drh_st* s_imp_drh;
929
+ a_sqlany_connection* s_sqlany_conn;
930
+ a_sqlany_stmt* ptr = NULL;
931
+ char* s_sql;
932
+ int result;
933
+ VALUE tdata;
934
+
935
+ s_sql = StringValueCStr( sql );
936
+
937
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
938
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
939
+
940
+ ptr = s_imp_drh->api.sqlany_prepare(s_sqlany_conn, s_sql);
941
+
942
+ if (ptr)
943
+ {
944
+ tdata = Data_Wrap_Struct(cA_sqlany_stmt, 0, 0, ptr);
945
+ }
946
+ else
947
+ {
948
+ tdata = Qnil;
949
+ }
950
+
951
+ return (tdata);
952
+ }
953
+
954
+ /*
955
+ * call-seq:
956
+ * sqlany_free_stmt(VALUE imp_drh, VALUE sqlany_stmt) -> nil
957
+ *
958
+ * Frees resources associated with a prepared statement object.
959
+ *
960
+ * This function frees the resources associated with a prepared statement
961
+ * object.
962
+ *
963
+ * <b>Parameters</b>:
964
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
965
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
966
+ *
967
+ * <b>Returns</b>:
968
+ * - <tt>nil</tt>.
969
+ *
970
+ */
971
+ static VALUE
972
+ static_SQLAnywhereInterface_sqlany_free_stmt(VALUE imp_drh, VALUE sqlany_stmt)
973
+ {
974
+ imp_drh_st* s_imp_drh;
975
+ a_sqlany_stmt* s_sqlany_stmt;
976
+ int i;
977
+ int number_of_params = 0;
978
+ a_sqlany_bind_param_info bind_info;
979
+
980
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
981
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
982
+
983
+ number_of_params = s_imp_drh->api.sqlany_num_params(s_sqlany_stmt);
984
+
985
+ for (i = 0; i < number_of_params; i++)
986
+ {
987
+ if( s_imp_drh->api.sqlany_get_bind_param_info(s_sqlany_stmt, i, &bind_info) )
988
+ {
989
+ // We don't free bind_info.name as it's not allocated
990
+ // if (bind_info.name) {free (bind_info.name);}
991
+
992
+ if (bind_info.input_value.is_null) {free(bind_info.input_value.is_null); }
993
+ if (bind_info.input_value.length) {free(bind_info.input_value.length); }
994
+ if (bind_info.input_value.buffer) {free(bind_info.input_value.buffer); }
995
+
996
+ if (bind_info.output_value.is_null) {free(bind_info.output_value.is_null); }
997
+ if (bind_info.output_value.length) {free(bind_info.output_value.length); }
998
+ if (bind_info.output_value.buffer) {free(bind_info.output_value.buffer); }
999
+ }
1000
+ }
1001
+
1002
+ s_imp_drh->api.sqlany_free_stmt(s_sqlany_stmt);
1003
+
1004
+ return ( Qnil );
1005
+ }
1006
+
1007
+ /*
1008
+ * call-seq:
1009
+ * sqlany_reset(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
1010
+ *
1011
+ *
1012
+ * <b>Parameters</b>:
1013
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1014
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
1015
+ *
1016
+ * <b>Returns</b>:
1017
+ * - <tt>VALUE result</tt>: <tt>1</tt> on successful execution, <tt>0</tt> otherwise.
1018
+ *
1019
+ */
1020
+ static VALUE
1021
+ static_SQLAnywhereInterface_sqlany_reset(VALUE imp_drh, VALUE sqlany_stmt)
1022
+ {
1023
+ imp_drh_st* s_imp_drh;
1024
+ a_sqlany_stmt* s_sqlany_stmt;
1025
+ sacapi_bool result;
1026
+
1027
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1028
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1029
+
1030
+ result = s_imp_drh->api.sqlany_reset(s_sqlany_stmt);
1031
+
1032
+ return (INT2NUM(result));
1033
+ }
1034
+
1035
+
1036
+ /*
1037
+ * call-seq:
1038
+ * sqlany_execute(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
1039
+ *
1040
+ * Executes a prepared statement.
1041
+ *
1042
+ * <b>Parameters</b>:
1043
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1044
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was created by sqlany_prepare() or sqlany_execute_direct().
1045
+ *
1046
+ * <b>Returns</b>:
1047
+ * - <tt>VALUE result</tt>: <tt>1</tt> on successful execution, <tt>0</tt> otherwise.
1048
+ *
1049
+ */
1050
+ static VALUE
1051
+ static_SQLAnywhereInterface_sqlany_execute(VALUE imp_drh, VALUE sqlany_stmt)
1052
+ {
1053
+ imp_drh_st* s_imp_drh;
1054
+ a_sqlany_stmt* s_sqlany_stmt;
1055
+ sacapi_bool result;
1056
+
1057
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1058
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1059
+
1060
+ result = s_imp_drh->api.sqlany_execute(s_sqlany_stmt);
1061
+
1062
+ return (INT2NUM(result));
1063
+ }
1064
+
1065
+ /*
1066
+ * call-seq:
1067
+ * sqlany_affected_rows(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
1068
+ *
1069
+ * Returns the number of rows affected by execution of the prepared
1070
+ * statement.
1071
+ *
1072
+ * <b>Parameters</b>:
1073
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1074
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement that was prepared and executed successfully with no result set returned.
1075
+ *
1076
+ * <b>Returns</b>:
1077
+ * - <tt>VALUE result</tt>: The number of rows affected or <tt>-1</tt> on failure.
1078
+ *
1079
+ */
1080
+ static VALUE
1081
+ static_SQLAnywhereInterface_sqlany_affected_rows(VALUE imp_drh, VALUE sqlany_stmt)
1082
+ {
1083
+ imp_drh_st* s_imp_drh;
1084
+ a_sqlany_stmt* s_sqlany_stmt;
1085
+ sacapi_i32 result;
1086
+
1087
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1088
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1089
+
1090
+ result = s_imp_drh->api.sqlany_affected_rows(s_sqlany_stmt);
1091
+
1092
+ return ( INT2NUM(result) );
1093
+ }
1094
+
1095
+ /*
1096
+ * call-seq:
1097
+ * sqlany_describe_bind_param(VALUE imp_drh, VALUE sqlany_stmt, VALUE index) -> [VALUE result, VALUE bind_param]
1098
+ *
1099
+ * Describes the bind parameters of a prepared statement.
1100
+ *
1101
+ * This function allows the caller to determine information about parameters
1102
+ * to a prepared statement. Depending on the type of the prepared statement
1103
+ * (call to stored procedure or a DML), only some information will be
1104
+ * provided. The information that will always be provided is the direction
1105
+ * of the parameters (input, output, or input-output).
1106
+ *
1107
+ * <b>Parameters</b>:
1108
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1109
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was returned from sqlany_prepare().
1110
+ * - <tt>VALUE index</tt> -- The index of the parameter. This should be a number between 0 and sqlany_num_params()- 1.
1111
+ *
1112
+ * <b>Returns</b>:
1113
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success or <tt>0</tt> on failure.
1114
+ * - <tt>VALUE bind_param</tt>: The described param object.
1115
+ *
1116
+ */
1117
+ static VALUE
1118
+ static_SQLAnywhereInterface_sqlany_describe_bind_param(VALUE imp_drh, VALUE sqlany_stmt, VALUE index)
1119
+ {
1120
+ imp_drh_st* s_imp_drh;
1121
+ a_sqlany_stmt* s_sqlany_stmt;
1122
+ a_sqlany_bind_param* s_sqlany_bind_param;
1123
+ sacapi_bool result;
1124
+ sacapi_u32 s_index;
1125
+ VALUE tdata;
1126
+ VALUE multi_result;
1127
+
1128
+ s_sqlany_bind_param = malloc(sizeof(a_sqlany_bind_param));
1129
+ memset( s_sqlany_bind_param, 0, sizeof(a_sqlany_bind_param) );
1130
+
1131
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1132
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1133
+ s_index = NUM2INT(index);
1134
+
1135
+ result = s_imp_drh->api.sqlany_describe_bind_param(s_sqlany_stmt, s_index, s_sqlany_bind_param);
1136
+
1137
+ //FIXME handle failed result
1138
+
1139
+ multi_result = rb_ary_new();
1140
+
1141
+ rb_ary_push(multi_result, INT2NUM(result));
1142
+
1143
+ tdata = Data_Wrap_Struct(cA_sqlany_bind_param, 0, 0, s_sqlany_bind_param);
1144
+ rb_ary_push(multi_result, tdata);
1145
+
1146
+ return( multi_result );
1147
+ }
1148
+
1149
+ /*
1150
+ * call-seq:
1151
+ * sqlany_bind_param(VALUE imp_drh, VALUE sqlany_stmt, VALUE index, VALUE sqlany_bind_param) -> VALUE result
1152
+ *
1153
+ * Binds a user supplied buffer as a parameter to the prepared statement.
1154
+ *
1155
+ * <b>Parameters</b>:
1156
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1157
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was returned from sqlany_prepare().
1158
+ * - <tt>VALUE index</tt> -- The index of the parameter. This should be a number between 0 and sqlany_num_params() - 1.
1159
+ * - <tt>VALUE sqlany_bind_param</tt> -- A filled bind object retrieved from sqlany_describe_bind_param().
1160
+ *
1161
+ * <b>Returns</b>:
1162
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success or <tt>0</tt> on failure.
1163
+ *
1164
+ */
1165
+ static VALUE
1166
+ static_SQLAnywhereInterface_sqlany_bind_param(VALUE imp_drh, VALUE sqlany_stmt, VALUE index, VALUE sqlany_bind_param )
1167
+ {
1168
+ imp_drh_st* s_imp_drh;
1169
+ a_sqlany_stmt* s_sqlany_stmt;
1170
+ a_sqlany_bind_param* s_sqlany_bind_param;
1171
+ sacapi_bool result;
1172
+ sacapi_u32 s_index;
1173
+
1174
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1175
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1176
+ Data_Get_Struct(sqlany_bind_param, a_sqlany_bind_param, s_sqlany_bind_param);
1177
+ s_index = NUM2INT(index);
1178
+
1179
+ result = s_imp_drh->api.sqlany_bind_param(s_sqlany_stmt, s_index, s_sqlany_bind_param);
1180
+
1181
+ return( INT2NUM(result) );
1182
+ }
1183
+
1184
+ /*
1185
+ * call-seq:
1186
+ * sqlany_get_bind_param_info(VALUE imp_drh, VALUE sqlany_stmt, VALUE index) -> [VALUE result, VALUE bind_param]
1187
+ *
1188
+ * Gets bound parameter info.
1189
+ *
1190
+ * This function retrieves information about the parameters that were
1191
+ * bound using sqlany_bind_param().
1192
+ *
1193
+ * <b>Parameters</b>:
1194
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1195
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was returned from sqlany_prepare().
1196
+ * - <tt>VALUE index</tt> -- The index of the parameter. This should be a number between 0 and sqlany_num_params() - 1.
1197
+ *
1198
+ * <b>Returns</b>:
1199
+ * - <tt>VALUE result</tt>: <tt>1</tt> on success or <tt>0</tt> on failure.
1200
+ * - <tt>VALUE bind_param</tt>: The described param object.
1201
+ *
1202
+ */
1203
+ static VALUE
1204
+ static_SQLAnywhereInterface_sqlany_get_bind_param_info(VALUE imp_drh, VALUE sqlany_stmt, VALUE index)
1205
+ {
1206
+ imp_drh_st* s_imp_drh;
1207
+ a_sqlany_stmt* s_sqlany_stmt;
1208
+ a_sqlany_bind_param_info s_sqlany_bind_param_info;
1209
+ sacapi_bool result;
1210
+ sacapi_u32 s_index;
1211
+ VALUE tdata;
1212
+ VALUE multi_result;
1213
+
1214
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1215
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1216
+ s_index = NUM2INT(index);
1217
+
1218
+ result = s_imp_drh->api.sqlany_get_bind_param_info(s_sqlany_stmt, s_index, &s_sqlany_bind_param_info);
1219
+
1220
+ //FIXME handle failed result
1221
+ multi_result = rb_ary_new();
1222
+
1223
+ rb_ary_push(multi_result, INT2NUM(result));
1224
+
1225
+ // FIXME: Is this safe to be on the stack?
1226
+ tdata = Data_Wrap_Struct(cA_sqlany_bind_param_info, 0, 0, &s_sqlany_bind_param_info);
1227
+ rb_ary_push(multi_result, tdata);
1228
+
1229
+ return( multi_result );
1230
+ }
1231
+
1232
+ /*
1233
+ * call-seq:
1234
+ * sqlany_num_params(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
1235
+ *
1236
+ * Returns the number of parameters that are expected for a prepared
1237
+ * statement.
1238
+ *
1239
+ * This function retrieves information about the parameters that were bound
1240
+ * using sqlany_bind_param().
1241
+ *
1242
+ * <b>Parameters</b>:
1243
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1244
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was returned from sqlany_prepare().
1245
+ *
1246
+ * <b>Returns</b>:
1247
+ * - <tt>VALUE result</tt>: The number of parameters that are expected. <tt>-1</tt> if the sqlany_stmt object is not valid.
1248
+ *
1249
+ */
1250
+ static VALUE
1251
+ static_SQLAnywhereInterface_sqlany_num_params(VALUE imp_drh, VALUE sqlany_stmt)
1252
+ {
1253
+ imp_drh_st* s_imp_drh;
1254
+ a_sqlany_stmt* s_sqlany_stmt;
1255
+ sacapi_i32 result;
1256
+
1257
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1258
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1259
+
1260
+ result = s_imp_drh->api.sqlany_num_params(s_sqlany_stmt);
1261
+
1262
+ return( INT2NUM(result) );
1263
+ }
1264
+
1265
+ /*
1266
+ * call-seq:
1267
+ * sqlany_get_next_result(VALUE imp_drh, VALUE sqlany_stmt) -> VALUE result
1268
+ *
1269
+ * Advances to the next result set in a multiple result set query.
1270
+ *
1271
+ * If a query (such as a call to a stored procedure) returns multiple result
1272
+ * sets, then this function advances from the current result set to the next.
1273
+ *
1274
+ *
1275
+ * <b>Parameters</b>:
1276
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1277
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was executed by sqlany_execute() or sqlany_execute_direct().
1278
+ *
1279
+ * <b>Returns</b>:
1280
+ * - <tt>VALUE result</tt>: <tt>1</tt> if was successfully able to advance to the next result set, <tt>0</tt> otherwise.
1281
+ *
1282
+ */
1283
+ static VALUE
1284
+ static_SQLAnywhereInterface_sqlany_get_next_result(VALUE imp_drh, VALUE sqlany_stmt)
1285
+ {
1286
+ imp_drh_st* s_imp_drh;
1287
+ a_sqlany_stmt* s_sqlany_stmt;
1288
+ sacapi_bool result;
1289
+
1290
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1291
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1292
+
1293
+ result = s_imp_drh->api.sqlany_get_next_result(s_sqlany_stmt);
1294
+
1295
+ return( INT2NUM(result) );
1296
+ }
1297
+
1298
+ /*
1299
+ * call-seq:
1300
+ * sqlany_fetch_absolute(VALUE imp_drh, VALUE sqlany_stmt, VALUE offset) -> VALUE result
1301
+ *
1302
+ * Fetches data at a specific row number in the result set.
1303
+ *
1304
+ * This function moves the current row in the result set to the row number
1305
+ * specified and fetches the data at that row.
1306
+ *
1307
+ * <b>Parameters</b>:
1308
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1309
+ * - <tt>VALUE sqlany_stmt</tt> -- A statement object that was executed by sqlany_execute() or sqlany_execute_direct().
1310
+ * - <tt>VALUE offset</tt> -- The row number to be fetched. The first row is <tt>1</tt>, the last row is <tt>-1</tt>.
1311
+ *
1312
+ * <b>Returns</b>:
1313
+ * - <tt>VALUE result</tt>: <tt>1</tt> if the fetch was successfully, <tt>0</tt> otherwise.
1314
+ *
1315
+ */
1316
+ static VALUE
1317
+ static_SQLAnywhereInterface_sqlany_fetch_absolute(VALUE imp_drh, VALUE sqlany_stmt, VALUE offset)
1318
+ {
1319
+ imp_drh_st* s_imp_drh;
1320
+ a_sqlany_stmt* s_sqlany_stmt;
1321
+ sacapi_i32 s_offset;
1322
+ sacapi_bool result;
1323
+
1324
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1325
+ Data_Get_Struct(sqlany_stmt, a_sqlany_stmt, s_sqlany_stmt);
1326
+ s_offset = NUM2INT(offset);
1327
+ result = s_imp_drh->api.sqlany_fetch_absolute(s_sqlany_stmt, s_offset);
1328
+
1329
+ return( INT2NUM(result) );
1330
+ }
1331
+
1332
+ /*
1333
+ * call-seq:
1334
+ * sqlany_sqlstate(VALUE imp_drh, VALUE sqlany_conn) -> VALUE sqlstate_str
1335
+ *
1336
+ * Retrieves the current SQL state.
1337
+ *
1338
+ * <b>Parameters</b>:
1339
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1340
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
1341
+ *
1342
+ * <b>Returns</b>:
1343
+ * - <tt>VALUE sqlstate_str</tt>: The SQL State.
1344
+ *
1345
+ */
1346
+ static VALUE
1347
+ static_SQLAnywhereInterface_sqlany_sqlstate(VALUE imp_drh, VALUE sqlany_conn)
1348
+ {
1349
+ imp_drh_st* s_imp_drh;
1350
+ a_sqlany_connection* s_sqlany_conn;
1351
+ size_t s_size;
1352
+ char s_buffer[255];
1353
+
1354
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1355
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
1356
+
1357
+ s_size = s_imp_drh->api.sqlany_sqlstate(s_sqlany_conn, s_buffer, sizeof(s_buffer));
1358
+
1359
+ return( rb_str_new(s_buffer, s_size));
1360
+ }
1361
+
1362
+ /*
1363
+ * call-seq:
1364
+ * sqlany_clear_error(VALUE imp_drh, VALUE sqlany_conn) -> nil
1365
+ *
1366
+ * Clears the last stored error code.
1367
+ *
1368
+ * <b>Parameters</b>:
1369
+ * - <tt>VALUE imp_drh</tt> -- An initialized API structure to finalize.
1370
+ * - <tt>VALUE sqlany_conn</tt> -- A connection object that was connected by sqlany_connect().
1371
+ *
1372
+ * <b>Returns</b>:
1373
+ * - <tt>nil</tt>:.
1374
+ *
1375
+ */
1376
+ static VALUE
1377
+ static_SQLAnywhereInterface_sqlany_clear_error(VALUE imp_drh, VALUE sqlany_conn)
1378
+ {
1379
+ imp_drh_st* s_imp_drh;
1380
+ a_sqlany_connection* s_sqlany_conn;
1381
+
1382
+ Data_Get_Struct(imp_drh, imp_drh_st, s_imp_drh);
1383
+ Data_Get_Struct(sqlany_conn, a_sqlany_connection, s_sqlany_conn);
1384
+
1385
+ s_imp_drh->api.sqlany_clear_error(s_sqlany_conn);
1386
+
1387
+ return( Qnil );
1388
+ }
1389
+
1390
+ /*
1391
+ * call-seq:
1392
+ * get_name(VALUE bind) -> VALUE name
1393
+ *
1394
+ * Gets the name of the bound parameter.
1395
+ *
1396
+ * <b>Parameters</b>:
1397
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1398
+ *
1399
+ * <b>Returns</b>:
1400
+ * - <tt>VALUE name</tt>: The bound variable's name.
1401
+ *
1402
+ */
1403
+ static VALUE
1404
+ static_Bind_get_name(VALUE bind)
1405
+ {
1406
+ a_sqlany_bind_param* s_bind;
1407
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1408
+ return (rb_str_new2(s_bind->name));
1409
+ }
1410
+
1411
+ /*
1412
+ * call-seq:
1413
+ * set_value(VALUE bind, VALUE val) -> nil
1414
+ *
1415
+ * Sets the value of a bind parameter.
1416
+ *
1417
+ * This function is used to bind a Ruby VALUE to a given parameter in a
1418
+ * prepared statement. If the bind_direction is INPUT only, the type INPUT
1419
+ * will be bound based on the RUBY type:
1420
+ *
1421
+ * +-------------+------------+
1422
+ * | Ruby Type | Bind Type |
1423
+ * +-------------+------------+
1424
+ * | T_STRING => A_STRING |
1425
+ * | T_FIXNUM => A_VAL_32 |
1426
+ * | T_BIGNUM => A_DOUBLE |
1427
+ * | T_FLOAT => A_DOUBLE |
1428
+ * | T_STRING => A_STRING |
1429
+ * | T_NIL => isnull = 1 |
1430
+ * +--------------------------+
1431
+ *
1432
+ * If the bind direction is OUTPUT, instead use the DBCAPI type to set the
1433
+ * size of the buffer.
1434
+ *
1435
+ * In the case of INOUT parameters, it is the application's job to call this
1436
+ * method twice, once to bind the INPUT, and once to bind the OUTPUT.
1437
+ *
1438
+ * <b>Parameters</b>:
1439
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1440
+ * - <tt>VALUE val</tt> -- The value to bind into the bound variable.
1441
+ *
1442
+ * <b>Returns</b>:
1443
+ * - <tt>nil</tt>.
1444
+ */
1445
+ static VALUE
1446
+ static_Bind_set_value(VALUE bind, VALUE val)
1447
+ {
1448
+ a_sqlany_bind_param* s_bind;
1449
+ int length;
1450
+
1451
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1452
+
1453
+ // FIXME: use Ruby's allocation routines?
1454
+ s_bind->value.is_null = malloc(sizeof(sacapi_bool));
1455
+ *s_bind->value.is_null = 0;
1456
+
1457
+ if (s_bind->direction == DD_INPUT)
1458
+ {
1459
+ switch(TYPE(val))
1460
+ {
1461
+ case T_STRING:
1462
+ s_bind->value.length = malloc(sizeof(size_t));
1463
+ length = RSTRING_LEN(val);
1464
+ *s_bind->value.length = length;
1465
+ s_bind->value.buffer = malloc(length);
1466
+ memcpy(s_bind->value.buffer, RSTRING_PTR(val), length);
1467
+ s_bind->value.type = A_STRING;
1468
+ break;
1469
+ case T_FIXNUM:
1470
+ if(sizeof(void*) == 4){ //32-bit
1471
+ s_bind->value.buffer = malloc(sizeof(int));
1472
+ *((int*)s_bind->value.buffer) = FIX2INT(val);
1473
+ s_bind->value.type = A_VAL32;
1474
+ }else{ //64-bit
1475
+ s_bind->value.buffer = malloc(sizeof(long));
1476
+ *((long*)s_bind->value.buffer) = FIX2LONG(val);
1477
+ s_bind->value.type = A_VAL64;
1478
+ }
1479
+ break;
1480
+ case T_BIGNUM:
1481
+ s_bind->value.buffer = malloc(sizeof(LONG_LONG));
1482
+ *((LONG_LONG*)s_bind->value.buffer) = rb_num2ll(val);
1483
+ s_bind->value.type = A_VAL64;
1484
+ break;
1485
+ case T_FLOAT:
1486
+ s_bind->value.buffer = malloc(sizeof(double));
1487
+ *((double*)s_bind->value.buffer) = NUM2DBL(val);
1488
+ s_bind->value.type = A_DOUBLE;
1489
+ break;
1490
+ case T_NIL:
1491
+ *s_bind->value.is_null = 1;
1492
+ s_bind->value.buffer = malloc(sizeof(int));
1493
+ s_bind->value.type = A_VAL32;
1494
+ break;
1495
+ default:
1496
+ rb_raise(rb_eTypeError, "Cannot convert type. Must be STRING, FIXNUM, BIGNUM, FLOAT, or NIL");
1497
+ break;
1498
+ }
1499
+ }
1500
+ else
1501
+ {
1502
+ switch (s_bind->value.type)
1503
+ {
1504
+ case A_STRING:
1505
+ s_bind->value.buffer = malloc(s_bind->value.buffer_size);
1506
+ break;
1507
+ case A_DOUBLE:
1508
+ s_bind->value.buffer = malloc(sizeof(float));
1509
+ break;
1510
+ case A_VAL64:
1511
+ case A_UVAL64:
1512
+ s_bind->value.buffer = malloc(sizeof(LONG_LONG));
1513
+ break;
1514
+ case A_VAL32:
1515
+ case A_UVAL32:
1516
+ s_bind->value.buffer = malloc(sizeof(int));
1517
+ break;
1518
+ case A_VAL16:
1519
+ case A_UVAL16:
1520
+ s_bind->value.buffer = malloc(sizeof(short));
1521
+ break;
1522
+ case A_VAL8:
1523
+ case A_UVAL8:
1524
+ s_bind->value.buffer = malloc(sizeof(char));
1525
+ break;
1526
+ default:
1527
+ rb_raise(rb_eTypeError, "Type unknown");
1528
+ break;
1529
+ }
1530
+ }
1531
+ return (Qnil);
1532
+ }
1533
+
1534
+ /*
1535
+ * call-seq:
1536
+ * set_direction(VALUE bind, VALUE direction) -> nil
1537
+ *
1538
+ * Sets the direction of the bound parameter before binding.
1539
+ *
1540
+ * <b>Parameters</b>:
1541
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1542
+ * - <tt>VALUE direction</tt> -- The direction of the binding variable.
1543
+ *
1544
+ * <b>Returns</b>:
1545
+ * - <tt>nil</tt>.
1546
+ *
1547
+ */
1548
+ static VALUE
1549
+ static_Bind_set_direction(VALUE bind, VALUE direction)
1550
+ {
1551
+ a_sqlany_bind_param* s_bind;
1552
+
1553
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1554
+
1555
+ s_bind->direction = NUM2CHR(direction);
1556
+
1557
+ return (Qnil);
1558
+ }
1559
+
1560
+ /*
1561
+ * call-seq:
1562
+ * set_buffer_size(VALUE bind, VALUE size) -> nil
1563
+ *
1564
+ * Sets the buffer size of INOUT and OUT parameters for string and binary
1565
+ * data.
1566
+ *
1567
+ * <b>Parameters</b>:
1568
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1569
+ * - <tt>VALUE size</tt> -- The size of the buffer to hold the INOUT or OUT parameter.
1570
+ *
1571
+ * <b>Returns</b>:
1572
+ * - <tt>nil</tt>.
1573
+ *
1574
+ */
1575
+ static VALUE
1576
+ static_Bind_set_buffer_size(VALUE bind, VALUE size)
1577
+ {
1578
+ a_sqlany_bind_param* s_bind;
1579
+
1580
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1581
+
1582
+ s_bind->value.buffer_size = NUM2INT(size);
1583
+
1584
+ return (Qnil);
1585
+ }
1586
+
1587
+ /*
1588
+ * call-seq:
1589
+ * get_direction(VALUE bind) -> VALUE direction
1590
+ *
1591
+ * Gets the direction of the bound parameter.
1592
+ *
1593
+ * <b>Parameters</b>:
1594
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1595
+ *
1596
+ * <b>Returns</b>:
1597
+ * - <tt>VALUE name</tt>: The direction of the bound parameter.
1598
+ *
1599
+ */
1600
+ static VALUE
1601
+ static_Bind_get_direction(VALUE bind)
1602
+ {
1603
+ a_sqlany_bind_param* s_bind;
1604
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1605
+
1606
+ return (CHR2FIX(s_bind->direction));
1607
+ }
1608
+
1609
+ /*
1610
+ * call-seq:
1611
+ * finish(VALUE bind) -> nil
1612
+ *
1613
+ * Frees the resources associated with the bound parameter.
1614
+ *
1615
+ * <b>Parameters</b>:
1616
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1617
+ *
1618
+ * <b>Returns</b>:
1619
+ * - <tt>nil</tt>.
1620
+ *
1621
+ */
1622
+ static VALUE
1623
+ static_Bind_finish(VALUE bind)
1624
+ {
1625
+ a_sqlany_bind_param* s_bind;
1626
+
1627
+ Data_Get_Struct(bind, a_sqlany_bind_param, s_bind);
1628
+
1629
+ // FIXME: use Ruby's allocation routines?
1630
+ if (s_bind) { free(s_bind);};
1631
+
1632
+ return (Qnil);
1633
+ }
1634
+
1635
+ /*
1636
+ * call-seq:
1637
+ * get_info_direction(VALUE bind) -> VALUE direction
1638
+ *
1639
+ * Gets the name of the bound parameter info object.
1640
+ *
1641
+ * <b>Parameters</b>:
1642
+ * - <tt>VALUE bind</tt> -- Bound parameter info retrieved from sqlany_describe_bind_param_info().
1643
+ *
1644
+ * <b>Returns</b>:
1645
+ * - <tt>VALUE direction</tt>: The bound variable's direction.
1646
+ *
1647
+ */
1648
+ static VALUE
1649
+ static_Bind_get_info_direction(VALUE bind)
1650
+ {
1651
+ a_sqlany_bind_param_info* s_bind;
1652
+ Data_Get_Struct(bind, a_sqlany_bind_param_info, s_bind);
1653
+
1654
+ return (CHR2FIX(s_bind->direction));
1655
+ }
1656
+
1657
+ /*
1658
+ * call-seq:
1659
+ * get_info_output(VALUE bind) -> VALUE name
1660
+ *
1661
+ * Gets the value of a bound parameter after execution.
1662
+ *
1663
+ * <b>Parameters</b>:
1664
+ * - <tt>VALUE bind</tt> -- Bound parameter retrieved from sqlany_describe_bind_param().
1665
+ *
1666
+ * <b>Returns</b>:
1667
+ * - <tt>VALUE name</tt>: The bound variable value.
1668
+ *
1669
+ */
1670
+ static VALUE
1671
+ static_Bind_get_info_output(VALUE bind)
1672
+ {
1673
+ a_sqlany_bind_param_info* s_bind;
1674
+ Data_Get_Struct(bind, a_sqlany_bind_param_info, s_bind);
1675
+ return(C2RB(&s_bind->output_value));
1676
+ }
1677
+
1678
+ /*
1679
+ *
1680
+ */
1681
+ void Init_sqlanywhere()
1682
+ {
1683
+ // Define top leve 'SQLAnywhere' module
1684
+ mSQLAnywhere = rb_define_module( "SQLAnywhere" );
1685
+
1686
+ // Define a sub-module name 'API' under SQLAnywhere.
1687
+ // In Ruby, this is accessed as SQLAnywhere::API
1688
+ mAPI = rb_define_module_under( mSQLAnywhere, "API" );
1689
+
1690
+ // Define sqlany interface functions
1691
+ rb_define_module_function( mAPI, "sqlany_initialize_interface", static_API_sqlany_initialize_interface, 1 );
1692
+ rb_define_module_function( mAPI, "sqlany_finalize_interface", static_API_sqlany_finalize_interface, 1 );
1693
+ rb_define_const(mAPI, "VERSION", rb_str_new2(VERSION));
1694
+
1695
+
1696
+ // Define interface classes under the SQLAnywhere module
1697
+ cSQLAnywhereInterface = rb_define_class_under( mSQLAnywhere, "SQLAnywhereInterface", rb_cObject);
1698
+ rb_define_alloc_func(cSQLAnywhereInterface, static_SQLAnywhereInterface_alloc);
1699
+
1700
+ // Define all of the DBCAPI functions as methods under an interface instance
1701
+ rb_define_method(cSQLAnywhereInterface, "sqlany_init", static_SQLAnywhereInterface_sqlany_init, 0);
1702
+ rb_define_method(cSQLAnywhereInterface, "sqlany_new_connection", static_SQLAnywhereInterface_sqlany_new_connection, 0);
1703
+ rb_define_method(cSQLAnywhereInterface, "sqlany_client_version", static_SQLAnywhereInterface_sqlany_client_version, 0);
1704
+ rb_define_method(cSQLAnywhereInterface, "sqlany_connect", static_SQLAnywhereInterface_sqlany_connect, 2);
1705
+ rb_define_method(cSQLAnywhereInterface, "sqlany_disconnect", static_SQLAnywhereInterface_sqlany_disconnect, 1);
1706
+ rb_define_method(cSQLAnywhereInterface, "sqlany_free_connection", static_SQLAnywhereInterface_sqlany_free_connection, 1);
1707
+ rb_define_method(cSQLAnywhereInterface, "sqlany_fini", static_SQLAnywhereInterface_sqlany_fini, 0);
1708
+ rb_define_method(cSQLAnywhereInterface, "sqlany_error", static_SQLAnywhereInterface_sqlany_error, 1);
1709
+ rb_define_method(cSQLAnywhereInterface, "sqlany_execute_immediate", static_SQLAnywhereInterface_sqlany_execute_immediate, 2);
1710
+ rb_define_method(cSQLAnywhereInterface, "sqlany_execute_direct", static_SQLAnywhereInterface_sqlany_execute_direct, 2);
1711
+ rb_define_method(cSQLAnywhereInterface, "sqlany_num_cols", static_SQLAnywhereInterface_sqlany_num_cols, 1);
1712
+ rb_define_method(cSQLAnywhereInterface, "sqlany_num_rows", static_SQLAnywhereInterface_sqlany_num_rows, 1);
1713
+ rb_define_method(cSQLAnywhereInterface, "sqlany_get_column", static_SQLAnywhereInterface_sqlany_get_column, 2);
1714
+ rb_define_method(cSQLAnywhereInterface, "sqlany_fetch_next", static_SQLAnywhereInterface_sqlany_fetch_next, 1);
1715
+ rb_define_method(cSQLAnywhereInterface, "sqlany_get_column_info", static_SQLAnywhereInterface_sqlany_get_column_info, 2);
1716
+ rb_define_method(cSQLAnywhereInterface, "sqlany_commit", static_SQLAnywhereInterface_sqlany_commit, 1);
1717
+ rb_define_method(cSQLAnywhereInterface, "sqlany_rollback", static_SQLAnywhereInterface_sqlany_rollback, 1);
1718
+ rb_define_method(cSQLAnywhereInterface, "sqlany_prepare", static_SQLAnywhereInterface_sqlany_prepare, 2);
1719
+ rb_define_method(cSQLAnywhereInterface, "sqlany_free_stmt", static_SQLAnywhereInterface_sqlany_free_stmt, 1);
1720
+ rb_define_method(cSQLAnywhereInterface, "sqlany_reset", static_SQLAnywhereInterface_sqlany_reset, 1);
1721
+ rb_define_method(cSQLAnywhereInterface, "sqlany_execute", static_SQLAnywhereInterface_sqlany_execute, 1);
1722
+ rb_define_method(cSQLAnywhereInterface, "sqlany_affected_rows", static_SQLAnywhereInterface_sqlany_affected_rows, 1);
1723
+ rb_define_method(cSQLAnywhereInterface, "sqlany_describe_bind_param", static_SQLAnywhereInterface_sqlany_describe_bind_param, 2);
1724
+ rb_define_method(cSQLAnywhereInterface, "sqlany_bind_param", static_SQLAnywhereInterface_sqlany_bind_param, 3);
1725
+ rb_define_method(cSQLAnywhereInterface, "sqlany_get_bind_param_info", static_SQLAnywhereInterface_sqlany_get_bind_param_info, 2);
1726
+ rb_define_method(cSQLAnywhereInterface, "sqlany_num_params", static_SQLAnywhereInterface_sqlany_num_params, 1);
1727
+ rb_define_method(cSQLAnywhereInterface, "sqlany_get_next_result", static_SQLAnywhereInterface_sqlany_get_next_result, 1);
1728
+ rb_define_method(cSQLAnywhereInterface, "sqlany_fetch_absolute", static_SQLAnywhereInterface_sqlany_fetch_absolute, 2);
1729
+ rb_define_method(cSQLAnywhereInterface, "sqlany_sqlstate", static_SQLAnywhereInterface_sqlany_sqlstate, 1);
1730
+ rb_define_method(cSQLAnywhereInterface, "sqlany_clear_error", static_SQLAnywhereInterface_sqlany_clear_error, 1);
1731
+
1732
+ // Define classes for accessing structures under SQLAnywhere module
1733
+ cA_sqlany_connection = rb_define_class_under (mSQLAnywhere, "a_sqlany_connection", rb_cObject);
1734
+ cA_sqlany_data_value = rb_define_class_under (mSQLAnywhere, "a_sqlany_data_value", rb_cObject);
1735
+ cA_sqlany_stmt = rb_define_class_under (mSQLAnywhere, "a_sqlany_stmt", rb_cObject);
1736
+ cA_sqlany_bind_param = rb_define_class_under (mSQLAnywhere, "a_sqlany_bind_param", rb_cObject);
1737
+ cA_sqlany_bind_param_info = rb_define_class_under (mSQLAnywhere, "a_sqlany_bind_param_info", rb_cObject);
1738
+
1739
+
1740
+ // Define methods for obtaining bind_parameter fields
1741
+ rb_define_method(cA_sqlany_bind_param, "get_name", static_Bind_get_name, 0);
1742
+ rb_define_method(cA_sqlany_bind_param, "set_value", static_Bind_set_value, 1);
1743
+ rb_define_method(cA_sqlany_bind_param, "get_direction", static_Bind_get_direction, 0);
1744
+ rb_define_method(cA_sqlany_bind_param, "set_direction", static_Bind_set_direction, 1);
1745
+ rb_define_method(cA_sqlany_bind_param, "set_buffer_size", static_Bind_set_buffer_size, 1);
1746
+ rb_define_method(cA_sqlany_bind_param, "finish", static_Bind_finish, 0);
1747
+
1748
+ // Define methods for obtaining bind_parameter_info fields
1749
+ rb_define_method(cA_sqlany_bind_param_info, "get_direction", static_Bind_get_info_direction, 0);
1750
+ rb_define_method(cA_sqlany_bind_param_info, "get_output", static_Bind_get_info_output, 0);
1751
+ }
1752
+
1753
+