advantage 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,245 @@
1
+ #ifndef __DBCAPI_INCLUDED__
2
+ #define __DBCAPI_INCLUDED__
3
+
4
+ typedef enum a_ads_data_type
5
+ {
6
+ /// Invalid data type.
7
+ A_INVALID_TYPE,
8
+ /// Binary data. Binary data is treated as-is and no character set conversion is performed.
9
+ A_BINARY,
10
+ /// String data. The data where character set conversion is performed.
11
+ A_STRING,
12
+ /// Double data. Includes float values.
13
+ A_DOUBLE,
14
+ /// 64-bit integer.
15
+ A_VAL64,
16
+ /// 64-bit unsigned integer.
17
+ A_UVAL64,
18
+ /// 32-bit integer.
19
+ A_VAL32,
20
+ /// 32-bit unsigned integer.
21
+ A_UVAL32,
22
+ /// 16-bit integer.
23
+ A_VAL16,
24
+ /// 16-bit unsigned integer.
25
+ A_UVAL16,
26
+ /// 8-bit integer.
27
+ A_VAL8,
28
+ /// 8-bit unsigned integer.
29
+ A_UVAL8,
30
+ /// Unicode data (NCHAR)
31
+ A_NCHAR,
32
+ // Numeric data (lossless)
33
+ A_DECIMAL,
34
+ // Date value
35
+ A_DATE,
36
+ // Time value
37
+ A_TIME,
38
+ // Timestamp
39
+ A_TIMESTAMP
40
+
41
+ } a_ads_data_type;
42
+
43
+ typedef struct a_ads_data_value
44
+ {
45
+ /// A pointer to user supplied buffer of data.
46
+ UNSIGNED8 *buffer;
47
+ /// The size of the buffer.
48
+ UNSIGNED32 buffer_size;
49
+ /// A pointer to the number of valid bytes in the buffer. This value must be less than buffer_size.
50
+ UNSIGNED32 *length;
51
+ /// The type of the data
52
+ a_ads_data_type type;
53
+ /// A pointer to indicate whether the last fetched data is NULL.
54
+ UNSIGNED32 *is_null;
55
+ } a_ads_data_value;
56
+
57
+ /** A data direction enumeration.
58
+ */
59
+ typedef enum a_ads_data_direction
60
+ {
61
+ /// Invalid data direction.
62
+ DD_INVALID = 0x0,
63
+ /// Input-only host variables.
64
+ DD_INPUT = 0x1,
65
+ /// Output-only host variables.
66
+ DD_OUTPUT = 0x2,
67
+ /// Input and output host variables.
68
+ DD_INPUT_OUTPUT = 0x3
69
+ } a_ads_data_direction;
70
+
71
+ typedef struct a_ads_bind_param
72
+ {
73
+ /// The direction of the data. (input, output, input_output)
74
+ a_ads_data_direction direction;
75
+ /// The actual value of the data.
76
+ a_ads_data_value value;
77
+ /// Name of the bind parameter. This is only used by ads_describe_bind_param().
78
+ UNSIGNED8 *name;
79
+ } a_ads_bind_param;
80
+
81
+ typedef enum a_ads_native_type
82
+ {
83
+ /// No data type.
84
+ DT_NOTYPE = 0,
85
+ /// Null-terminated character string that is a valid date.
86
+ DT_DATE = 384,
87
+ /// Null-terminated character string that is a valid time.
88
+ DT_TIME = 388,
89
+ /// Null-terminated character string that is a valid timestamp.
90
+ DT_TIMESTAMP = 392,
91
+ /// Varying length character string, in the CHAR character set, with a two-byte length field. The maximum length is 32765 bytes . When sending data, you must set the length field. When fetching data, the database server sets the length field. The data is not null-terminated or blank-padded.
92
+ DT_VARCHAR = 448,
93
+ /// Fixed-length blank-padded character string, in the CHAR character set. The maximum length, specified in bytes, is 32767. The data is not null-terminated.
94
+ DT_FIXCHAR = 452,
95
+ /// Long varying length character string, in the CHAR character set.
96
+ DT_LONGVARCHAR = 456,
97
+ /// Null-terminated character string, in the CHAR character set. The string is blank-padded if the database is initialized with blank-padded strings.
98
+ DT_STRING = 460,
99
+ /// 8-byte floating-point number.
100
+ DT_DOUBLE = 480,
101
+ /// 4-byte floating-point number.
102
+ DT_FLOAT = 482,
103
+ /// Packed decimal number (proprietary format).
104
+ DT_DECIMAL = 484,
105
+ /// 32-bit signed integer.
106
+ DT_INT = 496,
107
+ /// 16-bit signed integer.
108
+ DT_SMALLINT = 500,
109
+ /// Varying length binary data with a two-byte length field. The maximum length is 32765 bytes. When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field.
110
+ DT_BINARY = 524,
111
+ /// Long binary data.
112
+ DT_LONGBINARY = 528,
113
+ /// 8-bit signed integer.
114
+ DT_TINYINT = 604,
115
+ /// 64-bit signed integer.
116
+ DT_BIGINT = 608,
117
+ /// 32-bit unsigned integer.
118
+ DT_UNSINT = 612,
119
+ /// 16-bit unsigned integer.
120
+ DT_UNSSMALLINT = 616,
121
+ /// 64-bit unsigned integer.
122
+ DT_UNSBIGINT = 620,
123
+ /// 8-bit signed integer.
124
+ DT_BIT = 624,
125
+ // Null-terminated string, in NCHAR character set. The string is blank-padded if the database is initialized with blank-padded strings.This variable holds n-1 characters plus the null terminator.
126
+ DT_NSTRING = 628,
127
+ // Fixed length character string, in NCHAR character set. Blank-padded but not null-terminated. The maximum value for n is 32767.
128
+ DT_NFIXCHAR = 632,
129
+ // Varying length character string, in NCHAR character set, with 2-byte length field. Not null-terminated or blank-padded. The maximum value for n is 32765.
130
+ DT_NVARCHAR = 636,
131
+ /// Long varying length character string, in the NCHAR character set.
132
+ DT_LONGNVARCHAR = 640
133
+
134
+ } a_ads_native_type;
135
+
136
+ typedef struct a_ads_column_info
137
+ {
138
+ /// The name of the column (null-terminated).
139
+ /// The string can be referenced as long as the result set object is not freed.
140
+ UNSIGNED8 *name;
141
+ /// The column data type.
142
+ a_ads_data_type type;
143
+ /// The native type of the column in the database.
144
+ a_ads_native_type native_type;
145
+ /// The precision.
146
+ UNSIGNED16 precision;
147
+ /// The scale.
148
+ UNSIGNED16 scale;
149
+ /// The maximum size a data value in this column can take.
150
+ UNSIGNED32 max_size;
151
+ /// Indicates whether a value in the column can be null.
152
+ UNSIGNED32 nullable;
153
+ } a_ads_column_info;
154
+
155
+ typedef struct a_ads_bind_param_info
156
+ {
157
+ /// A pointer to the name of the parameter.
158
+ UNSIGNED8 *name;
159
+ /// The direction of the parameter.
160
+ a_ads_data_direction direction;
161
+ /// Information about the bound input value.
162
+ a_ads_data_value input_value;
163
+ /// Information about the bound output value.
164
+ a_ads_data_value output_value;
165
+ } a_ads_bind_param_info;
166
+
167
+ typedef struct a_ads_data_info
168
+ {
169
+ /// The type of the data in the column.
170
+ a_ads_data_type type;
171
+ /// Indicates whether the last fetched data is NULL.
172
+ /// This field is only valid after a successful fetch operation.
173
+ UNSIGNED32 is_null;
174
+ /// The total number of bytes available to be fetched.
175
+ /// This field is only valid after a successful fetch operation.
176
+ UNSIGNED32 data_size;
177
+ } a_ads_data_info;
178
+
179
+ // Dummy connection object we can create & destroy. This is needed since DBCAPI wants
180
+ // a connection object from the new_connection API. If we need to store connection
181
+ // specific info for DBCAPI connections we could store it in this structure as opposed
182
+ // to the ACE CCONNECTION object.
183
+ typedef struct A_ADS_CONNECTION_STRUCT
184
+ {
185
+ ADSHANDLE hConnect; // Real ADS connection, set via ads_connect
186
+
187
+ } a_ads_connection, *a_ads_connection_ptr;
188
+
189
+ typedef struct
190
+ {
191
+ UNSIGNED8 *pucData; // Data buffer for the column
192
+ UNSIGNED8 *pucColumnName; // Column name string
193
+ UNSIGNED32 ulBufferLength; // Length of buffer
194
+ UNSIGNED32 ulDataLength; // Length of data in the buffer
195
+ UNSIGNED32 ulIsNull; // T/F NULL flag
196
+
197
+ } DBCAPI_COLUMN;
198
+
199
+ // DBCAPI entrypoints (not published)
200
+ #ifdef __cplusplus
201
+ extern "C"
202
+ {
203
+ #endif
204
+
205
+ UNSIGNED32 ENTRYPOINT ads_affected_rows(ADSHANDLE hStatement);
206
+ UNSIGNED32 ENTRYPOINT ads_bind_param(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param *param);
207
+ void ENTRYPOINT ads_cancel(a_ads_connection *poConnect);
208
+ void ENTRYPOINT ads_clear_error(a_ads_connection *poConnect);
209
+ UNSIGNED32 ENTRYPOINT ads_client_version(UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength);
210
+ UNSIGNED32 ENTRYPOINT ads_commit(a_ads_connection *poConnect);
211
+ UNSIGNED32 ENTRYPOINT ads_connect(a_ads_connection *poConnect, UNSIGNED8 *pucConnectString);
212
+ UNSIGNED32 ENTRYPOINT ads_describe_bind_param(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param *param);
213
+ UNSIGNED32 ENTRYPOINT ads_disconnect(a_ads_connection *poConnect);
214
+ UNSIGNED32 ENTRYPOINT ads_error(a_ads_connection *poConnect, UNSIGNED8 *pucError, UNSIGNED32 ulLength);
215
+ UNSIGNED32 ENTRYPOINT ads_execute(ADSHANDLE hStatement);
216
+ ADSHANDLE ENTRYPOINT ads_execute_direct(a_ads_connection *poConnect, UNSIGNED8 *pucSQL);
217
+ UNSIGNED32 ENTRYPOINT ads_execute_immediate(a_ads_connection *poConnect, UNSIGNED8 *pucSQL);
218
+ UNSIGNED32 ENTRYPOINT ads_fetch_absolute(ADSHANDLE hStatement, UNSIGNED32 ulRowNum);
219
+ UNSIGNED32 ENTRYPOINT ads_fetch_next(ADSHANDLE hStatement);
220
+ UNSIGNED32 ENTRYPOINT ads_fini(void);
221
+ UNSIGNED32 ENTRYPOINT ads_free_connection(a_ads_connection *poConnect);
222
+ UNSIGNED32 ENTRYPOINT ads_free_stmt(ADSHANDLE hStatement);
223
+ UNSIGNED32 ENTRYPOINT ads_get_bind_param_info(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param_info *info);
224
+ UNSIGNED32 ENTRYPOINT ads_get_column(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_data_value *buffer);
225
+ UNSIGNED32 ENTRYPOINT ads_get_column_info(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_column_info *buffer);
226
+ UNSIGNED32 ENTRYPOINT ads_get_data(ADSHANDLE hStatement, UNSIGNED32 ulIndex, UNSIGNED32 ulOffset, void *buffer, UNSIGNED32 ulLength);
227
+ UNSIGNED32 ENTRYPOINT ads_get_data_info(ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_data_info *buffer);
228
+ UNSIGNED32 ENTRYPOINT ads_get_next_result(ADSHANDLE hStatement);
229
+ UNSIGNED32 ENTRYPOINT ads_init(UNSIGNED8 *app_name, UNSIGNED32 api_version, UNSIGNED32 *version_available);
230
+ a_ads_connection_ptr ENTRYPOINT ads_make_connection(void *arg);
231
+ a_ads_connection_ptr ENTRYPOINT ads_new_connection(void);
232
+ UNSIGNED32 ENTRYPOINT ads_num_cols(ADSHANDLE hStatement);
233
+ UNSIGNED32 ENTRYPOINT ads_num_params(ADSHANDLE hStatement);
234
+ UNSIGNED32 ENTRYPOINT ads_num_rows(ADSHANDLE hStatement);
235
+ ADSHANDLE ENTRYPOINT ads_prepare(a_ads_connection *poConnect, UNSIGNED8 *pucSQL, UNSIGNED8 ucIsUnicode);
236
+ UNSIGNED32 ENTRYPOINT ads_reset(ADSHANDLE hStatement);
237
+ UNSIGNED32 ENTRYPOINT ads_rollback(a_ads_connection *poConnect);
238
+ UNSIGNED32 ENTRYPOINT ads_send_param_data(ADSHANDLE hStatement, UNSIGNED32 ulIndex, UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength);
239
+ UNSIGNED32 ENTRYPOINT ads_sqlstate(a_ads_connection *poConnect, UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength);
240
+
241
+ #ifdef __cplusplus
242
+ }
243
+ #endif
244
+
245
+ #endif // __DBCAPI_INCLUDED__
@@ -0,0 +1,30 @@
1
+ #====================================================
2
+ #
3
+ # Copyright 2008-2010 iAnywhere Solutions, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ #
20
+ #====================================================
21
+
22
+ require 'mkmf'
23
+
24
+ CONFIG["debugflags"] = "-ggdb3"
25
+ CONFIG["optflags"] = "-O0"
26
+
27
+ dir_config('ADS')
28
+
29
+ create_makefile("advantage")
30
+
@@ -0,0 +1,332 @@
1
+ #====================================================
2
+ #
3
+ # Copyright 2008-2010 iAnywhere Solutions, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ #
20
+ #====================================================
21
+
22
+ require "test/unit"
23
+ require "date"
24
+
25
+ begin
26
+ require "rubygems"
27
+ unless defined? Advantage
28
+ require "advantage"
29
+ # require_relative "../lib/advantage/advantage.so"
30
+ end
31
+ end
32
+
33
+ class Types
34
+ A_INVALID_TYPE = 0
35
+ A_BINARY = 1
36
+ A_STRING = 2
37
+ A_DOUBLE = 3
38
+ A_VAL64 = 4
39
+ A_UVAL64 = 5
40
+ A_VAL32 = 6
41
+ A_UVAL32 = 7
42
+ A_VAL16 = 8
43
+ A_UVAL16 = 9
44
+ A_VAL8 = 10
45
+ A_UVAL8 = 11
46
+ A_NCHAR = 12
47
+ A_DECIMAL = 13
48
+ A_DATE = 14
49
+ A_TIME = 15
50
+ A_TIMESTAMP = 16
51
+ end
52
+
53
+ class Direction
54
+ DD_INVALID = 0
55
+ DD_INPUT = 1
56
+ DD_OUTPUT = 2
57
+ DD_INPUT_OUTPUT = 3
58
+ end
59
+
60
+ class Advantage_Test < Test::Unit::TestCase
61
+ def setup
62
+ @api = Advantage::AdvantageInterface.new()
63
+ assert_not_nil @api
64
+ assert_nothing_raised do
65
+ Advantage::API.ads_initialize_interface(@api)
66
+ end
67
+ assert_nothing_raised do
68
+ @api.ads_init()
69
+ end
70
+ @conn = @api.ads_new_connection()
71
+ assert_not_nil @conn
72
+ # conn_str = "data source=c:\\test\\ruby.add;user id=adssys;DateFormat=YYYY-MM-DD"
73
+ conn_str = "data source=//172.30.16.1:6262/c\$/ads/db/test/ruby.add;user id=adssys;DateFormat=YYYY-MM-DD;CommType=TCP_IP;Compression=INTERNET"
74
+ assert_succeeded @api.ads_connect(@conn, conn_str)
75
+ end
76
+
77
+ def teardown
78
+ assert_succeeded @api.ads_execute_immediate(@conn, "SELECT 1 FROM system.iota")
79
+ assert_nil @api.ads_disconnect(@conn)
80
+ assert_failed @api.ads_execute_immediate(@conn, "SELECT 1 FROM system.iota")
81
+ assert_nil @api.ads_free_connection(@conn)
82
+ assert_nothing_raised do
83
+ @api.ads_fini()
84
+ end
85
+ assert_nothing_raised do
86
+ Advantage::API.ads_finalize_interface(@api)
87
+ end
88
+ end
89
+
90
+ def test_execute_immediate
91
+ assert_succeeded @api.ads_execute_immediate(@conn, "SELECT 1 FROM system.iota")
92
+ end
93
+
94
+ #EJS - Need to update the EQUAL, etc.
95
+ def test_errors
96
+ sql = "INSERT INTO test(\"id\") VALUES('test');"
97
+ assert_failed @api.ads_execute_immediate(@conn, sql)
98
+ code, msg = @api.ads_error(@conn)
99
+ assert_equal 7200, code
100
+ assert_not_equal "", msg
101
+ assert_equal "S0000", @api.ads_sqlstate(@conn)
102
+ assert_nil @api.ads_clear_error(@conn)
103
+ code, msg = @api.ads_error(@conn)
104
+ assert_equal 0, code
105
+ assert_equal "", msg
106
+ end
107
+
108
+ def test_rollback
109
+ @api.AdsBeginTransaction(@conn)
110
+ id = setup_transaction
111
+ @api.ads_rollback(@conn)
112
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
113
+ rs = exec_direct_with_test(sql)
114
+ assert_failed @api.ads_fetch_next(rs)
115
+ end
116
+
117
+ def test_commit
118
+ id = setup_transaction
119
+ @api.ads_commit(@conn)
120
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
121
+ rs = exec_direct_with_test(sql)
122
+ assert_succeeded @api.ads_fetch_next(rs)
123
+ res, ret_id = @api.ads_get_column(rs, 0)
124
+ assert_succeeded res
125
+ assert_not_nil ret_id
126
+ assert_equal id, ret_id
127
+ assert_failed @api.ads_fetch_next(rs)
128
+ end
129
+
130
+ def test_column_info
131
+ rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
132
+ assert_equal 12, @api.ads_num_cols(rs)
133
+ assert_column_info(rs, 0, "id", Types::A_VAL32, 4)
134
+ assert_column_info(rs, 1, "_blob_", Types::A_BINARY, 9)
135
+ assert_column_info(rs, 2, "_numeric_", Types::A_DECIMAL, 5)
136
+ assert_column_info(rs, 3, "_char_", Types::A_STRING, 255)
137
+ assert_column_info(rs, 4, "_memo_", Types::A_STRING, 9)
138
+ assert_column_info(rs, 5, "_int_", Types::A_VAL32, 4)
139
+ assert_column_info(rs, 6, "_short_", Types::A_VAL16, 2)
140
+ assert_column_info(rs, 7, "_logical_", Types::A_UVAL8, 1)
141
+ assert_column_info(rs, 8, "_date_", Types::A_DATE, 4)
142
+ assert_column_info(rs, 9, "_timestamp_", Types::A_TIMESTAMP, 8)
143
+ assert_column_info(rs, 10, "_double_", Types::A_DOUBLE, 8)
144
+ assert_nil @api.ads_free_stmt(rs)
145
+ end
146
+
147
+ #EJS - Check out return values
148
+ #BLOB, LOGICAL
149
+ def test_bounds_on_types
150
+ rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
151
+ assert_succeeded @api.ads_fetch_next(rs)
152
+ assert_class_and_value(rs, String, 1, "x") #Blob
153
+ assert_class_and_value(rs, String, 2, " 1.10")
154
+ assert_class_and_value(rs, String, 3, "Bounded String Test ")
155
+ assert_class_and_value(rs, String, 4, "Unbounded String Test")
156
+ assert_class_and_value(rs, Integer, 5, 1)
157
+ assert_class_and_value(rs, Integer, 6, 1)
158
+ assert_class_and_value(rs, Integer, 7, 1) #Logical
159
+ assert_date_and_time(rs, Date, 8, Date.new(1999, 1, 2))
160
+ assert_date_and_time(rs, DateTime, 9, DateTime.new(1999, 1, 2, 21, 20, 53))
161
+ assert_class_and_float_value(rs, Float, 10, 3.402823e+38, 1e+32)
162
+
163
+ assert_succeeded @api.ads_fetch_next(rs)
164
+ assert_class_and_value(rs, String, 1, 255.chr) #Blob
165
+ assert_class_and_value(rs, String, 2, "-1.10")
166
+ assert_class_and_value(rs, String, 3, " ")
167
+ assert_class_and_value(rs, NilClass, 4, nil)
168
+ assert_class_and_value(rs, Integer, 5, 0)
169
+ assert_class_and_value(rs, Integer, 6, 0)
170
+ assert_class_and_value(rs, Integer, 7, 0) #Logical
171
+ assert_class_and_value(rs, NilClass, 8, nil)
172
+ assert_class_and_value(rs, NilClass, 9, nil)
173
+ assert_class_and_float_value(rs, Float, 10, -3.402823e+38, 1e+32)
174
+ assert_nil @api.ads_free_stmt(rs)
175
+ end
176
+
177
+ def test_prepared_stmt
178
+ stmt = @api.ads_prepare(@conn, "SELECT * FROM \"types\" WHERE \"id\" = ?")
179
+ assert_not_nil stmt
180
+ assert_equal 1, @api.ads_num_params(stmt)
181
+ res, param = @api.ads_describe_bind_param(stmt, 0)
182
+ assert_not_equal 0, res
183
+ assert_equal Direction::DD_INPUT, param.get_direction()
184
+ #assert_failed @api.ads_execute(stmt)
185
+
186
+ assert_nil param.set_value(0)
187
+ @api.ads_bind_param(stmt, 0, param)
188
+ assert_succeeded @api.ads_execute(stmt)
189
+ assert_succeeded @api.ads_fetch_next(stmt)
190
+ assert_class_and_value(stmt, String, 3, "Bounded String Test ")
191
+
192
+ @api.ads_reset(stmt)
193
+ assert_nil param.set_value(1)
194
+ @api.ads_bind_param(stmt, 0, param)
195
+ assert_succeeded @api.ads_execute(stmt)
196
+ assert_succeeded @api.ads_fetch_next(stmt)
197
+ assert_class_and_value(stmt, String, 3, " ")
198
+
199
+ assert_nil @api.ads_free_stmt(stmt)
200
+ end
201
+
202
+ def test_insert_numeric
203
+ assert_insert("_numeric_", " 1.10", String)
204
+ end
205
+
206
+ def test_insert_char
207
+ assert_insert("_char_", "Bounded String Test ", String)
208
+ end
209
+
210
+ def test_insert_memo
211
+ assert_insert("_memo_", "Unbounded String Test", String)
212
+ end
213
+
214
+ def test_insert_int32
215
+ assert_insert("_int_", 2147483646, Integer)
216
+ assert_insert("_int_", -2147483646, Integer)
217
+ end
218
+
219
+ def test_insert_int8
220
+ assert_insert("_short_", 32767, Integer)
221
+ assert_insert("_short_", -32767, Integer)
222
+ end
223
+
224
+ def test_insert_date
225
+ assert_insert("_date_", Date.new(1999, 1, 2), Date)
226
+ end
227
+
228
+ def test_insert_timestamp
229
+ assert_insert("_timestamp_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
230
+ end
231
+
232
+ def test_insert_double
233
+ assert_insert("_double_", 1.797, Float, 1e+38)
234
+ end
235
+
236
+ def assert_insert(column_name, value, type, delta = nil)
237
+ @api.AdsBeginTransaction(@conn)
238
+ stmt = @api.ads_prepare(@conn, 'INSERT INTO "types"("id", "' + column_name + '", "_logical_") VALUES(3, ?, true)')
239
+ assert_not_nil stmt
240
+ res, param = @api.ads_describe_bind_param(stmt, 0)
241
+ if type == Date or type == DateTime
242
+ assert_nil param.set_value(value.strftime("%F %T"))
243
+ else
244
+ assert_nil param.set_value(value)
245
+ end
246
+ @api.ads_bind_param(stmt, 0, param)
247
+ assert_succeeded @api.ads_execute(stmt)
248
+ assert_nil @api.ads_free_stmt(stmt)
249
+
250
+ rs = exec_direct_with_test('SELECT "' + column_name + '" FROM "types" WHERE "id" = 3')
251
+ assert_succeeded @api.ads_fetch_next(rs)
252
+ if type == Date or type == DateTime
253
+ assert_date_and_time(rs, type, 0, value)
254
+ elsif type == Float
255
+ assert_class_and_float_value(rs, type, 0, value, delta)
256
+ else
257
+ assert_class_and_value(rs, type, 0, value)
258
+ end
259
+
260
+ assert_nil @api.ads_free_stmt(rs)
261
+
262
+ @api.ads_rollback(@conn)
263
+ end
264
+
265
+ def assert_column_info(rs, pos, expected_col_name, expected_col_type, expected_col_size)
266
+ res, col_num, col_name, col_type, col_native_type, col_precision, col_scale, col_size, col_nullable = @api.ads_get_column_info(rs, pos)
267
+ assert_succeeded res
268
+ assert_equal expected_col_name, col_name
269
+ assert_equal expected_col_type, col_type
270
+ assert_equal expected_col_size, col_size
271
+ end
272
+
273
+ def assert_class_and_float_value(rs, cl, pos, expected_value, allowed_delta)
274
+ res, val = @api.ads_get_column(rs, pos)
275
+ assert_succeeded res
276
+ assert_not_nil val unless expected_value.nil?
277
+ assert_in_delta expected_value, val, allowed_delta
278
+ assert_instance_of cl, val
279
+ end
280
+
281
+ def assert_date_and_time(rs, cl, pos, expected_value)
282
+ res, val = @api.ads_get_column(rs, pos)
283
+ assert_succeeded res
284
+ assert_not_nil val unless expected_value.nil?
285
+ parsed = cl.parse(val)
286
+ assert_equal expected_value, parsed
287
+ assert_instance_of cl, parsed
288
+ end
289
+
290
+ def assert_class_and_value(rs, cl, pos, expected_value)
291
+ res, val = @api.ads_get_column(rs, pos)
292
+ assert_succeeded res
293
+ assert_not_nil val unless expected_value.nil?
294
+ assert_equal expected_value, val
295
+ assert_instance_of cl, val
296
+ end
297
+
298
+ def setup_transaction
299
+ sql = "INSERT INTO test VALUES( DEFAULT );"
300
+ assert_succeeded @api.ads_execute_immediate(@conn, sql)
301
+
302
+ rs = exec_direct_with_test("SELECT LASTAUTOINC( CONNECTION ) FROM SYSTEM.IOTA")
303
+ assert_succeeded @api.ads_fetch_next(rs)
304
+ res, id = @api.ads_get_column(rs, 0)
305
+ assert_succeeded res
306
+ assert_not_nil id
307
+
308
+ sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
309
+ rs = @api.ads_execute_direct(@conn, sql)
310
+ assert_not_nil rs
311
+
312
+ assert_succeeded @api.ads_fetch_next(rs)
313
+ assert_failed @api.ads_fetch_next(rs)
314
+ assert_nil @api.ads_free_stmt(rs)
315
+ id
316
+ end
317
+
318
+ def exec_direct_with_test(sql)
319
+ rs = @api.ads_execute_direct(@conn, sql)
320
+ code, msg = @api.ads_error(@conn)
321
+ assert_not_nil rs, "SQL Code: #{code}; Message: #{msg}"
322
+ rs
323
+ end
324
+
325
+ def assert_succeeded(val)
326
+ assert_not_equal 0, val, @api.ads_error(@conn)
327
+ end
328
+
329
+ def assert_failed(val)
330
+ assert_equal 0, val, @api.ads_error(@conn)
331
+ end
332
+ end