firebird 0.10.0
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitlab-ci.yml +27 -0
- data/.travis.yml +20 -0
- data/Gemfile +2 -0
- data/README.md +15 -0
- data/Rakefile +13 -0
- data/USAGE.txt +180 -0
- data/ext/fb/extconf.rb +93 -0
- data/ext/fb/fb_ext.c +3022 -0
- data/fb.gemspec +34 -0
- data/lib/fb.rb +23 -0
- data/lib/fb/version.rb +3 -0
- data/mkmf.cmd +1 -0
- data/test/ConnectionTestCases.rb +550 -0
- data/test/CursorTestCases.rb +294 -0
- data/test/DataTypesTestCases.rb +556 -0
- data/test/DatabaseTestCases.rb +183 -0
- data/test/EncodingTestCases.rb +39 -0
- data/test/NumericDataTypesTestCases.rb +588 -0
- data/test/TransactionTestCases.rb +270 -0
- data/test/test_helper.rb +91 -0
- metadata +108 -0
@@ -0,0 +1,294 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class CursorTestCases < FbTestCase
|
4
|
+
def test_fetch_array
|
5
|
+
Database.create(@parms) do |connection|
|
6
|
+
connection.execute("select * from rdb$database") do |cursor|
|
7
|
+
assert_instance_of Cursor, cursor
|
8
|
+
row = cursor.fetch :array
|
9
|
+
assert_instance_of Array, row
|
10
|
+
if @fb_version == 3
|
11
|
+
assert_equal 5, row.size
|
12
|
+
else
|
13
|
+
assert_equal 4, row.size
|
14
|
+
end
|
15
|
+
end
|
16
|
+
connection.execute("select * from rdb$database where rdb$description = 'bogus'") do |cursor|
|
17
|
+
assert_instance_of Cursor, cursor
|
18
|
+
row = cursor.fetch :array
|
19
|
+
assert_instance_of NilClass, row
|
20
|
+
assert_nil row
|
21
|
+
end
|
22
|
+
connection.drop
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_fetch_hash
|
27
|
+
Database.create(@parms) do |connection|
|
28
|
+
connection.execute("select * from rdb$database") do |cursor|
|
29
|
+
assert_instance_of Cursor, cursor
|
30
|
+
row = cursor.fetch :hash
|
31
|
+
assert_instance_of Hash, row
|
32
|
+
if @fb_version == 3
|
33
|
+
assert_equal 5, row.size
|
34
|
+
else
|
35
|
+
assert_equal 4, row.size
|
36
|
+
end
|
37
|
+
end
|
38
|
+
connection.execute("select * from rdb$database where rdb$description = 'bogus'") do |cursor|
|
39
|
+
assert_instance_of Cursor, cursor
|
40
|
+
row = cursor.fetch :hash
|
41
|
+
assert_instance_of NilClass, row
|
42
|
+
assert_nil row
|
43
|
+
end
|
44
|
+
connection.drop
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_fetch_all_array
|
49
|
+
Database.create(@parms) do |connection|
|
50
|
+
connection.execute("select * from rdb$database") do |cursor|
|
51
|
+
assert_instance_of Cursor, cursor
|
52
|
+
rows = cursor.fetchall :array
|
53
|
+
assert_instance_of Array, rows
|
54
|
+
assert_equal 1, rows.size
|
55
|
+
assert_instance_of Array, rows[0]
|
56
|
+
if @fb_version == 3
|
57
|
+
assert_equal 5, rows[0].size
|
58
|
+
else
|
59
|
+
assert_equal 4, rows[0].size
|
60
|
+
end
|
61
|
+
end
|
62
|
+
connection.drop
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_fetch_all_hash
|
67
|
+
Database.create(@parms) do |connection|
|
68
|
+
connection.execute("select * from rdb$database") do |cursor|
|
69
|
+
assert_instance_of Cursor, cursor
|
70
|
+
rows = cursor.fetchall :hash
|
71
|
+
assert_instance_of Array, rows
|
72
|
+
assert_equal 1, rows.size
|
73
|
+
assert_instance_of Hash, rows[0]
|
74
|
+
if @fb_version == 3
|
75
|
+
assert_equal 5, rows[0].size
|
76
|
+
else
|
77
|
+
assert_equal 4, rows[0].size
|
78
|
+
end
|
79
|
+
end
|
80
|
+
connection.drop
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_fields_array
|
85
|
+
Database.create(@parms) do |connection|
|
86
|
+
connection.execute("select * from rdb$database") do |cursor|
|
87
|
+
fields = cursor.fields
|
88
|
+
fields_ary = cursor.fields :array
|
89
|
+
assert_equal fields, fields_ary
|
90
|
+
if @fb_version == 3
|
91
|
+
assert_equal 5, fields.size
|
92
|
+
else
|
93
|
+
assert_equal 4, fields.size
|
94
|
+
end
|
95
|
+
assert_equal "RDB$DESCRIPTION", fields[0].name;
|
96
|
+
assert_equal "RDB$RELATION_ID", fields[1].name;
|
97
|
+
assert_equal "RDB$SECURITY_CLASS", fields[2].name;
|
98
|
+
assert_equal "RDB$CHARACTER_SET_NAME", fields[3].name;
|
99
|
+
if @fb_version == 3
|
100
|
+
assert_equal "RDB$LINGER", fields[4].name;
|
101
|
+
end
|
102
|
+
end
|
103
|
+
connection.drop
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_fields_array_downcased
|
108
|
+
Database.create(@parms.merge(:downcase_names => true)) do |connection| # xxx true
|
109
|
+
connection.execute("select * from rdb$database") do |cursor|
|
110
|
+
fields = cursor.fields
|
111
|
+
fields_ary = cursor.fields :array
|
112
|
+
assert_equal fields, fields_ary
|
113
|
+
if @fb_version == 3
|
114
|
+
assert_equal 5, fields.size
|
115
|
+
else
|
116
|
+
assert_equal 4, fields.size
|
117
|
+
end
|
118
|
+
assert_equal "rdb$description", fields[0].name;
|
119
|
+
assert_equal "rdb$relation_id", fields[1].name;
|
120
|
+
assert_equal "rdb$security_class", fields[2].name;
|
121
|
+
assert_equal "rdb$character_set_name", fields[3].name;
|
122
|
+
if @fb_version == 3
|
123
|
+
assert_equal "rdb$linger", fields[4].name;
|
124
|
+
end
|
125
|
+
end
|
126
|
+
connection.drop
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_fields_hash
|
131
|
+
Database.create(@parms) do |connection|
|
132
|
+
connection.execute("select * from rdb$database") do |cursor|
|
133
|
+
fields = cursor.fields :hash
|
134
|
+
if @fb_version == 3
|
135
|
+
assert_equal 5, fields.size
|
136
|
+
else
|
137
|
+
assert_equal 4, fields.size
|
138
|
+
end
|
139
|
+
assert_equal 520, fields["RDB$DESCRIPTION"].type_code
|
140
|
+
assert_equal 500, fields["RDB$RELATION_ID"].type_code
|
141
|
+
assert_equal 452, fields["RDB$SECURITY_CLASS"].type_code
|
142
|
+
assert_equal 452, fields["RDB$CHARACTER_SET_NAME"].type_code
|
143
|
+
if @fb_version == 3
|
144
|
+
assert_equal 496, fields["RDB$LINGER"].type_code
|
145
|
+
end
|
146
|
+
end
|
147
|
+
connection.drop
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_fields_hash_downcased
|
152
|
+
Database.create(@parms.merge(:downcase_names => true)) do |connection| # xxx true
|
153
|
+
connection.execute("select * from rdb$database") do |cursor|
|
154
|
+
fields = cursor.fields :hash
|
155
|
+
if @fb_version == 3
|
156
|
+
assert_equal 5, fields.size
|
157
|
+
else
|
158
|
+
assert_equal 4, fields.size
|
159
|
+
end
|
160
|
+
assert_equal 520, fields["rdb$description"].type_code
|
161
|
+
assert_equal 500, fields["rdb$relation_id"].type_code
|
162
|
+
assert_equal 452, fields["rdb$security_class"].type_code
|
163
|
+
assert_equal 452, fields["rdb$character_set_name"].type_code
|
164
|
+
if @fb_version == 3
|
165
|
+
assert_equal 496, fields["rdb$linger"].type_code
|
166
|
+
end
|
167
|
+
end
|
168
|
+
connection.drop
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_each_array
|
173
|
+
Database.create(@parms) do |connection|
|
174
|
+
connection.execute("select * from rdb$database") do |cursor|
|
175
|
+
count = 0
|
176
|
+
cursor.each :array do |row|
|
177
|
+
count += 1
|
178
|
+
assert_instance_of Array, row
|
179
|
+
if @fb_version == 3
|
180
|
+
assert_equal 5, row.size
|
181
|
+
else
|
182
|
+
assert_equal 4, row.size
|
183
|
+
end
|
184
|
+
end
|
185
|
+
assert_equal 1, count
|
186
|
+
end
|
187
|
+
connection.drop
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_each_hash
|
192
|
+
Database.create(@parms) do |connection|
|
193
|
+
connection.execute("select * from rdb$database") do |cursor|
|
194
|
+
count = 0
|
195
|
+
cursor.each :hash do |row|
|
196
|
+
count += 1
|
197
|
+
assert_instance_of Hash, row
|
198
|
+
if @fb_version == 3
|
199
|
+
assert_equal 5, row.size
|
200
|
+
else
|
201
|
+
assert_equal 4, row.size
|
202
|
+
end
|
203
|
+
end
|
204
|
+
assert_equal 1, count
|
205
|
+
end
|
206
|
+
connection.drop
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_fetch_after_nil
|
211
|
+
Database.create(@parms) do |connection|
|
212
|
+
connection.execute("create generator test_seq");
|
213
|
+
connection.execute("select gen_id(test_seq, 1) from rdb$database") do |cursor|
|
214
|
+
r1 = cursor.fetch
|
215
|
+
assert !r1.nil?
|
216
|
+
r2 = cursor.fetch
|
217
|
+
assert_nil r2
|
218
|
+
assert_raises Error do
|
219
|
+
cursor.fetch
|
220
|
+
end
|
221
|
+
end
|
222
|
+
connection.execute("select * from rdb$database") do |cursor|
|
223
|
+
r1 = cursor.fetch
|
224
|
+
assert !r1.nil?
|
225
|
+
r2 = cursor.fetch
|
226
|
+
assert_nil r2
|
227
|
+
assert_raises Error do
|
228
|
+
cursor.fetch
|
229
|
+
end
|
230
|
+
end
|
231
|
+
connection.drop
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_fetch_hash_with_aliased_fields
|
236
|
+
sql = "SELECT RDB$DESCRIPTION DES, RDB$RELATION_ID REL, RDB$SECURITY_CLASS SEC, RDB$CHARACTER_SET_NAME FROM RDB$DATABASE"
|
237
|
+
Database.create(@parms) do |connection|
|
238
|
+
connection.execute(sql) do |cursor|
|
239
|
+
assert_instance_of Cursor, cursor
|
240
|
+
row = cursor.fetch :hash
|
241
|
+
assert_instance_of Hash, row
|
242
|
+
assert_equal 4, row.size
|
243
|
+
assert row.keys.include?("DES"), "No field DES"
|
244
|
+
assert row.keys.include?("REL"), "No field REL"
|
245
|
+
assert row.keys.include?("SEC"), "No field SEC"
|
246
|
+
assert row.keys.include?("RDB$CHARACTER_SET_NAME"), "No field RDB$CHARACTER_SET_NAME"
|
247
|
+
end
|
248
|
+
connection.drop
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_simultaneous_cursors
|
253
|
+
sql_schema = <<-END
|
254
|
+
CREATE TABLE MASTER (ID INT, NAME1 VARCHAR(10));
|
255
|
+
CREATE TABLE DETAIL (ID INT, MASTER_ID INT, NAME2 VARCHAR(10));
|
256
|
+
END
|
257
|
+
sql_insert_master = "INSERT INTO MASTER (ID, NAME1) VALUES (?, ?)"
|
258
|
+
sql_insert_detail = "INSERT INTO DETAIL (ID, MASTER_ID, NAME2) VALUES (?, ?, ?)"
|
259
|
+
sql_select_master = "SELECT * FROM MASTER ORDER BY ID"
|
260
|
+
sql_select_detail = "SELECT * FROM DETAIL ORDER BY ID"
|
261
|
+
Database.create(@parms) do |connection|
|
262
|
+
connection.execute_script(sql_schema)
|
263
|
+
connection.transaction do
|
264
|
+
3.times do |m|
|
265
|
+
connection.execute(sql_insert_master, m, "name_#{m}")
|
266
|
+
end
|
267
|
+
9.times do |d|
|
268
|
+
connection.execute(sql_insert_detail, d, d / 3, "name_#{d / 3}_#{d}")
|
269
|
+
end
|
270
|
+
end
|
271
|
+
master = connection.execute(sql_select_master)
|
272
|
+
begin
|
273
|
+
detail = connection.execute(sql_select_detail)
|
274
|
+
begin
|
275
|
+
3.times do |m|
|
276
|
+
mr = master.fetch
|
277
|
+
assert_equal m, mr[0]
|
278
|
+
assert_equal "name_#{m}", mr[1]
|
279
|
+
3.times do |d|
|
280
|
+
dr = detail.fetch
|
281
|
+
assert_equal m * 3 + d, dr[0]
|
282
|
+
assert_equal m, dr[1]
|
283
|
+
assert_equal "name_#{m}_#{m * 3 + d}", dr[2]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
ensure
|
287
|
+
detail.close
|
288
|
+
end
|
289
|
+
ensure
|
290
|
+
master.close
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
@@ -0,0 +1,556 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class DataTypesTestCases < FbTestCase
|
4
|
+
def gen_i(i)
|
5
|
+
i
|
6
|
+
end
|
7
|
+
|
8
|
+
def gen_si(i)
|
9
|
+
i
|
10
|
+
end
|
11
|
+
|
12
|
+
def gen_bi(i)
|
13
|
+
i * 1000000000
|
14
|
+
end
|
15
|
+
|
16
|
+
def gen_f(i)
|
17
|
+
i / 2
|
18
|
+
end
|
19
|
+
|
20
|
+
def gen_d(i)
|
21
|
+
i * 3333 / 2
|
22
|
+
end
|
23
|
+
|
24
|
+
def gen_c(i)
|
25
|
+
"%c" % (i + 64)
|
26
|
+
end
|
27
|
+
|
28
|
+
def gen_c10(i)
|
29
|
+
gen_c(i) * 5
|
30
|
+
end
|
31
|
+
|
32
|
+
def gen_vc(i)
|
33
|
+
gen_c(i)
|
34
|
+
end
|
35
|
+
|
36
|
+
def gen_vc10(i)
|
37
|
+
gen_c(i) * i
|
38
|
+
end
|
39
|
+
|
40
|
+
def gen_vc10000(i)
|
41
|
+
gen_c(i) * i * 1000
|
42
|
+
end
|
43
|
+
|
44
|
+
def gen_dt(i)
|
45
|
+
Date.civil(2000, i+1, i+1)
|
46
|
+
end
|
47
|
+
|
48
|
+
def gen_tm(i)
|
49
|
+
Time.utc(1990, 1, 1, 12, i, i)
|
50
|
+
end
|
51
|
+
|
52
|
+
def gen_ts(i)
|
53
|
+
Time.local(2006, 1, 1, i, i, i)
|
54
|
+
end
|
55
|
+
|
56
|
+
def gen_n92(i)
|
57
|
+
i * 100
|
58
|
+
end
|
59
|
+
|
60
|
+
def gen_d92(i)
|
61
|
+
i * 10000
|
62
|
+
end
|
63
|
+
|
64
|
+
def sum_i(range)
|
65
|
+
range.inject(0) { |m, i| m + gen_i(i) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def sum_si(range)
|
69
|
+
range.inject(0) { |m, i| m + gen_si(i) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def sum_bi(range)
|
73
|
+
range.inject(0) { |m, i| m + gen_bi(i) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def sum_f(range)
|
77
|
+
range.inject(0) { |m, i| m + gen_f(i) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def sum_d(range)
|
81
|
+
range.inject(0) { |m, i| m + gen_d(i) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def sum_n92(range)
|
85
|
+
range.inject(0) { |m, i| m + gen_n92(i) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def sum_d92(range)
|
89
|
+
range.inject(0) { |m, i| m + gen_d92(i) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_insert_basic_types
|
93
|
+
sql_schema = <<-END
|
94
|
+
create table TEST (
|
95
|
+
I INTEGER,
|
96
|
+
SI SMALLINT,
|
97
|
+
BI BIGINT,
|
98
|
+
F FLOAT,
|
99
|
+
D DOUBLE PRECISION,
|
100
|
+
C CHAR,
|
101
|
+
C10 CHAR(10),
|
102
|
+
VC VARCHAR(1),
|
103
|
+
VC10 VARCHAR(10),
|
104
|
+
VC10000 VARCHAR(10000),
|
105
|
+
DT DATE,
|
106
|
+
TM TIME,
|
107
|
+
TS TIMESTAMP,
|
108
|
+
N92 NUMERIC(9,2),
|
109
|
+
D92 DECIMAL(9,2),
|
110
|
+
N154 NUMERIC(15,4),
|
111
|
+
D185 DECIMAL(18,5));
|
112
|
+
END
|
113
|
+
sql_insert = <<-END
|
114
|
+
insert into test
|
115
|
+
(I, SI, BI, F, D, C, C10, VC, VC10, VC10000, DT, TM, TS, N92, D92, N154, D185)
|
116
|
+
values
|
117
|
+
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
118
|
+
END
|
119
|
+
sql_select = "select * from TEST order by I"
|
120
|
+
sql_sum = "select sum(I), sum(SI), sum(BI), sum(F), sum(D), sum(N92), sum(D92), sum(N154) from TEST"
|
121
|
+
sql_avg = "select avg(I), avg(SI), avg(BI), avg(F), avg(D), avg(N92), avg(D92), avg(N154) from TEST"
|
122
|
+
sql_max = "select max(I), max(SI), max(BI), max(F), max(D), max(N92), max(D92), max(N154) from TEST"
|
123
|
+
sql_min = "select min(I), min(SI), min(BI), min(F), min(D), min(N92), min(D92), min(N154) from TEST"
|
124
|
+
Database.create(@parms) do |connection|
|
125
|
+
connection.execute(sql_schema);
|
126
|
+
connection.transaction do
|
127
|
+
10.times do |i|
|
128
|
+
connection.execute(
|
129
|
+
sql_insert,
|
130
|
+
gen_i(i), gen_si(i), gen_bi(i),
|
131
|
+
gen_f(i), gen_d(i),
|
132
|
+
gen_c(i), gen_c10(i), gen_vc(i), gen_vc10(i), gen_vc10000(i),
|
133
|
+
gen_dt(i), gen_tm(i), gen_ts(i),
|
134
|
+
gen_n92(i), gen_d92(i), gen_n92(i), gen_d92(i))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
connection.execute(sql_select) do |cursor|
|
138
|
+
i = 0
|
139
|
+
cursor.each :hash do |row|
|
140
|
+
assert_equal gen_i(i), row["I"], "INTEGER"
|
141
|
+
assert_equal gen_si(i), row["SI"], "SMALLINT"
|
142
|
+
assert_equal gen_bi(i), row["BI"], "BIGINT"
|
143
|
+
assert_equal gen_f(i), row["F"], "FLOAT"
|
144
|
+
assert_equal gen_d(i), row["D"], "DOUBLE PRECISION"
|
145
|
+
assert_equal gen_c(i), row["C"], "CHAR"
|
146
|
+
assert_equal gen_c10(i).ljust(10), row["C10"], "CHAR(10)"
|
147
|
+
assert_equal gen_vc(i), row["VC"], "VARCHAR(1)"
|
148
|
+
assert_equal gen_vc10(i), row["VC10"], "VARCHAR(10)"
|
149
|
+
assert_equal gen_vc10000(i), row["VC10000"], "VARCHAR(10000)"
|
150
|
+
assert_equal gen_dt(i), row["DT"], "DATE"
|
151
|
+
assert_equal gen_tm(i).strftime("%H%M%S"), row["TM"].utc.strftime("%H%M%S"), "TIME"
|
152
|
+
assert_equal gen_ts(i), row["TS"], "TIMESTAMP"
|
153
|
+
assert_equal gen_n92(i), row["N92"], "NUMERIC"
|
154
|
+
assert_equal gen_d92(i), row["D92"], "DECIMAL"
|
155
|
+
assert_equal gen_n92(i), row["N154"], "NUMERIC"
|
156
|
+
assert_equal gen_d92(i), row["D185"], "DECIMAL"
|
157
|
+
i += 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
sums = connection.query(sql_sum).first
|
162
|
+
assert_equal sum_i(0...10), sums[0], "INTEGER"
|
163
|
+
assert_equal sum_si(0...10), sums[1], "SMALLINT"
|
164
|
+
assert_equal sum_bi(0...10), sums[2], "BIGINT"
|
165
|
+
assert_equal sum_f(0...10), sums[3], "FLOAT"
|
166
|
+
assert_equal sum_d(0...10), sums[4], "DOUBLE PRECISION"
|
167
|
+
assert_equal sum_n92(0...10), sums[5], "NUMERIC" # 4500.00
|
168
|
+
assert_equal sum_d92(0...10), sums[6], "DECIMAL" # 4500.00
|
169
|
+
assert_equal sum_n92(0...10), sums[7], "NUMERIC" # 4500.00
|
170
|
+
|
171
|
+
avgs = connection.query(sql_avg).first
|
172
|
+
assert_equal sum_i(0...10) / 10, avgs[0], "INTEGER"
|
173
|
+
assert_equal sum_si(0...10) / 10, avgs[1], "SMALLINT"
|
174
|
+
assert_equal sum_bi(0...10) / 10, avgs[2], "BIGINT"
|
175
|
+
assert_equal sum_f(0...10) / 10, avgs[3], "FLOAT"
|
176
|
+
assert_equal sum_d(0...10) / 10, avgs[4], "DOUBLE PRECISION"
|
177
|
+
assert_equal sum_n92(0...10) / 10, avgs[5], "NUMERIC" # 450.00
|
178
|
+
assert_equal sum_d92(0...10) / 10, avgs[6], "DECIMAL" # 450.00
|
179
|
+
assert_equal sum_n92(0...10) / 10, avgs[7], "NUMERIC" # 450.00
|
180
|
+
|
181
|
+
maxs = connection.query(sql_max).first
|
182
|
+
assert_equal gen_i(9), maxs[0], "INTEGER"
|
183
|
+
assert_equal gen_si(9), maxs[1], "SMALLINT"
|
184
|
+
assert_equal gen_bi(9), maxs[2], "BIGINT"
|
185
|
+
assert_equal gen_f(9), maxs[3], "FLOAT"
|
186
|
+
assert_equal gen_d(9), maxs[4], "DOUBLE PRECISION"
|
187
|
+
assert_equal gen_n92(9), maxs[5], "NUMERIC"
|
188
|
+
assert_equal gen_d92(9), maxs[6], "DECIMAL"
|
189
|
+
assert_equal gen_n92(9), maxs[7], "NUMERIC"
|
190
|
+
|
191
|
+
mins = connection.query(sql_min).first
|
192
|
+
assert_equal gen_i(0), mins[0], "INTEGER"
|
193
|
+
assert_equal gen_si(0), mins[1], "SMALLINT"
|
194
|
+
assert_equal gen_bi(0), mins[2], "BIGINT"
|
195
|
+
assert_equal gen_f(0), mins[3], "FLOAT"
|
196
|
+
assert_equal gen_d(0), mins[4], "DOUBLE PRECISION"
|
197
|
+
assert_equal gen_n92(0), mins[5], "NUMERIC"
|
198
|
+
assert_equal gen_d92(0), mins[6], "DECIMAL"
|
199
|
+
assert_equal gen_n92(0), mins[7], "NUMERIC"
|
200
|
+
connection.drop
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_insert_blobs_text
|
205
|
+
sql_schema = "create table test (id int, name varchar(20), memo blob sub_type text)"
|
206
|
+
sql_insert = "insert into test (id, name, memo) values (?, ?, ?)"
|
207
|
+
sql_select = "select * from test order by id"
|
208
|
+
Database.create(@parms) do |connection|
|
209
|
+
connection.execute(sql_schema);
|
210
|
+
memo = "x" * 65535
|
211
|
+
connection.transaction do
|
212
|
+
10.times do |i|
|
213
|
+
connection.execute(sql_insert, i, i.to_s, memo);
|
214
|
+
end
|
215
|
+
end
|
216
|
+
connection.execute(sql_select) do |cursor|
|
217
|
+
i = 0
|
218
|
+
cursor.each :hash do |row|
|
219
|
+
assert_equal i, row["ID"]
|
220
|
+
assert_equal i.to_s, row["NAME"]
|
221
|
+
assert_equal memo, row["MEMO"]
|
222
|
+
i += 1
|
223
|
+
end
|
224
|
+
end
|
225
|
+
connection.drop
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_insert_blobs_binary
|
230
|
+
sql_schema = "create table test (id int, name varchar(20), attachment blob segment size 1000)"
|
231
|
+
sql_insert = "insert into test (id, name, attachment) values (?, ?, ?)"
|
232
|
+
sql_select = "select * from test order by id"
|
233
|
+
Database.create(@parms) do |connection|
|
234
|
+
connection.execute(sql_schema);
|
235
|
+
attachment = SecureRandom.random_bytes(250_000)
|
236
|
+
connection.transaction do
|
237
|
+
3.times do |i|
|
238
|
+
connection.execute(sql_insert, i, i.to_s, attachment);
|
239
|
+
end
|
240
|
+
end
|
241
|
+
connection.execute(sql_select) do |cursor|
|
242
|
+
i = 0
|
243
|
+
cursor.each :array do |row|
|
244
|
+
assert_equal i, row[0], "ID's do not match"
|
245
|
+
assert_equal i.to_s, row[1], "NAME's do not match"
|
246
|
+
assert_equal attachment.size, row[2].size, "ATTACHMENT sizes do not match"
|
247
|
+
i += 1
|
248
|
+
end
|
249
|
+
end
|
250
|
+
connection.drop
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_insert_incorrect_types
|
255
|
+
cols = %w{ I SI BI F D C C10 VC VC10 VC10000 DT TM TS }
|
256
|
+
types = %w{ INTEGER SMALLINT BIGINT FLOAT DOUBLE\ PRECISION CHAR CHAR(10) VARCHAR(1) VARCHAR(10) VARCHAR(10000) DATE TIME TIMESTAMP }
|
257
|
+
sql_schema = "";
|
258
|
+
assert_equal cols.size, types.size
|
259
|
+
cols.size.times do |i|
|
260
|
+
sql_schema << "CREATE TABLE TEST_#{cols[i]} (VAL #{types[i]});\n"
|
261
|
+
end
|
262
|
+
Database.create(@parms) do |connection|
|
263
|
+
connection.execute_script(sql_schema)
|
264
|
+
cols.size.times do |i|
|
265
|
+
sql_insert = "INSERT INTO TEST_#{cols[i]} (VAL) VALUES (?);"
|
266
|
+
if cols[i] == 'I'
|
267
|
+
assert_raises TypeError do
|
268
|
+
connection.execute(sql_insert, {:five => "five"})
|
269
|
+
end
|
270
|
+
assert_raises TypeError do
|
271
|
+
connection.execute(sql_insert, Time.now)
|
272
|
+
end
|
273
|
+
assert_raises RangeError do
|
274
|
+
connection.execute(sql_insert, 5000000000)
|
275
|
+
end
|
276
|
+
elsif cols[i] == 'SI'
|
277
|
+
assert_raises TypeError do
|
278
|
+
connection.execute(sql_insert, {:five => "five"})
|
279
|
+
end
|
280
|
+
assert_raises TypeError do
|
281
|
+
connection.execute(sql_insert, Time.now)
|
282
|
+
end
|
283
|
+
assert_raises RangeError do
|
284
|
+
connection.execute(sql_insert, 100000)
|
285
|
+
end
|
286
|
+
elsif cols[i] == 'BI'
|
287
|
+
assert_raises TypeError do
|
288
|
+
connection.execute(sql_insert, {:five => "five"})
|
289
|
+
end
|
290
|
+
assert_raises TypeError do
|
291
|
+
connection.execute(sql_insert, Time.now)
|
292
|
+
end
|
293
|
+
assert_raises RangeError do
|
294
|
+
connection.execute(sql_insert, 184467440737095516160) # 2^64 * 10
|
295
|
+
end
|
296
|
+
elsif cols[i] == 'F'
|
297
|
+
assert_raises TypeError do
|
298
|
+
connection.execute(sql_insert, {:five => "five"})
|
299
|
+
end
|
300
|
+
assert_raises RangeError do
|
301
|
+
connection.execute(sql_insert, 10 ** 39)
|
302
|
+
end
|
303
|
+
elsif cols[i] == 'D'
|
304
|
+
assert_raises TypeError do
|
305
|
+
connection.execute(sql_insert, {:five => "five"})
|
306
|
+
end
|
307
|
+
elsif cols[i] == 'VC'
|
308
|
+
assert_raises RangeError do
|
309
|
+
connection.execute(sql_insert, "too long")
|
310
|
+
end
|
311
|
+
assert_raises RangeError do
|
312
|
+
connection.execute(sql_insert, 1.0/3.0)
|
313
|
+
end
|
314
|
+
elsif cols[i] == 'VC10'
|
315
|
+
assert_raises RangeError do
|
316
|
+
connection.execute(sql_insert, 1.0/3.0)
|
317
|
+
end
|
318
|
+
elsif cols[i].include?('VC10000')
|
319
|
+
assert_raises RangeError do
|
320
|
+
connection.execute(sql_insert, "X" * 10001)
|
321
|
+
end
|
322
|
+
elsif cols[i] == 'C'
|
323
|
+
assert_raises RangeError do
|
324
|
+
connection.execute(sql_insert, "too long")
|
325
|
+
end
|
326
|
+
elsif cols[i] == 'C10'
|
327
|
+
assert_raises RangeError do
|
328
|
+
connection.execute(sql_insert, Time.now)
|
329
|
+
end
|
330
|
+
elsif cols[i] == 'DT'
|
331
|
+
assert_raises ArgumentError do
|
332
|
+
connection.execute(sql_insert, Date)
|
333
|
+
end
|
334
|
+
assert_raises ArgumentError do
|
335
|
+
connection.execute(sql_insert, 2006)
|
336
|
+
end
|
337
|
+
elsif cols[i] == 'TM'
|
338
|
+
assert_raises TypeError do
|
339
|
+
connection.execute(sql_insert, {:date => "2006/1/1"})
|
340
|
+
end
|
341
|
+
assert_raises TypeError do
|
342
|
+
connection.execute(sql_insert, 10000)
|
343
|
+
end
|
344
|
+
elsif cols[i] == 'TS'
|
345
|
+
assert_raises TypeError do
|
346
|
+
connection.execute(sql_insert, 5.5)
|
347
|
+
end
|
348
|
+
assert_raises TypeError do
|
349
|
+
connection.execute(sql_insert, 10000)
|
350
|
+
end
|
351
|
+
elsif cols[i] == 'N92'
|
352
|
+
assert_raises TypeError do
|
353
|
+
connection.execute(sql_insert, {:five => "five"})
|
354
|
+
end
|
355
|
+
assert_raises TypeError do
|
356
|
+
connection.execute(sql_insert, Time.now)
|
357
|
+
end
|
358
|
+
assert_raises RangeError do
|
359
|
+
connection.execute(sql_insert, 5000000000)
|
360
|
+
end
|
361
|
+
elsif cols[i] == 'D92'
|
362
|
+
assert_raises TypeError do
|
363
|
+
connection.execute(sql_insert, {:five => "five"})
|
364
|
+
end
|
365
|
+
assert_raises TypeError do
|
366
|
+
connection.execute(sql_insert, Time.now)
|
367
|
+
end
|
368
|
+
assert_raises RangeError do
|
369
|
+
connection.execute(sql_insert, 5000000000)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
connection.drop
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def test_insert_correct_types
|
378
|
+
cols = %w{ I SI BI F D C C10 VC VC10 VC10000 DT TM TS N92 D92 N154 }
|
379
|
+
types = %w{ INTEGER SMALLINT BIGINT FLOAT DOUBLE\ PRECISION CHAR CHAR(10) VARCHAR(1) VARCHAR(10) VARCHAR(10000) DATE TIME TIMESTAMP NUMERIC(9,2) DECIMAL(9,2) NUMERIC(15,4) }
|
380
|
+
sql_schema = "";
|
381
|
+
assert_equal cols.size, types.size
|
382
|
+
cols.size.times do |i|
|
383
|
+
sql_schema << "CREATE TABLE TEST_#{cols[i]} (VAL #{types[i]});\n"
|
384
|
+
end
|
385
|
+
Database.create(@parms) do |connection|
|
386
|
+
connection.execute_script(sql_schema)
|
387
|
+
cols.size.times do |i|
|
388
|
+
sql_insert = "INSERT INTO TEST_#{cols[i]} (VAL) VALUES (?);"
|
389
|
+
sql_select = "SELECT * FROM TEST_#{cols[i]};"
|
390
|
+
if cols[i] == 'I'
|
391
|
+
connection.execute(sql_insert, 500_000)
|
392
|
+
connection.execute(sql_insert, "500_000")
|
393
|
+
vals = connection.query(sql_select)
|
394
|
+
assert_equal 500_000, vals[0][0]
|
395
|
+
assert_equal 500_000, vals[1][0]
|
396
|
+
elsif cols[i] == 'SI'
|
397
|
+
connection.execute(sql_insert, 32_123)
|
398
|
+
connection.execute(sql_insert, "32_123")
|
399
|
+
vals = connection.query(sql_select)
|
400
|
+
assert_equal 32_123, vals[0][0]
|
401
|
+
assert_equal 32_123, vals[1][0]
|
402
|
+
elsif cols[i] == 'BI'
|
403
|
+
connection.execute(sql_insert, 5_000_000_000)
|
404
|
+
connection.execute(sql_insert, "5_000_000_000")
|
405
|
+
vals = connection.query(sql_select)
|
406
|
+
assert_equal 5_000_000_000, vals[0][0]
|
407
|
+
assert_equal 5_000_000_000, vals[1][0]
|
408
|
+
elsif cols[i] == 'F'
|
409
|
+
connection.execute(sql_insert, 5.75)
|
410
|
+
connection.execute(sql_insert, "5.75")
|
411
|
+
vals = connection.query(sql_select)
|
412
|
+
assert_equal 5.75, vals[0][0]
|
413
|
+
assert_equal 5.75, vals[1][0]
|
414
|
+
elsif cols[i] == 'D'
|
415
|
+
connection.execute(sql_insert, 12345.12345)
|
416
|
+
connection.execute(sql_insert, "12345.12345")
|
417
|
+
vals = connection.query(sql_select)
|
418
|
+
assert_equal 12345.12345, vals[0][0]
|
419
|
+
assert_equal 12345.12345, vals[1][0]
|
420
|
+
elsif cols[i] == 'VC'
|
421
|
+
connection.execute(sql_insert, "5")
|
422
|
+
connection.execute(sql_insert, 5)
|
423
|
+
vals = connection.query(sql_select)
|
424
|
+
assert_equal "5", vals[0][0]
|
425
|
+
assert_equal "5", vals[1][0]
|
426
|
+
elsif cols[i] == 'VC10'
|
427
|
+
connection.execute(sql_insert, "1234567890")
|
428
|
+
connection.execute(sql_insert, 1234567890)
|
429
|
+
vals = connection.query(sql_select)
|
430
|
+
assert_equal "1234567890", vals[0][0]
|
431
|
+
assert_equal "1234567890", vals[1][0]
|
432
|
+
elsif cols[i].include?('VC10000')
|
433
|
+
connection.execute(sql_insert, "1" * 100)
|
434
|
+
connection.execute(sql_insert, ("1" * 100).to_i)
|
435
|
+
vals = connection.query(sql_select)
|
436
|
+
assert_equal "1" * 100, vals[0][0]
|
437
|
+
assert_equal "1" * 100, vals[1][0]
|
438
|
+
elsif cols[i] == 'C'
|
439
|
+
connection.execute(sql_insert, "5")
|
440
|
+
connection.execute(sql_insert, 5)
|
441
|
+
vals = connection.query(sql_select)
|
442
|
+
assert_equal "5", vals[0][0]
|
443
|
+
assert_equal "5", vals[1][0]
|
444
|
+
elsif cols[i] == 'C10'
|
445
|
+
connection.execute(sql_insert, "1234567890")
|
446
|
+
connection.execute(sql_insert, 1234567890)
|
447
|
+
vals = connection.query(sql_select)
|
448
|
+
assert_equal "1234567890", vals[0][0]
|
449
|
+
assert_equal "1234567890", vals[1][0]
|
450
|
+
elsif cols[i] == 'DT'
|
451
|
+
connection.execute(sql_insert, Date.civil(2000,2,2))
|
452
|
+
connection.execute(sql_insert, "2000/2/2")
|
453
|
+
connection.execute(sql_insert, "2000-2-2")
|
454
|
+
vals = connection.query(sql_select)
|
455
|
+
assert_equal Date.civil(2000,2,2), vals[0][0]
|
456
|
+
assert_equal Date.civil(2000,2,2), vals[1][0]
|
457
|
+
elsif cols[i] == 'TM'
|
458
|
+
connection.execute(sql_insert, Time.utc(2000,1,1,2,22,22))
|
459
|
+
connection.execute(sql_insert, "2000/1/1 2:22:22")
|
460
|
+
connection.execute(sql_insert, "2000-1-1 2:22:22")
|
461
|
+
vals = connection.query(sql_select)
|
462
|
+
assert_equal Time.utc(2000,1,1,2,22,22), vals[0][0]
|
463
|
+
assert_equal Time.utc(2000,1,1,2,22,22), vals[1][0]
|
464
|
+
elsif cols[i] == 'TS'
|
465
|
+
connection.execute(sql_insert, Time.local(2006,6,6,3,33,33))
|
466
|
+
connection.execute(sql_insert, "2006/6/6 3:33:33")
|
467
|
+
connection.execute(sql_insert, "2006-6-6 3:33:33")
|
468
|
+
vals = connection.query(sql_select)
|
469
|
+
assert_equal Time.local(2006,6,6,3,33,33), vals[0][0]
|
470
|
+
assert_equal Time.local(2006,6,6,3,33,33), vals[1][0]
|
471
|
+
assert_equal Time.local(2006,6,6,3,33,33), vals[2][0]
|
472
|
+
elsif cols[i] == 'N92'
|
473
|
+
connection.execute(sql_insert, 12345.12)
|
474
|
+
connection.execute(sql_insert, "12345.12")
|
475
|
+
connection.execute(sql_insert, -12345.12)
|
476
|
+
vals = connection.query(sql_select)
|
477
|
+
assert vals[0][0].is_a?(BigDecimal), "Numeric(9, 2) must return BigDecimal"
|
478
|
+
assert_equal 12345.12, vals[0][0], "NUMERIC (decimal)"
|
479
|
+
assert_equal 12345.12, vals[1][0], "NUMERIC (string)"
|
480
|
+
assert_equal(-12345.12, vals[2][0], "NUMERIC (string)")
|
481
|
+
elsif cols[i] == 'D92'
|
482
|
+
connection.execute(sql_insert, 12345.12)
|
483
|
+
connection.execute(sql_insert, "12345.12")
|
484
|
+
connection.execute(sql_insert, -12345.12)
|
485
|
+
vals = connection.query(sql_select)
|
486
|
+
assert vals[0][0].is_a?(BigDecimal), "Decimal(9,2) must return BigDecimal"
|
487
|
+
assert_equal 12345.12, vals[0][0], "DECIMAL (decimal)"
|
488
|
+
assert_equal 12345.12, vals[1][0], "DECIMAL (string)"
|
489
|
+
assert_equal(-12345.12, vals[2][0], "DECIMAL (string)")
|
490
|
+
elsif cols[i] == 'N154'
|
491
|
+
connection.execute(sql_insert, 91520.65)
|
492
|
+
connection.execute(sql_insert, "91520.65")
|
493
|
+
connection.execute(sql_insert, -91520.65)
|
494
|
+
vals = connection.query(sql_select)
|
495
|
+
assert vals[0][0].is_a?(BigDecimal), "Numeric(15,4) must return BigDecimal"
|
496
|
+
assert Float(91520.65) != vals[0][0]
|
497
|
+
assert_equal BigDecimal('91520.65'), vals[0][0]
|
498
|
+
assert_equal BigDecimal('91520.65'), vals[1][0]
|
499
|
+
assert_equal BigDecimal('-91520.65'), vals[2][0]
|
500
|
+
end
|
501
|
+
end
|
502
|
+
connection.drop
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_boolean_type
|
507
|
+
if @fb_version == 3
|
508
|
+
|
509
|
+
sql_schema = "create table testboolean (id int generated by default as identity primary key, bval boolean)"
|
510
|
+
sql_insert = "insert into testboolean (bval) values (?)"
|
511
|
+
sql_select = "select * from testboolean order by id"
|
512
|
+
|
513
|
+
Database.create(@parms) do |connection|
|
514
|
+
|
515
|
+
connection.execute(sql_schema);
|
516
|
+
|
517
|
+
connection.transaction do
|
518
|
+
|
519
|
+
connection.execute(sql_insert, nil);
|
520
|
+
|
521
|
+
connection.execute(sql_insert, false);
|
522
|
+
|
523
|
+
connection.execute(sql_insert, true);
|
524
|
+
|
525
|
+
5.times do |i|
|
526
|
+
connection.execute(sql_insert, i.even?);
|
527
|
+
end
|
528
|
+
|
529
|
+
end
|
530
|
+
|
531
|
+
connection.execute(sql_select) do |cursor|
|
532
|
+
|
533
|
+
i = 0
|
534
|
+
|
535
|
+
cursor.each :hash do |row|
|
536
|
+
case i
|
537
|
+
when 0
|
538
|
+
assert_nil row["BVAL"]
|
539
|
+
when 1
|
540
|
+
assert_equal false, row["BVAL"]
|
541
|
+
when 2
|
542
|
+
assert_equal true, row["BVAL"]
|
543
|
+
else
|
544
|
+
end
|
545
|
+
i += 1
|
546
|
+
end
|
547
|
+
|
548
|
+
end
|
549
|
+
|
550
|
+
connection.drop
|
551
|
+
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
end
|