sqlanywhere 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (12) hide show
  1. data/CHANGELOG +29 -25
  2. data/LICENSE +23 -23
  3. data/README +134 -130
  4. data/Rakefile +199 -196
  5. data/ext/extconf.rb +30 -30
  6. data/ext/sacapi.h +678 -678
  7. data/ext/sacapidll.c +167 -167
  8. data/ext/sacapidll.h +253 -253
  9. data/ext/sqlanywhere.c +1686 -1686
  10. data/test/sqlanywhere_test.rb +413 -413
  11. data/test/test.sql +87 -87
  12. metadata +2 -2
@@ -1,413 +1,413 @@
1
- #====================================================
2
- #
3
- # Copyright 2008-2009 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
-
25
- require 'test/unit'
26
- require 'date'
27
-
28
- begin
29
- require 'rubygems'
30
- gem 'sqlanywhere'
31
- unless defined? SQLAnywhere
32
- require 'sqlanywhere'
33
- end
34
- end
35
-
36
- class Types
37
- A_INVALID_TYPE= 0
38
- A_BINARY = 1
39
- A_STRING = 2
40
- A_DOUBLE = 3
41
- A_VAL64 = 4
42
- A_UVAL64 = 5
43
- A_VAL32 = 6
44
- A_UVAL32 = 7
45
- A_VAL16 = 8
46
- A_UVAL16 = 9
47
- A_VAL8 = 10
48
- A_UVAL8 = 11
49
- end
50
-
51
- class Direction
52
- DD_INVALID = 0
53
- DD_INPUT = 1
54
- DD_OUTPUT = 2
55
- DD_INPUT_OUTPUT = 3
56
- end
57
-
58
- class SQLAnywhere_Test < Test::Unit::TestCase
59
- def setup
60
- @api = SQLAnywhere::SQLAnywhereInterface.new()
61
- assert_not_nil @api
62
- assert_nothing_raised do
63
- SQLAnywhere::API.sqlany_initialize_interface( @api )
64
- end
65
- assert_nothing_raised do
66
- @api.sqlany_init()
67
- end
68
- @conn = @api.sqlany_new_connection()
69
- assert_not_nil @conn
70
- conn_str = "eng=test;uid=dba;pwd=sql"
71
- assert_succeeded @api.sqlany_connect(@conn, conn_str)
72
- end
73
-
74
- def teardown
75
- assert_succeeded @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
76
- assert_nil @api.sqlany_disconnect(@conn)
77
- assert_failed @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
78
- assert_nil @api.sqlany_free_connection(@conn)
79
- assert_nothing_raised do
80
- @api.sqlany_fini()
81
- end
82
- assert_nothing_raised do
83
- SQLAnywhere::API.sqlany_finalize_interface( @api )
84
- end
85
- end
86
-
87
- def test_execute_immediate
88
- assert_succeeded @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
89
- end
90
-
91
- def test_errors
92
- sql = "INSERT INTO test(\"id\") VALUES('test');"
93
- assert_failed @api.sqlany_execute_immediate(@conn, sql)
94
- code, msg = @api.sqlany_error(@conn)
95
- assert_equal -157, code
96
- assert_not_equal "", msg
97
- assert_equal "53018\000", @api.sqlany_sqlstate(@conn)
98
- assert_nil @api.sqlany_clear_error(@conn)
99
- code, msg = @api.sqlany_error(@conn)
100
- assert_equal 0, code
101
- assert_equal "", msg
102
- end
103
-
104
- def test_rollback
105
- id = setup_transaction
106
- @api.sqlany_rollback(@conn)
107
- sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
108
- rs = exec_direct_with_test(sql)
109
- assert_failed @api.sqlany_fetch_next(rs)
110
- end
111
-
112
- def test_commit
113
- id = setup_transaction
114
- @api.sqlany_commit(@conn)
115
- sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
116
- rs = exec_direct_with_test(sql)
117
- assert_succeeded @api.sqlany_fetch_next(rs)
118
- res, ret_id = @api.sqlany_get_column(rs, 0)
119
- assert_succeeded res
120
- assert_not_nil ret_id
121
- assert_equal id, ret_id
122
- assert_failed @api.sqlany_fetch_next(rs)
123
- end
124
-
125
- def test_column_info
126
- rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
127
- assert_equal 22, @api.sqlany_num_cols(rs)
128
- assert_column_info(rs, 0, "id", Types::A_VAL32, 4)
129
- assert_column_info(rs, 1, "_binary_", Types::A_BINARY, 8)
130
- assert_column_info(rs, 2, "_numeric_", Types::A_STRING, 2)
131
- assert_column_info(rs, 3, "_decimal_", Types::A_STRING, 2)
132
- assert_column_info(rs, 4, "_bounded_string_", Types::A_STRING, 255)
133
- assert_column_info(rs, 5, "_unbounded_string_", Types::A_STRING, (2 * (2**30)) - 1)
134
- assert_column_info(rs, 6, "_signed_bigint_", Types::A_VAL64, 8)
135
- assert_column_info(rs, 7, "_unsigned_bigint_", Types::A_UVAL64, 8)
136
- assert_column_info(rs, 8, "_signed_int_", Types::A_VAL32, 4)
137
- assert_column_info(rs, 9, "_unsigned_int_", Types::A_UVAL32, 4)
138
- assert_column_info(rs, 10, "_signed_smallint_", Types::A_VAL16, 2)
139
- assert_column_info(rs, 11, "_unsigned_smallint_", Types::A_UVAL16, 2)
140
- assert_column_info(rs, 12, "_signed_tinyint_", Types::A_VAL8, 1)
141
- assert_column_info(rs, 13, "_unsigned_tinyint_", Types::A_VAL8, 1)
142
- assert_column_info(rs, 14, "_bit_", Types::A_UVAL8, 1)
143
- assert_column_info(rs, 15, "_date_", Types::A_STRING, 10)
144
- assert_column_info(rs, 16, "_datetime_", Types::A_STRING, 23)
145
- assert_column_info(rs, 17, "_smalldatetime_", Types::A_STRING, 23)
146
- assert_column_info(rs, 18, "_timestamp_", Types::A_STRING, 23)
147
- assert_column_info(rs, 19, "_double_", Types::A_DOUBLE, 8)
148
- assert_column_info(rs, 20, "_float_", Types::A_DOUBLE, 4)
149
- assert_column_info(rs, 21, "_real_", Types::A_DOUBLE, 4)
150
- assert_nil @api.sqlany_free_stmt(rs)
151
- end
152
-
153
- def test_bounds_on_types
154
- rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
155
- assert_succeeded @api.sqlany_fetch_next(rs)
156
- assert_class_and_value(rs, String, 1, "x")
157
- assert_class_and_value(rs, String, 2, "1.1")
158
- assert_class_and_value(rs, String, 3, "1.1")
159
- assert_class_and_value(rs, String, 4, 'Bounded String Test')
160
- assert_class_and_value(rs, String, 5, 'Unbounded String Test')
161
- assert_class_and_value(rs, Bignum, 6, 9223372036854775807)
162
- assert_class_and_value(rs, Bignum, 7, 18446744073709551615)
163
- assert_class_and_value(rs, Bignum, 8, 2147483647)
164
- assert_class_and_value(rs, Bignum, 9, 4294967295)
165
- assert_class_and_value(rs, Fixnum, 10, 32767)
166
- assert_class_and_value(rs, Fixnum, 11, 65535)
167
- assert_class_and_value(rs, Fixnum, 12, 255)
168
- assert_class_and_value(rs, Fixnum, 13, 255)
169
- assert_class_and_value(rs, Fixnum, 14, 1)
170
- assert_date_and_time(rs, Date, 15, Date.new(1999, 1, 2))
171
- assert_date_and_time(rs, DateTime, 16, DateTime.new(1999, 1, 2, 21, 20, 53))
172
- assert_date_and_time(rs, DateTime, 17, DateTime.new(1999, 1, 2, 21, 20, 53))
173
- assert_date_and_time(rs, DateTime, 18, DateTime.new(1999, 1, 2, 21, 20, 53))
174
- assert_class_and_float_value(rs, Float, 19, 1.79769313486231e+308, 1e+293 )
175
- assert_class_and_float_value(rs, Float, 20, 3.402823e+38, 1e+32 )
176
- assert_class_and_float_value(rs, Float, 21, 3.402823e+38, 1e+32 )
177
-
178
- assert_succeeded @api.sqlany_fetch_next(rs)
179
- assert_class_and_value(rs, String, 1, 255.chr)
180
- assert_class_and_value(rs, String, 2, "-1.1")
181
- assert_class_and_value(rs, String, 3, "-1.1")
182
- assert_class_and_value(rs, String, 4, '')
183
- assert_class_and_value(rs, String, 5, '')
184
- assert_class_and_value(rs, Bignum, 6, -9223372036854775808)
185
- assert_class_and_value(rs, Fixnum, 7, 0)
186
- assert_class_and_value(rs, Bignum, 8, -2147483648)
187
- assert_class_and_value(rs, Fixnum, 9, 0)
188
- assert_class_and_value(rs, Fixnum, 10, -32768)
189
- assert_class_and_value(rs, Fixnum, 11, 0)
190
- assert_class_and_value(rs, Fixnum, 12, 0)
191
- assert_class_and_value(rs, Fixnum, 13, 0)
192
- assert_class_and_value(rs, Fixnum, 14, 0)
193
- assert_class_and_value(rs, NilClass, 15, nil)
194
- assert_class_and_value(rs, NilClass, 16, nil)
195
- assert_class_and_value(rs, NilClass, 17, nil)
196
- assert_class_and_value(rs, NilClass, 18, nil)
197
- assert_class_and_float_value(rs, Float, 19, -1.79769313486231e+308, 1e+293 )
198
- assert_class_and_float_value(rs, Float, 20, -3.402823e+38, 1e+32 )
199
- assert_class_and_float_value(rs, Float, 21, -3.402823e+38, 1e+32 )
200
- assert_nil @api.sqlany_free_stmt(rs)
201
- end
202
-
203
- def test_prepared_stmt
204
- stmt = @api.sqlany_prepare(@conn, "SELECT * FROM \"types\" WHERE \"id\" = ?")
205
- assert_not_nil stmt
206
- assert_failed @api.sqlany_execute(stmt)
207
- assert_equal 1, @api.sqlany_num_params(stmt)
208
- res, param = @api.sqlany_describe_bind_param(stmt, 0)
209
- assert_not_equal 0, res
210
- assert_equal "?", param.get_name()
211
- assert_equal Direction::DD_INPUT, param.get_direction()
212
-
213
- assert_nil param.set_value(0);
214
- @api.sqlany_bind_param(stmt, 0, param)
215
- assert_succeeded @api.sqlany_execute(stmt)
216
- assert_succeeded @api.sqlany_fetch_next(stmt)
217
- assert_class_and_value(stmt, String, 4, "Bounded String Test")
218
-
219
- assert_nil param.set_value(1);
220
- @api.sqlany_bind_param(stmt, 0, param)
221
- assert_succeeded @api.sqlany_execute(stmt)
222
- assert_succeeded @api.sqlany_fetch_next(stmt)
223
- assert_class_and_value(stmt, String, 4, "")
224
-
225
- assert_nil @api.sqlany_free_stmt(stmt)
226
- end
227
-
228
- def test_insert_binary
229
- assert_insert("_binary_", "x", String)
230
- end
231
-
232
- def test_insert_numeric
233
- assert_insert("_numeric_", "1.1", String)
234
- end
235
-
236
- def test_insert_decimal
237
- assert_insert("_decimal_", "1.1", String)
238
- end
239
-
240
- def test_insert_bounded_string
241
- assert_insert("_bounded_string_", "Bounded String Test", String)
242
- end
243
-
244
- def test_insert_unbounded_string
245
- assert_insert("_unbounded_string_", "Unbounded String Test", String)
246
- end
247
-
248
- def test_insert_int64
249
- assert_insert("_signed_bigint_", 9223372036854775807, Bignum)
250
- assert_insert("_signed_bigint_", -9223372036854775808, Bignum)
251
- end
252
-
253
- def test_insert_uint64
254
- assert_insert("_unsigned_bigint_", 9223372036854775807, Bignum)
255
- assert_insert("_unsigned_bigint_", 0, Fixnum)
256
- end
257
-
258
- def test_insert_int32
259
- assert_insert("_signed_int_", 2147483647, Bignum)
260
- assert_insert("_signed_int_", -2147483648, Bignum)
261
- end
262
-
263
- def test_insert_uint32
264
- assert_insert("_unsigned_int_", 4294967295, Bignum)
265
- assert_insert("_unsigned_int_", 0, Fixnum)
266
- end
267
-
268
- def test_insert_int16
269
- assert_insert("_signed_smallint_", 32767, Fixnum)
270
- assert_insert("_signed_smallint_", -32768, Fixnum)
271
- end
272
-
273
- def test_insert_uint16
274
- assert_insert("_unsigned_smallint_", 65535, Fixnum)
275
- assert_insert("_unsigned_smallint_", 0, Fixnum)
276
- end
277
-
278
- def test_insert_int8
279
- assert_insert("_signed_smallint_", 255, Fixnum)
280
- assert_insert("_signed_smallint_", 0, Fixnum)
281
- end
282
-
283
- def test_insert_uint8
284
- assert_insert("_unsigned_smallint_", 255, Fixnum)
285
- assert_insert("_unsigned_smallint_", 0, Fixnum)
286
- end
287
-
288
- def test_insert_date
289
- assert_insert("_date_", Date.new(1999, 1, 2), Date)
290
- end
291
-
292
- def test_insert_datetime
293
- assert_insert("_datetime_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
294
- end
295
-
296
- def test_insert_smalldate
297
- assert_insert("_smalldatetime_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
298
- end
299
-
300
- def test_insert_timestamp
301
- assert_insert("_timestamp_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
302
- end
303
-
304
- def test_insert_double
305
- assert_insert("_double_", 1.79769313486231e+308, Float, 1e+293)
306
- end
307
-
308
- def test_insert_float
309
- assert_insert("_float_", 3.402823e+38, Float, 1e+32)
310
- end
311
-
312
- def test_insert_real
313
- assert_insert("_real_", 3.402823e+38, Float, 1e+32)
314
- end
315
-
316
- def assert_insert(column_name, value, type, delta = nil)
317
- stmt = @api.sqlany_prepare(@conn, 'INSERT INTO "types"("id", "' + column_name + '", "_bit_") VALUES(3, ?, 1)')
318
- assert_not_nil stmt
319
- res, param = @api.sqlany_describe_bind_param(stmt, 0)
320
- if type == Date or type == DateTime then
321
- assert_nil param.set_value(value.strftime("%F %T"));
322
- else
323
- assert_nil param.set_value(value);
324
- end
325
- @api.sqlany_bind_param(stmt, 0, param)
326
- assert_succeeded @api.sqlany_execute(stmt)
327
- assert_nil @api.sqlany_free_stmt(stmt)
328
-
329
- rs = exec_direct_with_test('SELECT "' + column_name + '" FROM "types" WHERE "id" = 3')
330
- assert_succeeded @api.sqlany_fetch_next(rs)
331
- if type == Date or type == DateTime then
332
- assert_date_and_time(rs, type, 0, value)
333
- elsif type == Float
334
- assert_class_and_float_value(rs, type, 0, value, delta)
335
- else
336
- assert_class_and_value(rs, type, 0, value)
337
- end
338
-
339
- assert_nil @api.sqlany_free_stmt(rs)
340
-
341
- @api.sqlany_rollback(@conn)
342
- end
343
-
344
- def assert_column_info(rs, pos, expected_col_name, expected_col_type, expected_col_size)
345
- res, col_num, col_name, col_type, col_native_type, col_precision, col_scale, col_size, col_nullable = @api.sqlany_get_column_info(rs, pos);
346
- assert_succeeded res
347
- assert_equal expected_col_name, col_name
348
- assert_equal expected_col_type, col_type
349
- assert_equal expected_col_size, col_size
350
- end
351
-
352
- def assert_class_and_float_value(rs, cl, pos, expected_value, allowed_delta)
353
- res, val = @api.sqlany_get_column(rs, pos)
354
- assert_succeeded res
355
- assert_not_nil val unless expected_value.nil?
356
- assert_in_delta expected_value, val, allowed_delta
357
- assert_instance_of cl, val
358
- end
359
-
360
- def assert_date_and_time(rs, cl, pos, expected_value)
361
- res, val = @api.sqlany_get_column(rs, pos)
362
- assert_succeeded res
363
- assert_not_nil val unless expected_value.nil?
364
- parsed = cl.parse(val)
365
- assert_equal expected_value, parsed
366
- assert_instance_of cl, parsed
367
- end
368
-
369
- def assert_class_and_value(rs, cl, pos, expected_value)
370
- res, val = @api.sqlany_get_column(rs, pos)
371
- assert_succeeded res
372
- assert_not_nil val unless expected_value.nil?
373
- assert_equal expected_value, val
374
- assert_instance_of cl, val
375
- end
376
-
377
- def setup_transaction
378
- sql = "INSERT INTO test VALUES( DEFAULT );"
379
- assert_succeeded @api.sqlany_execute_immediate(@conn, sql)
380
-
381
- rs = exec_direct_with_test("SELECT @@identity")
382
- assert_succeeded @api.sqlany_fetch_next(rs)
383
- res, id = @api.sqlany_get_column(rs, 0)
384
- assert_succeeded res
385
- assert_not_nil id
386
-
387
- sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
388
- rs = @api.sqlany_execute_direct(@conn, sql)
389
- assert_not_nil rs
390
-
391
- assert_succeeded @api.sqlany_fetch_next(rs)
392
- assert_failed @api.sqlany_fetch_next(rs)
393
- assert_nil @api.sqlany_free_stmt(rs)
394
- id
395
- end
396
-
397
- def exec_direct_with_test(sql)
398
- rs = @api.sqlany_execute_direct(@conn, sql)
399
- code, msg = @api.sqlany_error(@conn)
400
- assert_not_nil rs, "SQL Code: #{code}; Message: #{msg}"
401
- rs
402
- end
403
-
404
- def assert_succeeded(val)
405
- assert_not_equal 0, val, @api.sqlany_error(@conn)
406
- end
407
-
408
- def assert_failed(val)
409
- assert_equal 0, val, @api.sqlany_error(@conn)
410
- end
411
-
412
- end
413
-
1
+ #====================================================
2
+ #
3
+ # Copyright 2008-2009 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
+
25
+ require 'test/unit'
26
+ require 'date'
27
+
28
+ begin
29
+ require 'rubygems'
30
+ gem 'sqlanywhere'
31
+ unless defined? SQLAnywhere
32
+ require 'sqlanywhere'
33
+ end
34
+ end
35
+
36
+ class Types
37
+ A_INVALID_TYPE= 0
38
+ A_BINARY = 1
39
+ A_STRING = 2
40
+ A_DOUBLE = 3
41
+ A_VAL64 = 4
42
+ A_UVAL64 = 5
43
+ A_VAL32 = 6
44
+ A_UVAL32 = 7
45
+ A_VAL16 = 8
46
+ A_UVAL16 = 9
47
+ A_VAL8 = 10
48
+ A_UVAL8 = 11
49
+ end
50
+
51
+ class Direction
52
+ DD_INVALID = 0
53
+ DD_INPUT = 1
54
+ DD_OUTPUT = 2
55
+ DD_INPUT_OUTPUT = 3
56
+ end
57
+
58
+ class SQLAnywhere_Test < Test::Unit::TestCase
59
+ def setup
60
+ @api = SQLAnywhere::SQLAnywhereInterface.new()
61
+ assert_not_nil @api
62
+ assert_nothing_raised do
63
+ SQLAnywhere::API.sqlany_initialize_interface( @api )
64
+ end
65
+ assert_nothing_raised do
66
+ @api.sqlany_init()
67
+ end
68
+ @conn = @api.sqlany_new_connection()
69
+ assert_not_nil @conn
70
+ conn_str = "eng=test;uid=dba;pwd=sql"
71
+ assert_succeeded @api.sqlany_connect(@conn, conn_str)
72
+ end
73
+
74
+ def teardown
75
+ assert_succeeded @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
76
+ assert_nil @api.sqlany_disconnect(@conn)
77
+ assert_failed @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
78
+ assert_nil @api.sqlany_free_connection(@conn)
79
+ assert_nothing_raised do
80
+ @api.sqlany_fini()
81
+ end
82
+ assert_nothing_raised do
83
+ SQLAnywhere::API.sqlany_finalize_interface( @api )
84
+ end
85
+ end
86
+
87
+ def test_execute_immediate
88
+ assert_succeeded @api.sqlany_execute_immediate(@conn, 'SELECT * FROM dummy')
89
+ end
90
+
91
+ def test_errors
92
+ sql = "INSERT INTO test(\"id\") VALUES('test');"
93
+ assert_failed @api.sqlany_execute_immediate(@conn, sql)
94
+ code, msg = @api.sqlany_error(@conn)
95
+ assert_equal -157, code
96
+ assert_not_equal "", msg
97
+ assert_equal "53018\000", @api.sqlany_sqlstate(@conn)
98
+ assert_nil @api.sqlany_clear_error(@conn)
99
+ code, msg = @api.sqlany_error(@conn)
100
+ assert_equal 0, code
101
+ assert_equal "", msg
102
+ end
103
+
104
+ def test_rollback
105
+ id = setup_transaction
106
+ @api.sqlany_rollback(@conn)
107
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
108
+ rs = exec_direct_with_test(sql)
109
+ assert_failed @api.sqlany_fetch_next(rs)
110
+ end
111
+
112
+ def test_commit
113
+ id = setup_transaction
114
+ @api.sqlany_commit(@conn)
115
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
116
+ rs = exec_direct_with_test(sql)
117
+ assert_succeeded @api.sqlany_fetch_next(rs)
118
+ res, ret_id = @api.sqlany_get_column(rs, 0)
119
+ assert_succeeded res
120
+ assert_not_nil ret_id
121
+ assert_equal id, ret_id
122
+ assert_failed @api.sqlany_fetch_next(rs)
123
+ end
124
+
125
+ def test_column_info
126
+ rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
127
+ assert_equal 22, @api.sqlany_num_cols(rs)
128
+ assert_column_info(rs, 0, "id", Types::A_VAL32, 4)
129
+ assert_column_info(rs, 1, "_binary_", Types::A_BINARY, 8)
130
+ assert_column_info(rs, 2, "_numeric_", Types::A_STRING, 2)
131
+ assert_column_info(rs, 3, "_decimal_", Types::A_STRING, 2)
132
+ assert_column_info(rs, 4, "_bounded_string_", Types::A_STRING, 255)
133
+ assert_column_info(rs, 5, "_unbounded_string_", Types::A_STRING, (2 * (2**30)) - 1)
134
+ assert_column_info(rs, 6, "_signed_bigint_", Types::A_VAL64, 8)
135
+ assert_column_info(rs, 7, "_unsigned_bigint_", Types::A_UVAL64, 8)
136
+ assert_column_info(rs, 8, "_signed_int_", Types::A_VAL32, 4)
137
+ assert_column_info(rs, 9, "_unsigned_int_", Types::A_UVAL32, 4)
138
+ assert_column_info(rs, 10, "_signed_smallint_", Types::A_VAL16, 2)
139
+ assert_column_info(rs, 11, "_unsigned_smallint_", Types::A_UVAL16, 2)
140
+ assert_column_info(rs, 12, "_signed_tinyint_", Types::A_VAL8, 1)
141
+ assert_column_info(rs, 13, "_unsigned_tinyint_", Types::A_VAL8, 1)
142
+ assert_column_info(rs, 14, "_bit_", Types::A_UVAL8, 1)
143
+ assert_column_info(rs, 15, "_date_", Types::A_STRING, 10)
144
+ assert_column_info(rs, 16, "_datetime_", Types::A_STRING, 23)
145
+ assert_column_info(rs, 17, "_smalldatetime_", Types::A_STRING, 23)
146
+ assert_column_info(rs, 18, "_timestamp_", Types::A_STRING, 23)
147
+ assert_column_info(rs, 19, "_double_", Types::A_DOUBLE, 8)
148
+ assert_column_info(rs, 20, "_float_", Types::A_DOUBLE, 4)
149
+ assert_column_info(rs, 21, "_real_", Types::A_DOUBLE, 4)
150
+ assert_nil @api.sqlany_free_stmt(rs)
151
+ end
152
+
153
+ def test_bounds_on_types
154
+ rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
155
+ assert_succeeded @api.sqlany_fetch_next(rs)
156
+ assert_class_and_value(rs, String, 1, "x")
157
+ assert_class_and_value(rs, String, 2, "1.1")
158
+ assert_class_and_value(rs, String, 3, "1.1")
159
+ assert_class_and_value(rs, String, 4, 'Bounded String Test')
160
+ assert_class_and_value(rs, String, 5, 'Unbounded String Test')
161
+ assert_class_and_value(rs, Bignum, 6, 9223372036854775807)
162
+ assert_class_and_value(rs, Bignum, 7, 18446744073709551615)
163
+ assert_class_and_value(rs, Bignum, 8, 2147483647)
164
+ assert_class_and_value(rs, Bignum, 9, 4294967295)
165
+ assert_class_and_value(rs, Fixnum, 10, 32767)
166
+ assert_class_and_value(rs, Fixnum, 11, 65535)
167
+ assert_class_and_value(rs, Fixnum, 12, 255)
168
+ assert_class_and_value(rs, Fixnum, 13, 255)
169
+ assert_class_and_value(rs, Fixnum, 14, 1)
170
+ assert_date_and_time(rs, Date, 15, Date.new(1999, 1, 2))
171
+ assert_date_and_time(rs, DateTime, 16, DateTime.new(1999, 1, 2, 21, 20, 53))
172
+ assert_date_and_time(rs, DateTime, 17, DateTime.new(1999, 1, 2, 21, 20, 53))
173
+ assert_date_and_time(rs, DateTime, 18, DateTime.new(1999, 1, 2, 21, 20, 53))
174
+ assert_class_and_float_value(rs, Float, 19, 1.79769313486231e+308, 1e+293 )
175
+ assert_class_and_float_value(rs, Float, 20, 3.402823e+38, 1e+32 )
176
+ assert_class_and_float_value(rs, Float, 21, 3.402823e+38, 1e+32 )
177
+
178
+ assert_succeeded @api.sqlany_fetch_next(rs)
179
+ assert_class_and_value(rs, String, 1, 255.chr)
180
+ assert_class_and_value(rs, String, 2, "-1.1")
181
+ assert_class_and_value(rs, String, 3, "-1.1")
182
+ assert_class_and_value(rs, String, 4, '')
183
+ assert_class_and_value(rs, String, 5, '')
184
+ assert_class_and_value(rs, Bignum, 6, -9223372036854775808)
185
+ assert_class_and_value(rs, Fixnum, 7, 0)
186
+ assert_class_and_value(rs, Bignum, 8, -2147483648)
187
+ assert_class_and_value(rs, Fixnum, 9, 0)
188
+ assert_class_and_value(rs, Fixnum, 10, -32768)
189
+ assert_class_and_value(rs, Fixnum, 11, 0)
190
+ assert_class_and_value(rs, Fixnum, 12, 0)
191
+ assert_class_and_value(rs, Fixnum, 13, 0)
192
+ assert_class_and_value(rs, Fixnum, 14, 0)
193
+ assert_class_and_value(rs, NilClass, 15, nil)
194
+ assert_class_and_value(rs, NilClass, 16, nil)
195
+ assert_class_and_value(rs, NilClass, 17, nil)
196
+ assert_class_and_value(rs, NilClass, 18, nil)
197
+ assert_class_and_float_value(rs, Float, 19, -1.79769313486231e+308, 1e+293 )
198
+ assert_class_and_float_value(rs, Float, 20, -3.402823e+38, 1e+32 )
199
+ assert_class_and_float_value(rs, Float, 21, -3.402823e+38, 1e+32 )
200
+ assert_nil @api.sqlany_free_stmt(rs)
201
+ end
202
+
203
+ def test_prepared_stmt
204
+ stmt = @api.sqlany_prepare(@conn, "SELECT * FROM \"types\" WHERE \"id\" = ?")
205
+ assert_not_nil stmt
206
+ assert_failed @api.sqlany_execute(stmt)
207
+ assert_equal 1, @api.sqlany_num_params(stmt)
208
+ res, param = @api.sqlany_describe_bind_param(stmt, 0)
209
+ assert_not_equal 0, res
210
+ assert_equal "?", param.get_name()
211
+ assert_equal Direction::DD_INPUT, param.get_direction()
212
+
213
+ assert_nil param.set_value(0);
214
+ @api.sqlany_bind_param(stmt, 0, param)
215
+ assert_succeeded @api.sqlany_execute(stmt)
216
+ assert_succeeded @api.sqlany_fetch_next(stmt)
217
+ assert_class_and_value(stmt, String, 4, "Bounded String Test")
218
+
219
+ assert_nil param.set_value(1);
220
+ @api.sqlany_bind_param(stmt, 0, param)
221
+ assert_succeeded @api.sqlany_execute(stmt)
222
+ assert_succeeded @api.sqlany_fetch_next(stmt)
223
+ assert_class_and_value(stmt, String, 4, "")
224
+
225
+ assert_nil @api.sqlany_free_stmt(stmt)
226
+ end
227
+
228
+ def test_insert_binary
229
+ assert_insert("_binary_", "x", String)
230
+ end
231
+
232
+ def test_insert_numeric
233
+ assert_insert("_numeric_", "1.1", String)
234
+ end
235
+
236
+ def test_insert_decimal
237
+ assert_insert("_decimal_", "1.1", String)
238
+ end
239
+
240
+ def test_insert_bounded_string
241
+ assert_insert("_bounded_string_", "Bounded String Test", String)
242
+ end
243
+
244
+ def test_insert_unbounded_string
245
+ assert_insert("_unbounded_string_", "Unbounded String Test", String)
246
+ end
247
+
248
+ def test_insert_int64
249
+ assert_insert("_signed_bigint_", 9223372036854775807, Bignum)
250
+ assert_insert("_signed_bigint_", -9223372036854775808, Bignum)
251
+ end
252
+
253
+ def test_insert_uint64
254
+ assert_insert("_unsigned_bigint_", 9223372036854775807, Bignum)
255
+ assert_insert("_unsigned_bigint_", 0, Fixnum)
256
+ end
257
+
258
+ def test_insert_int32
259
+ assert_insert("_signed_int_", 2147483647, Bignum)
260
+ assert_insert("_signed_int_", -2147483648, Bignum)
261
+ end
262
+
263
+ def test_insert_uint32
264
+ assert_insert("_unsigned_int_", 4294967295, Bignum)
265
+ assert_insert("_unsigned_int_", 0, Fixnum)
266
+ end
267
+
268
+ def test_insert_int16
269
+ assert_insert("_signed_smallint_", 32767, Fixnum)
270
+ assert_insert("_signed_smallint_", -32768, Fixnum)
271
+ end
272
+
273
+ def test_insert_uint16
274
+ assert_insert("_unsigned_smallint_", 65535, Fixnum)
275
+ assert_insert("_unsigned_smallint_", 0, Fixnum)
276
+ end
277
+
278
+ def test_insert_int8
279
+ assert_insert("_signed_smallint_", 255, Fixnum)
280
+ assert_insert("_signed_smallint_", 0, Fixnum)
281
+ end
282
+
283
+ def test_insert_uint8
284
+ assert_insert("_unsigned_smallint_", 255, Fixnum)
285
+ assert_insert("_unsigned_smallint_", 0, Fixnum)
286
+ end
287
+
288
+ def test_insert_date
289
+ assert_insert("_date_", Date.new(1999, 1, 2), Date)
290
+ end
291
+
292
+ def test_insert_datetime
293
+ assert_insert("_datetime_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
294
+ end
295
+
296
+ def test_insert_smalldate
297
+ assert_insert("_smalldatetime_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
298
+ end
299
+
300
+ def test_insert_timestamp
301
+ assert_insert("_timestamp_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
302
+ end
303
+
304
+ def test_insert_double
305
+ assert_insert("_double_", 1.79769313486231e+308, Float, 1e+293)
306
+ end
307
+
308
+ def test_insert_float
309
+ assert_insert("_float_", 3.402823e+38, Float, 1e+32)
310
+ end
311
+
312
+ def test_insert_real
313
+ assert_insert("_real_", 3.402823e+38, Float, 1e+32)
314
+ end
315
+
316
+ def assert_insert(column_name, value, type, delta = nil)
317
+ stmt = @api.sqlany_prepare(@conn, 'INSERT INTO "types"("id", "' + column_name + '", "_bit_") VALUES(3, ?, 1)')
318
+ assert_not_nil stmt
319
+ res, param = @api.sqlany_describe_bind_param(stmt, 0)
320
+ if type == Date or type == DateTime then
321
+ assert_nil param.set_value(value.strftime("%F %T"));
322
+ else
323
+ assert_nil param.set_value(value);
324
+ end
325
+ @api.sqlany_bind_param(stmt, 0, param)
326
+ assert_succeeded @api.sqlany_execute(stmt)
327
+ assert_nil @api.sqlany_free_stmt(stmt)
328
+
329
+ rs = exec_direct_with_test('SELECT "' + column_name + '" FROM "types" WHERE "id" = 3')
330
+ assert_succeeded @api.sqlany_fetch_next(rs)
331
+ if type == Date or type == DateTime then
332
+ assert_date_and_time(rs, type, 0, value)
333
+ elsif type == Float
334
+ assert_class_and_float_value(rs, type, 0, value, delta)
335
+ else
336
+ assert_class_and_value(rs, type, 0, value)
337
+ end
338
+
339
+ assert_nil @api.sqlany_free_stmt(rs)
340
+
341
+ @api.sqlany_rollback(@conn)
342
+ end
343
+
344
+ def assert_column_info(rs, pos, expected_col_name, expected_col_type, expected_col_size)
345
+ res, col_num, col_name, col_type, col_native_type, col_precision, col_scale, col_size, col_nullable = @api.sqlany_get_column_info(rs, pos);
346
+ assert_succeeded res
347
+ assert_equal expected_col_name, col_name
348
+ assert_equal expected_col_type, col_type
349
+ assert_equal expected_col_size, col_size
350
+ end
351
+
352
+ def assert_class_and_float_value(rs, cl, pos, expected_value, allowed_delta)
353
+ res, val = @api.sqlany_get_column(rs, pos)
354
+ assert_succeeded res
355
+ assert_not_nil val unless expected_value.nil?
356
+ assert_in_delta expected_value, val, allowed_delta
357
+ assert_instance_of cl, val
358
+ end
359
+
360
+ def assert_date_and_time(rs, cl, pos, expected_value)
361
+ res, val = @api.sqlany_get_column(rs, pos)
362
+ assert_succeeded res
363
+ assert_not_nil val unless expected_value.nil?
364
+ parsed = cl.parse(val)
365
+ assert_equal expected_value, parsed
366
+ assert_instance_of cl, parsed
367
+ end
368
+
369
+ def assert_class_and_value(rs, cl, pos, expected_value)
370
+ res, val = @api.sqlany_get_column(rs, pos)
371
+ assert_succeeded res
372
+ assert_not_nil val unless expected_value.nil?
373
+ assert_equal expected_value, val
374
+ assert_instance_of cl, val
375
+ end
376
+
377
+ def setup_transaction
378
+ sql = "INSERT INTO test VALUES( DEFAULT );"
379
+ assert_succeeded @api.sqlany_execute_immediate(@conn, sql)
380
+
381
+ rs = exec_direct_with_test("SELECT @@identity")
382
+ assert_succeeded @api.sqlany_fetch_next(rs)
383
+ res, id = @api.sqlany_get_column(rs, 0)
384
+ assert_succeeded res
385
+ assert_not_nil id
386
+
387
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
388
+ rs = @api.sqlany_execute_direct(@conn, sql)
389
+ assert_not_nil rs
390
+
391
+ assert_succeeded @api.sqlany_fetch_next(rs)
392
+ assert_failed @api.sqlany_fetch_next(rs)
393
+ assert_nil @api.sqlany_free_stmt(rs)
394
+ id
395
+ end
396
+
397
+ def exec_direct_with_test(sql)
398
+ rs = @api.sqlany_execute_direct(@conn, sql)
399
+ code, msg = @api.sqlany_error(@conn)
400
+ assert_not_nil rs, "SQL Code: #{code}; Message: #{msg}"
401
+ rs
402
+ end
403
+
404
+ def assert_succeeded(val)
405
+ assert_not_equal 0, val, @api.sqlany_error(@conn)
406
+ end
407
+
408
+ def assert_failed(val)
409
+ assert_equal 0, val, @api.sqlany_error(@conn)
410
+ end
411
+
412
+ end
413
+