sqlanywhere 0.1.0-i386-mswin32

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