advantage 0.1.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +123 -0
- data/Rakefile +186 -0
- data/ext/Makefile +215 -0
- data/ext/ace.h +5143 -0
- data/ext/adscapidll.c +168 -0
- data/ext/adscapidll.h +245 -0
- data/ext/adscapidll.o +0 -0
- data/ext/advantage-i386-mingw32.def +2 -0
- data/ext/advantage.c +1800 -0
- data/ext/advantage.o +0 -0
- data/ext/advantage.so +0 -0
- data/ext/dbcapi.h +249 -0
- data/ext/extconf.rb +27 -0
- data/lib/advantage.so +0 -0
- data/test/advantage_test.rb +332 -0
- data/test/test.sql +64 -0
- metadata +72 -0
data/ext/advantage.o
ADDED
Binary file
|
data/ext/advantage.so
ADDED
Binary file
|
data/ext/dbcapi.h
ADDED
@@ -0,0 +1,249 @@
|
|
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
|
+
|
180
|
+
// Dummy connection object we can create & destroy. This is needed since DBCAPI wants
|
181
|
+
// a connection object from the new_connection API. If we need to store connection
|
182
|
+
// specific info for DBCAPI connections we could store it in this structure as opposed
|
183
|
+
// to the ACE CCONNECTION object.
|
184
|
+
typedef struct A_ADS_CONNECTION_STRUCT
|
185
|
+
{
|
186
|
+
ADSHANDLE hConnect; // Real ADS connection, set via ads_connect
|
187
|
+
|
188
|
+
} a_ads_connection, *a_ads_connection_ptr;
|
189
|
+
|
190
|
+
typedef struct
|
191
|
+
{
|
192
|
+
UNSIGNED8 *pucData; // Data buffer for the column
|
193
|
+
UNSIGNED8 *pucColumnName; // Column name string
|
194
|
+
UNSIGNED32 ulBufferLength; // Length of buffer
|
195
|
+
UNSIGNED32 ulDataLength; // Length of data in the buffer
|
196
|
+
UNSIGNED32 ulIsNull; // T/F NULL flag
|
197
|
+
|
198
|
+
} DBCAPI_COLUMN;
|
199
|
+
|
200
|
+
|
201
|
+
// DBCAPI entrypoints (not published)
|
202
|
+
#ifdef __cplusplus
|
203
|
+
extern "C"
|
204
|
+
{
|
205
|
+
#endif
|
206
|
+
|
207
|
+
UNSIGNED32 ENTRYPOINT ads_affected_rows( ADSHANDLE hStatement );
|
208
|
+
UNSIGNED32 ENTRYPOINT ads_bind_param( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param *param );
|
209
|
+
void ENTRYPOINT ads_cancel( a_ads_connection *poConnect );
|
210
|
+
void ENTRYPOINT ads_clear_error( a_ads_connection *poConnect );
|
211
|
+
UNSIGNED32 ENTRYPOINT ads_client_version( UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength );
|
212
|
+
UNSIGNED32 ENTRYPOINT ads_commit( a_ads_connection *poConnect );
|
213
|
+
UNSIGNED32 ENTRYPOINT ads_connect( a_ads_connection *poConnect, UNSIGNED8 *pucConnectString );
|
214
|
+
UNSIGNED32 ENTRYPOINT ads_describe_bind_param( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param *param );
|
215
|
+
UNSIGNED32 ENTRYPOINT ads_disconnect( a_ads_connection *poConnect );
|
216
|
+
UNSIGNED32 ENTRYPOINT ads_error( a_ads_connection *poConnect, UNSIGNED8 *pucError, UNSIGNED32 ulLength );
|
217
|
+
UNSIGNED32 ENTRYPOINT ads_execute( ADSHANDLE hStatement );
|
218
|
+
ADSHANDLE ENTRYPOINT ads_execute_direct( a_ads_connection *poConnect, UNSIGNED8 *pucSQL );
|
219
|
+
UNSIGNED32 ENTRYPOINT ads_execute_immediate( a_ads_connection *poConnect, UNSIGNED8 *pucSQL );
|
220
|
+
UNSIGNED32 ENTRYPOINT ads_fetch_absolute( ADSHANDLE hStatement, UNSIGNED32 ulRowNum );
|
221
|
+
UNSIGNED32 ENTRYPOINT ads_fetch_next( ADSHANDLE hStatement );
|
222
|
+
UNSIGNED32 ENTRYPOINT ads_fini( void );
|
223
|
+
UNSIGNED32 ENTRYPOINT ads_free_connection( a_ads_connection *poConnect );
|
224
|
+
UNSIGNED32 ENTRYPOINT ads_free_stmt( ADSHANDLE hStatement );
|
225
|
+
UNSIGNED32 ENTRYPOINT ads_get_bind_param_info( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_bind_param_info *info );
|
226
|
+
UNSIGNED32 ENTRYPOINT ads_get_column( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_data_value *buffer );
|
227
|
+
UNSIGNED32 ENTRYPOINT ads_get_column_info( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_column_info *buffer );
|
228
|
+
UNSIGNED32 ENTRYPOINT ads_get_data( ADSHANDLE hStatement, UNSIGNED32 ulIndex, UNSIGNED32 ulOffset, void *buffer, UNSIGNED32 ulLength );
|
229
|
+
UNSIGNED32 ENTRYPOINT ads_get_data_info( ADSHANDLE hStatement, UNSIGNED32 ulIndex, a_ads_data_info *buffer );
|
230
|
+
UNSIGNED32 ENTRYPOINT ads_get_next_result( ADSHANDLE hStatement );
|
231
|
+
UNSIGNED32 ENTRYPOINT ads_init( UNSIGNED8 *app_name, UNSIGNED32 api_version, UNSIGNED32 *version_available );
|
232
|
+
a_ads_connection_ptr ENTRYPOINT ads_make_connection( void *arg );
|
233
|
+
a_ads_connection_ptr ENTRYPOINT ads_new_connection( void );
|
234
|
+
UNSIGNED32 ENTRYPOINT ads_num_cols( ADSHANDLE hStatement );
|
235
|
+
UNSIGNED32 ENTRYPOINT ads_num_params( ADSHANDLE hStatement );
|
236
|
+
UNSIGNED32 ENTRYPOINT ads_num_rows( ADSHANDLE hStatement );
|
237
|
+
ADSHANDLE ENTRYPOINT ads_prepare( a_ads_connection *poConnect, UNSIGNED8 *pucSQL, UNSIGNED8 ucIsUnicode );
|
238
|
+
UNSIGNED32 ENTRYPOINT ads_reset( ADSHANDLE hStatement );
|
239
|
+
UNSIGNED32 ENTRYPOINT ads_rollback( a_ads_connection *poConnect );
|
240
|
+
UNSIGNED32 ENTRYPOINT ads_send_param_data( ADSHANDLE hStatement, UNSIGNED32 ulIndex, UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength );
|
241
|
+
UNSIGNED32 ENTRYPOINT ads_sqlstate( a_ads_connection *poConnect, UNSIGNED8 *pucBuffer, UNSIGNED32 ulLength );
|
242
|
+
|
243
|
+
|
244
|
+
#ifdef __cplusplus
|
245
|
+
}
|
246
|
+
#endif
|
247
|
+
|
248
|
+
#endif // __DBCAPI_INCLUDED__
|
249
|
+
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,27 @@
|
|
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
|
+
dir_config('ADS')
|
25
|
+
|
26
|
+
create_makefile("advantage")
|
27
|
+
|
data/lib/advantage.so
ADDED
Binary file
|
@@ -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
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Types
|
33
|
+
A_INVALID_TYPE= 0
|
34
|
+
A_BINARY = 1
|
35
|
+
A_STRING = 2
|
36
|
+
A_DOUBLE = 3
|
37
|
+
A_VAL64 = 4
|
38
|
+
A_UVAL64 = 5
|
39
|
+
A_VAL32 = 6
|
40
|
+
A_UVAL32 = 7
|
41
|
+
A_VAL16 = 8
|
42
|
+
A_UVAL16 = 9
|
43
|
+
A_VAL8 = 10
|
44
|
+
A_UVAL8 = 11
|
45
|
+
A_NCHAR = 12
|
46
|
+
A_DECIMAL = 13
|
47
|
+
A_DATE = 14
|
48
|
+
A_TIME = 15
|
49
|
+
A_TIMESTAMP = 16
|
50
|
+
end
|
51
|
+
|
52
|
+
class Direction
|
53
|
+
DD_INVALID = 0
|
54
|
+
DD_INPUT = 1
|
55
|
+
DD_OUTPUT = 2
|
56
|
+
DD_INPUT_OUTPUT = 3
|
57
|
+
end
|
58
|
+
|
59
|
+
class Advantage_Test < Test::Unit::TestCase
|
60
|
+
def setup
|
61
|
+
@api = Advantage::AdvantageInterface.new()
|
62
|
+
assert_not_nil @api
|
63
|
+
assert_nothing_raised do
|
64
|
+
Advantage::API.ads_initialize_interface( @api )
|
65
|
+
end
|
66
|
+
assert_nothing_raised do
|
67
|
+
@api.ads_init()
|
68
|
+
end
|
69
|
+
@conn = @api.ads_new_connection()
|
70
|
+
assert_not_nil @conn
|
71
|
+
conn_str = "data source=c:\\test\\ruby.add;user id=adssys;DateFormat=YYYY-MM-DD"
|
72
|
+
assert_succeeded @api.ads_connect(@conn, conn_str)
|
73
|
+
end
|
74
|
+
|
75
|
+
def teardown
|
76
|
+
assert_succeeded @api.ads_execute_immediate(@conn, 'SELECT 1 FROM system.iota')
|
77
|
+
assert_nil @api.ads_disconnect(@conn)
|
78
|
+
assert_failed @api.ads_execute_immediate(@conn, 'SELECT 1 FROM system.iota')
|
79
|
+
assert_nil @api.ads_free_connection(@conn)
|
80
|
+
assert_nothing_raised do
|
81
|
+
@api.ads_fini()
|
82
|
+
end
|
83
|
+
assert_nothing_raised do
|
84
|
+
Advantage::API.ads_finalize_interface( @api )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_execute_immediate
|
89
|
+
assert_succeeded @api.ads_execute_immediate(@conn, 'SELECT 1 FROM system.iota')
|
90
|
+
end
|
91
|
+
|
92
|
+
#EJS - Need to update the EQUAL, etc.
|
93
|
+
def test_errors
|
94
|
+
sql = "INSERT INTO test(\"id\") VALUES('test');"
|
95
|
+
assert_failed @api.ads_execute_immediate(@conn, sql)
|
96
|
+
code, msg = @api.ads_error(@conn)
|
97
|
+
assert_equal 7200, code
|
98
|
+
assert_not_equal "", msg
|
99
|
+
assert_equal "S0000", @api.ads_sqlstate(@conn)
|
100
|
+
assert_nil @api.ads_clear_error(@conn)
|
101
|
+
code, msg = @api.ads_error(@conn)
|
102
|
+
assert_equal 0, code
|
103
|
+
assert_equal "", msg
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_rollback
|
107
|
+
@api.AdsBeginTransaction(@conn)
|
108
|
+
id = setup_transaction
|
109
|
+
@api.ads_rollback(@conn)
|
110
|
+
sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
|
111
|
+
rs = exec_direct_with_test(sql)
|
112
|
+
assert_failed @api.ads_fetch_next(rs)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_commit
|
116
|
+
id = setup_transaction
|
117
|
+
@api.ads_commit(@conn)
|
118
|
+
sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
|
119
|
+
rs = exec_direct_with_test(sql)
|
120
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
121
|
+
res, ret_id = @api.ads_get_column(rs, 0)
|
122
|
+
assert_succeeded res
|
123
|
+
assert_not_nil ret_id
|
124
|
+
assert_equal id, ret_id
|
125
|
+
assert_failed @api.ads_fetch_next(rs)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_column_info
|
129
|
+
rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
|
130
|
+
assert_equal 12, @api.ads_num_cols(rs)
|
131
|
+
assert_column_info(rs, 0, "id", Types::A_VAL32, 4)
|
132
|
+
assert_column_info(rs, 1, "_blob_", Types::A_BINARY, 9)
|
133
|
+
assert_column_info(rs, 2, "_numeric_", Types::A_DECIMAL, 4)
|
134
|
+
assert_column_info(rs, 3, "_char_", Types::A_STRING, 255)
|
135
|
+
assert_column_info(rs, 4, "_memo_", Types::A_STRING, 9)
|
136
|
+
assert_column_info(rs, 5, "_int_", Types::A_VAL32, 4)
|
137
|
+
assert_column_info(rs, 6, "_short_", Types::A_VAL16, 2)
|
138
|
+
assert_column_info(rs, 7, "_logical_", Types::A_UVAL8, 1)
|
139
|
+
assert_column_info(rs, 8, "_date_", Types::A_DATE, 4)
|
140
|
+
assert_column_info(rs, 9, "_timestamp_", Types::A_TIMESTAMP, 8)
|
141
|
+
assert_column_info(rs, 10, "_double_", Types::A_DOUBLE, 8)
|
142
|
+
assert_nil @api.ads_free_stmt(rs)
|
143
|
+
end
|
144
|
+
|
145
|
+
#EJS - Check out return values
|
146
|
+
#BLOB, LOGICAL
|
147
|
+
def test_bounds_on_types
|
148
|
+
rs = exec_direct_with_test("SELECT TOP 2 * FROM \"types\" ORDER BY \"id\"")
|
149
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
150
|
+
assert_class_and_value(rs, String, 1, "x") #Blob
|
151
|
+
assert_class_and_value(rs, String, 2, " 1.10")
|
152
|
+
assert_class_and_value(rs, String, 3, 'Bounded String Test ')
|
153
|
+
assert_class_and_value(rs, String, 4, 'Unbounded String Test')
|
154
|
+
assert_class_and_value(rs, Fixnum, 5, 1)
|
155
|
+
assert_class_and_value(rs, Fixnum, 6, 1)
|
156
|
+
assert_class_and_value(rs, Fixnum, 7, 1) #Logical
|
157
|
+
assert_date_and_time(rs, Date, 8, Date.new(1999, 1, 2))
|
158
|
+
assert_date_and_time(rs, DateTime, 9, DateTime.new(1999, 1, 2, 21, 20, 53))
|
159
|
+
assert_class_and_float_value(rs, Float, 10, 3.402823e+38, 1e+32 )
|
160
|
+
|
161
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
162
|
+
assert_class_and_value(rs, String, 1, 255.chr) #Blob
|
163
|
+
assert_class_and_value(rs, String, 2, "-1.1")
|
164
|
+
assert_class_and_value(rs, String, 3, ' ')
|
165
|
+
assert_class_and_value(rs, NilClass, 4, nil)
|
166
|
+
assert_class_and_value(rs, Fixnum, 5, 0)
|
167
|
+
assert_class_and_value(rs, Fixnum, 6, 0)
|
168
|
+
assert_class_and_value(rs, Fixnum, 7, 0) #Logical
|
169
|
+
assert_class_and_value(rs, NilClass, 8, nil)
|
170
|
+
assert_class_and_value(rs, NilClass, 9, nil)
|
171
|
+
assert_class_and_float_value(rs, Float, 10, -3.402823e+38, 1e+32 )
|
172
|
+
assert_nil @api.ads_free_stmt(rs)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_prepared_stmt
|
176
|
+
stmt = @api.ads_prepare(@conn, "SELECT * FROM \"types\" WHERE \"id\" = ?")
|
177
|
+
assert_not_nil stmt
|
178
|
+
assert_equal 1, @api.ads_num_params(stmt)
|
179
|
+
res, param = @api.ads_describe_bind_param(stmt, 0)
|
180
|
+
assert_not_equal 0, res
|
181
|
+
assert_equal Direction::DD_INPUT, param.get_direction()
|
182
|
+
#assert_failed @api.ads_execute(stmt)
|
183
|
+
|
184
|
+
assert_nil param.set_value(0);
|
185
|
+
@api.ads_bind_param(stmt, 0, param)
|
186
|
+
assert_succeeded @api.ads_execute(stmt)
|
187
|
+
assert_succeeded @api.ads_fetch_next(stmt)
|
188
|
+
assert_class_and_value(stmt, String, 3, "Bounded String Test ")
|
189
|
+
|
190
|
+
@api.ads_reset(stmt)
|
191
|
+
assert_nil param.set_value(1);
|
192
|
+
@api.ads_bind_param(stmt, 0, param)
|
193
|
+
assert_succeeded @api.ads_execute(stmt)
|
194
|
+
assert_succeeded @api.ads_fetch_next(stmt)
|
195
|
+
assert_class_and_value(stmt, String, 3, " ")
|
196
|
+
|
197
|
+
assert_nil @api.ads_free_stmt(stmt)
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_insert_numeric
|
201
|
+
assert_insert("_numeric_", " 1.10", String)
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_insert_char
|
205
|
+
assert_insert("_char_", "Bounded String Test ", String)
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_insert_memo
|
209
|
+
assert_insert("_memo_", "Unbounded String Test", String)
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_insert_int32
|
213
|
+
assert_insert("_int_", 2147483646, Bignum)
|
214
|
+
assert_insert("_int_", -2147483646, Bignum)
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_insert_int8
|
218
|
+
assert_insert("_short_", 32767, Fixnum)
|
219
|
+
assert_insert("_short_", -32767, Fixnum)
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_insert_date
|
223
|
+
assert_insert("_date_", Date.new(1999, 1, 2), Date)
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_insert_timestamp
|
227
|
+
assert_insert("_timestamp_", DateTime.new(1999, 1, 2, 21, 20, 53), DateTime)
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_insert_double
|
231
|
+
assert_insert("_double_", 1.797, Float, 1e+38)
|
232
|
+
end
|
233
|
+
|
234
|
+
def assert_insert(column_name, value, type, delta = nil)
|
235
|
+
@api.AdsBeginTransaction(@conn)
|
236
|
+
stmt = @api.ads_prepare(@conn, 'INSERT INTO "types"("id", "' + column_name + '", "_logical_") VALUES(3, ?, true)')
|
237
|
+
assert_not_nil stmt
|
238
|
+
res, param = @api.ads_describe_bind_param(stmt, 0)
|
239
|
+
if type == Date or type == DateTime then
|
240
|
+
assert_nil param.set_value(value.strftime("%F %T"));
|
241
|
+
else
|
242
|
+
assert_nil param.set_value(value);
|
243
|
+
end
|
244
|
+
@api.ads_bind_param(stmt, 0, param)
|
245
|
+
assert_succeeded @api.ads_execute(stmt)
|
246
|
+
assert_nil @api.ads_free_stmt(stmt)
|
247
|
+
|
248
|
+
rs = exec_direct_with_test('SELECT "' + column_name + '" FROM "types" WHERE "id" = 3')
|
249
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
250
|
+
if type == Date or type == DateTime then
|
251
|
+
assert_date_and_time(rs, type, 0, value)
|
252
|
+
elsif type == Float
|
253
|
+
assert_class_and_float_value(rs, type, 0, value, delta)
|
254
|
+
else
|
255
|
+
assert_class_and_value(rs, type, 0, value)
|
256
|
+
end
|
257
|
+
|
258
|
+
assert_nil @api.ads_free_stmt(rs)
|
259
|
+
|
260
|
+
@api.ads_rollback(@conn)
|
261
|
+
end
|
262
|
+
|
263
|
+
def assert_column_info(rs, pos, expected_col_name, expected_col_type, expected_col_size)
|
264
|
+
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);
|
265
|
+
assert_succeeded res
|
266
|
+
assert_equal expected_col_name, col_name
|
267
|
+
assert_equal expected_col_type, col_type
|
268
|
+
assert_equal expected_col_size, col_size
|
269
|
+
end
|
270
|
+
|
271
|
+
def assert_class_and_float_value(rs, cl, pos, expected_value, allowed_delta)
|
272
|
+
res, val = @api.ads_get_column(rs, pos)
|
273
|
+
assert_succeeded res
|
274
|
+
assert_not_nil val unless expected_value.nil?
|
275
|
+
assert_in_delta expected_value, val, allowed_delta
|
276
|
+
assert_instance_of cl, val
|
277
|
+
end
|
278
|
+
|
279
|
+
def assert_date_and_time(rs, cl, pos, expected_value)
|
280
|
+
res, val = @api.ads_get_column(rs, pos)
|
281
|
+
assert_succeeded res
|
282
|
+
assert_not_nil val unless expected_value.nil?
|
283
|
+
parsed = cl.parse(val)
|
284
|
+
assert_equal expected_value, parsed
|
285
|
+
assert_instance_of cl, parsed
|
286
|
+
end
|
287
|
+
|
288
|
+
def assert_class_and_value(rs, cl, pos, expected_value)
|
289
|
+
res, val = @api.ads_get_column(rs, pos)
|
290
|
+
assert_succeeded res
|
291
|
+
assert_not_nil val unless expected_value.nil?
|
292
|
+
assert_equal expected_value, val
|
293
|
+
assert_instance_of cl, val
|
294
|
+
end
|
295
|
+
|
296
|
+
def setup_transaction
|
297
|
+
sql = "INSERT INTO test VALUES( DEFAULT );"
|
298
|
+
assert_succeeded @api.ads_execute_immediate(@conn, sql)
|
299
|
+
|
300
|
+
rs = exec_direct_with_test("SELECT LASTAUTOINC( CONNECTION ) FROM SYSTEM.IOTA")
|
301
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
302
|
+
res, id = @api.ads_get_column(rs, 0)
|
303
|
+
assert_succeeded res
|
304
|
+
assert_not_nil id
|
305
|
+
|
306
|
+
sql = "SELECT * FROM test where \"id\" = " + id.to_s + ";"
|
307
|
+
rs = @api.ads_execute_direct(@conn, sql)
|
308
|
+
assert_not_nil rs
|
309
|
+
|
310
|
+
assert_succeeded @api.ads_fetch_next(rs)
|
311
|
+
assert_failed @api.ads_fetch_next(rs)
|
312
|
+
assert_nil @api.ads_free_stmt(rs)
|
313
|
+
id
|
314
|
+
end
|
315
|
+
|
316
|
+
def exec_direct_with_test(sql)
|
317
|
+
rs = @api.ads_execute_direct(@conn, sql)
|
318
|
+
code, msg = @api.ads_error(@conn)
|
319
|
+
assert_not_nil rs, "SQL Code: #{code}; Message: #{msg}"
|
320
|
+
rs
|
321
|
+
end
|
322
|
+
|
323
|
+
def assert_succeeded(val)
|
324
|
+
assert_not_equal 0, val, @api.ads_error(@conn)
|
325
|
+
end
|
326
|
+
|
327
|
+
def assert_failed(val)
|
328
|
+
assert_equal 0, val, @api.ads_error(@conn)
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|