sqlanywhere 0.1.0-i486-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+