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,270 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class TransactionTestCases < FbTestCase
|
4
|
+
def test_transaction
|
5
|
+
Database.create(@parms) do |connection|
|
6
|
+
assert !connection.transaction_started
|
7
|
+
connection.transaction
|
8
|
+
assert connection.transaction_started
|
9
|
+
connection.commit
|
10
|
+
assert !connection.transaction_started
|
11
|
+
connection.transaction
|
12
|
+
assert connection.transaction_started
|
13
|
+
connection.rollback
|
14
|
+
assert !connection.transaction_started
|
15
|
+
connection.drop
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_transaction_block
|
20
|
+
Database.create(@parms) do |connection|
|
21
|
+
assert !connection.transaction_started
|
22
|
+
connection.transaction do
|
23
|
+
assert connection.transaction_started
|
24
|
+
end
|
25
|
+
assert !connection.transaction_started
|
26
|
+
assert_raises RuntimeError do
|
27
|
+
connection.transaction do
|
28
|
+
assert connection.transaction_started
|
29
|
+
raise "generic exception"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
assert !connection.transaction_started
|
33
|
+
connection.drop
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_auto_transaction_select_with_exception
|
38
|
+
sql_select = "SELECT * FROM RDB$DATABASE"
|
39
|
+
Database.create(@parms) do |connection|
|
40
|
+
assert !connection.transaction_started
|
41
|
+
assert_raises RuntimeError do
|
42
|
+
connection.execute(sql_select) do |cursor|
|
43
|
+
assert connection.transaction_started
|
44
|
+
raise "abort"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
assert !connection.transaction_started
|
48
|
+
connection.drop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_auto_transaction_insert_with_exception
|
53
|
+
sql_schema = "CREATE TABLE TEST (ID INT NOT NULL PRIMARY KEY, NAME VARCHAR(20))"
|
54
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
55
|
+
Database.create(@parms) do |connection|
|
56
|
+
connection.execute(sql_schema)
|
57
|
+
assert !connection.transaction_started
|
58
|
+
connection.execute(sql_insert, 1, "one")
|
59
|
+
assert !connection.transaction_started
|
60
|
+
assert_raises Error do
|
61
|
+
connection.execute(sql_insert, 1, "two")
|
62
|
+
end
|
63
|
+
assert !connection.transaction_started, "transaction is active"
|
64
|
+
connection.drop
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_auto_transaction_query
|
69
|
+
Database.create(@parms) do |connection|
|
70
|
+
assert !connection.transaction_started
|
71
|
+
connection.query("select * from rdb$database")
|
72
|
+
assert !connection.transaction_started
|
73
|
+
connection.drop
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_query_in_transaction
|
78
|
+
Database.create(@parms) do |connection|
|
79
|
+
assert !connection.transaction_started
|
80
|
+
connection.transaction do
|
81
|
+
assert connection.transaction_started
|
82
|
+
connection.query("select * from rdb$database")
|
83
|
+
assert connection.transaction_started
|
84
|
+
end
|
85
|
+
assert !connection.transaction_started
|
86
|
+
connection.drop
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_insert_commit
|
91
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
92
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
93
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
94
|
+
Database.create(@parms) do |connection|
|
95
|
+
connection.execute(sql_schema);
|
96
|
+
connection.transaction
|
97
|
+
10.times do |i|
|
98
|
+
connection.execute(sql_insert, i, i.to_s);
|
99
|
+
end
|
100
|
+
connection.commit
|
101
|
+
connection.execute(sql_select) do |cursor|
|
102
|
+
rows = cursor.fetchall
|
103
|
+
assert_equal 10, rows.size
|
104
|
+
10.times do |i|
|
105
|
+
assert_equal i, rows[i][0]
|
106
|
+
assert_equal i.to_s, rows[i][1]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
connection.drop
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_insert_rollback
|
114
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
115
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
116
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
117
|
+
Database.create(@parms) do |connection|
|
118
|
+
connection.execute(sql_schema)
|
119
|
+
connection.transaction
|
120
|
+
10.times do |i|
|
121
|
+
connection.execute(sql_insert, i, i.to_s);
|
122
|
+
end
|
123
|
+
connection.rollback
|
124
|
+
rows = connection.execute(sql_select) do |cursor| cursor.fetchall end
|
125
|
+
assert_equal 0, rows.size
|
126
|
+
connection.drop
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_transaction_block_insert_commit
|
131
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
132
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
133
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
134
|
+
Database.create(@parms) do |connection|
|
135
|
+
connection.execute(sql_schema);
|
136
|
+
assert !connection.transaction_started
|
137
|
+
result = connection.transaction do
|
138
|
+
assert connection.transaction_started
|
139
|
+
10.times do |i|
|
140
|
+
connection.execute(sql_insert, i, i.to_s);
|
141
|
+
end
|
142
|
+
assert connection.transaction_started
|
143
|
+
"transaction block result"
|
144
|
+
end
|
145
|
+
assert_equal "transaction block result", result
|
146
|
+
assert !connection.transaction_started
|
147
|
+
connection.execute(sql_select) do |cursor|
|
148
|
+
assert_equal 10, cursor.fetchall.size
|
149
|
+
end
|
150
|
+
connection.drop
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_transaction_block_insert_rollback
|
155
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
156
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
157
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
158
|
+
Database.create(@parms) do |connection|
|
159
|
+
connection.execute(sql_schema)
|
160
|
+
assert !connection.transaction_started
|
161
|
+
assert_raises RuntimeError do
|
162
|
+
connection.transaction do
|
163
|
+
10.times do |i|
|
164
|
+
connection.execute(sql_insert, i, i.to_s);
|
165
|
+
end
|
166
|
+
raise "Raise an exception, causing the transaction to be rolled back."
|
167
|
+
end
|
168
|
+
end
|
169
|
+
rows = connection.execute(sql_select) do |cursor| cursor.fetchall end
|
170
|
+
assert_equal 0, rows.size
|
171
|
+
connection.drop
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_simultaneous_transactions
|
176
|
+
db_file1 = "#{@db_file}1"
|
177
|
+
db_file2 = "#{@db_file}2"
|
178
|
+
FileUtils.rm_rf db_file1
|
179
|
+
FileUtils.rm_rf db_file2
|
180
|
+
parms1 = @parms.merge(:database => "#{@db_host}:#{db_file1}")
|
181
|
+
parms2 = @parms.merge(:database => "#{@db_host}:#{db_file2}")
|
182
|
+
Database.create(parms1) do |conn1|
|
183
|
+
Database.create(parms2) do |conn2|
|
184
|
+
assert !conn1.transaction_started, "conn1 transaction is started"
|
185
|
+
assert !conn2.transaction_started, "conn2 transaction is started"
|
186
|
+
conn1.transaction do
|
187
|
+
assert conn1.transaction_started, "conn1 transaction is not started"
|
188
|
+
assert !conn2.transaction_started, "conn2 transaction is started"
|
189
|
+
conn2.transaction do
|
190
|
+
assert conn2.transaction_started, "conn2 transaction is not started"
|
191
|
+
assert conn1.transaction_started, "conn1 transaction is not started"
|
192
|
+
end
|
193
|
+
assert !conn2.transaction_started, "conn2 transaction is still active"
|
194
|
+
assert conn1.transaction_started, "conn1 transaction is not still active"
|
195
|
+
end
|
196
|
+
assert !conn1.transaction_started, "conn1 transaction is still active"
|
197
|
+
conn2.drop
|
198
|
+
end
|
199
|
+
conn1.drop
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_transaction_options_snapshot
|
204
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
205
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
206
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
207
|
+
sql_delete = "DELETE FROM TEST WHERE ID < ?"
|
208
|
+
Database.create(@parms) do |conn1|
|
209
|
+
conn1.execute(sql_schema)
|
210
|
+
conn1.transaction do
|
211
|
+
10.times do |i|
|
212
|
+
conn1.execute(sql_insert, i, "NAME#{i}")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
Database.connect(@parms) do |conn2|
|
216
|
+
conn2.transaction("SNAPSHOT") do
|
217
|
+
affected = conn1.execute(sql_delete, 5)
|
218
|
+
assert_equal 5, affected
|
219
|
+
rs1 = conn2.query(sql_select)
|
220
|
+
assert_equal 10, rs1.size
|
221
|
+
end
|
222
|
+
rs2 = conn2.query(sql_select)
|
223
|
+
assert_equal 5, rs2.size
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_transaction_options_read_committed
|
229
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
230
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
231
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
232
|
+
sql_delete = "DELETE FROM TEST WHERE ID < ?"
|
233
|
+
Database.create(@parms) do |conn1|
|
234
|
+
conn1.execute(sql_schema)
|
235
|
+
conn1.transaction do
|
236
|
+
10.times do |i|
|
237
|
+
conn1.execute(sql_insert, i, "NAME#{i}")
|
238
|
+
end
|
239
|
+
end
|
240
|
+
Database.connect(@parms) do |conn2|
|
241
|
+
conn2.transaction("READ COMMITTED") do
|
242
|
+
affected = conn1.execute(sql_delete, 5)
|
243
|
+
assert_equal 5, affected
|
244
|
+
rs1 = conn2.query(sql_select)
|
245
|
+
assert_equal 5, rs1.size
|
246
|
+
end
|
247
|
+
rs2 = conn2.query(sql_select)
|
248
|
+
assert_equal 5, rs2.size
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_auto_and_explicit_transactions
|
254
|
+
sql_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20))"
|
255
|
+
sql_insert = "INSERT INTO TEST (ID, NAME) VALUES (?, ?)"
|
256
|
+
sql_select = "SELECT * FROM TEST ORDER BY ID"
|
257
|
+
sql_update = "UPDATE TEST SET NAME = 'NAME 0' WHERE ID = 10"
|
258
|
+
Database.create(@parms) do |conn|
|
259
|
+
conn.execute(sql_schema)
|
260
|
+
conn.transaction { 10.times { |i| conn.execute(sql_insert, i, "NAME#{i}") } }
|
261
|
+
conn.query(sql_select)
|
262
|
+
assert !conn.transaction_started
|
263
|
+
conn.transaction("READ COMMITTED") do
|
264
|
+
assert conn.transaction_started
|
265
|
+
conn.execute(sql_update)
|
266
|
+
end
|
267
|
+
assert !conn.transaction_started
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'bigdecimal'
|
6
|
+
require 'fb'
|
7
|
+
|
8
|
+
if RUBY_VERSION =~ /^2/
|
9
|
+
require 'minitest/autorun'
|
10
|
+
|
11
|
+
unless Minitest.const_defined?('Test')
|
12
|
+
Minitest::Test = MiniTest::Unit::TestCase
|
13
|
+
end
|
14
|
+
|
15
|
+
class FbTestCase < Minitest::Test
|
16
|
+
end
|
17
|
+
|
18
|
+
else
|
19
|
+
require 'test/unit'
|
20
|
+
|
21
|
+
class FbTestCase < Test::Unit::TestCase
|
22
|
+
def default_test
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class FbTestCase
|
28
|
+
include Fb
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@parms = get_db_conn_params("drivertest.fdb")
|
32
|
+
@parms_s = get_db_conn_string(@parms)
|
33
|
+
@db_file = @parms[:database].split(":", 2).last
|
34
|
+
@db_host = "localhost"
|
35
|
+
@fb_version = get_fb_version
|
36
|
+
end
|
37
|
+
|
38
|
+
def teardown
|
39
|
+
Database.drop(@parms) rescue nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_db_conn_params(dbname = nil)
|
43
|
+
dbname ||= "drivertest.%s.fdb" % SecureRandom.hex(24)
|
44
|
+
|
45
|
+
db_file = case RUBY_PLATFORM
|
46
|
+
when /win32/
|
47
|
+
File.join("c:", "var", "fbdata", dbname)
|
48
|
+
else
|
49
|
+
File.join("/", "tmp", "firebird", dbname)
|
50
|
+
end
|
51
|
+
{
|
52
|
+
:database => "localhost:#{db_file}",
|
53
|
+
:username => "sysdba",
|
54
|
+
:password => "masterkey",
|
55
|
+
:charset => 'NONE',
|
56
|
+
:role => 'READER'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_db_conn_string(params = nil)
|
61
|
+
params ||= get_db_conn_params
|
62
|
+
"database = #{params[:database]}; username = #{params[:username]}; password = #{params[:password]}; charset = NONE; role = READER;"
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_fb_version
|
66
|
+
@@fb_version ||= begin
|
67
|
+
version = -1
|
68
|
+
params = get_db_conn_params("fbversion.fdb")
|
69
|
+
begin
|
70
|
+
Database.create(params) do |connection|
|
71
|
+
d = connection.query("SELECT substring(rdb$get_context('SYSTEM', 'ENGINE_VERSION') from 1 for 1) from rdb$database")
|
72
|
+
version = Integer(d.first[0])
|
73
|
+
connection.drop
|
74
|
+
end
|
75
|
+
ensure
|
76
|
+
Database.drop(params) rescue nil
|
77
|
+
end
|
78
|
+
version
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Fb::Connection
|
84
|
+
def execute_script(sql_schema)
|
85
|
+
self.transaction do
|
86
|
+
sql_schema.strip.split(';').each do |stmt|
|
87
|
+
self.execute(stmt)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: firebird
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Popa Adrian Marius
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-06-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Ruby Firebird Extension Library
|
56
|
+
email: mapopa@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions:
|
59
|
+
- ext/fb/extconf.rb
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".gitlab-ci.yml"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- USAGE.txt
|
69
|
+
- ext/fb/extconf.rb
|
70
|
+
- ext/fb/fb_ext.c
|
71
|
+
- fb.gemspec
|
72
|
+
- lib/fb.rb
|
73
|
+
- lib/fb/version.rb
|
74
|
+
- mkmf.cmd
|
75
|
+
- test/ConnectionTestCases.rb
|
76
|
+
- test/CursorTestCases.rb
|
77
|
+
- test/DataTypesTestCases.rb
|
78
|
+
- test/DatabaseTestCases.rb
|
79
|
+
- test/EncodingTestCases.rb
|
80
|
+
- test/NumericDataTypesTestCases.rb
|
81
|
+
- test/TransactionTestCases.rb
|
82
|
+
- test/test_helper.rb
|
83
|
+
homepage: http://github.com/mariuz/fb
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
metadata: {}
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
- ext
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements:
|
103
|
+
- Firebird client library fbclient.dll, libfbclient.so or Firebird.framework.
|
104
|
+
rubygems_version: 3.0.3
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Firebird database driver
|
108
|
+
test_files: []
|