data_objects 0.10.3 → 0.10.4.rc1
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.
- data/LICENSE +1 -1
- data/README.markdown +1 -1
- data/Rakefile +6 -32
- data/lib/data_objects/connection.rb +9 -6
- data/lib/data_objects/pooling.rb +1 -1
- data/lib/data_objects/spec/lib/pending_helpers.rb +11 -0
- data/lib/data_objects/spec/{helpers → lib}/ssl.rb +0 -0
- data/lib/data_objects/spec/setup.rb +5 -0
- data/lib/data_objects/spec/{command_spec.rb → shared/command_spec.rb} +54 -50
- data/lib/data_objects/spec/shared/connection_spec.rb +245 -0
- data/lib/data_objects/spec/{encoding_spec.rb → shared/encoding_spec.rb} +41 -43
- data/lib/data_objects/spec/shared/error/sql_error_spec.rb +30 -0
- data/lib/data_objects/spec/{quoting_spec.rb → shared/quoting_spec.rb} +0 -0
- data/lib/data_objects/spec/{reader_spec.rb → shared/reader_spec.rb} +31 -26
- data/lib/data_objects/spec/shared/result_spec.rb +79 -0
- data/lib/data_objects/spec/{typecast → shared/typecast}/array_spec.rb +4 -2
- data/lib/data_objects/spec/{typecast → shared/typecast}/bigdecimal_spec.rb +12 -8
- data/lib/data_objects/spec/{typecast → shared/typecast}/boolean_spec.rb +14 -10
- data/lib/data_objects/spec/{typecast → shared/typecast}/byte_array_spec.rb +6 -4
- data/lib/data_objects/spec/{typecast → shared/typecast}/class_spec.rb +5 -3
- data/lib/data_objects/spec/{typecast → shared/typecast}/date_spec.rb +13 -9
- data/lib/data_objects/spec/{typecast → shared/typecast}/datetime_spec.rb +14 -11
- data/lib/data_objects/spec/{typecast → shared/typecast}/float_spec.rb +17 -13
- data/lib/data_objects/spec/{typecast → shared/typecast}/integer_spec.rb +7 -5
- data/lib/data_objects/spec/{typecast → shared/typecast}/ipaddr_spec.rb +0 -0
- data/lib/data_objects/spec/{typecast → shared/typecast}/nil_spec.rb +23 -17
- data/lib/data_objects/spec/{typecast → shared/typecast}/other_spec.rb +11 -9
- data/lib/data_objects/spec/{typecast → shared/typecast}/range_spec.rb +4 -2
- data/lib/data_objects/spec/{typecast → shared/typecast}/string_spec.rb +10 -8
- data/lib/data_objects/spec/{typecast → shared/typecast}/time_spec.rb +44 -6
- data/lib/data_objects/transaction.rb +9 -0
- data/lib/data_objects/uri.rb +62 -4
- data/lib/data_objects/version.rb +1 -1
- data/spec/command_spec.rb +2 -2
- data/spec/connection_spec.rb +45 -25
- data/spec/pooling_spec.rb +9 -9
- data/spec/reader_spec.rb +11 -12
- data/spec/result_spec.rb +13 -11
- data/spec/spec_helper.rb +1 -16
- data/spec/transaction_spec.rb +9 -11
- data/spec/uri_spec.rb +35 -27
- data/tasks/spec.rake +8 -17
- metadata +40 -56
- data/lib/data_objects/spec/bacon.rb +0 -9
- data/lib/data_objects/spec/connection_spec.rb +0 -217
- data/lib/data_objects/spec/error/sql_error_spec.rb +0 -19
- data/lib/data_objects/spec/helpers/immediate_red_green_output.rb +0 -59
- data/lib/data_objects/spec/helpers/pending.rb +0 -22
- data/lib/data_objects/spec/result_spec.rb +0 -79
- data/tasks/metrics.rake +0 -36
@@ -1,16 +1,16 @@
|
|
1
|
-
|
1
|
+
shared_examples_for 'a driver supporting different encodings' do
|
2
2
|
|
3
|
-
|
4
|
-
@connection = DataObjects::Connection.new(CONFIG.uri)
|
5
|
-
end
|
3
|
+
describe 'character_set' do
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
before do
|
6
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
7
|
+
end
|
10
8
|
|
11
|
-
|
9
|
+
after do
|
10
|
+
@connection.close
|
11
|
+
end
|
12
12
|
|
13
|
-
|
13
|
+
it { @connection.should respond_to(:character_set) }
|
14
14
|
|
15
15
|
it 'uses utf8 by default' do
|
16
16
|
@connection.character_set.should == 'UTF-8'
|
@@ -24,9 +24,7 @@ shared 'a driver supporting different encodings' do
|
|
24
24
|
|
25
25
|
after { @latin1_connection.close }
|
26
26
|
|
27
|
-
it
|
28
|
-
@latin1_connection.character_set.should == 'ISO-8859-1'
|
29
|
-
end
|
27
|
+
it { @latin1_connection.character_set.should == 'ISO-8859-1' }
|
30
28
|
end
|
31
29
|
|
32
30
|
describe 'uses UTF-8 when an invalid encoding is given' do
|
@@ -36,29 +34,28 @@ shared 'a driver supporting different encodings' do
|
|
36
34
|
|
37
35
|
after { @latin1_connection.close }
|
38
36
|
|
39
|
-
it
|
40
|
-
@latin1_connection.character_set.should == 'UTF-8'
|
41
|
-
end
|
37
|
+
it { @latin1_connection.character_set.should == 'UTF-8' }
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
45
41
|
|
46
|
-
|
42
|
+
shared_examples_for 'returning correctly encoded strings for the default database encoding' do
|
47
43
|
|
48
44
|
if defined?(::Encoding)
|
49
45
|
|
46
|
+
before :all do
|
50
47
|
setup_test_environment
|
48
|
+
end
|
51
49
|
|
52
|
-
|
53
|
-
@connection.close if @connection
|
54
|
-
@connection = DataObjects::Connection.new(CONFIG.uri)
|
55
|
-
end
|
50
|
+
describe 'with encoded string support' do
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
before do
|
53
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
54
|
+
end
|
60
55
|
|
61
|
-
|
56
|
+
after do
|
57
|
+
@connection.close
|
58
|
+
end
|
62
59
|
|
63
60
|
describe 'reading a String' do
|
64
61
|
before do
|
@@ -72,9 +69,9 @@ shared 'returning correctly encoded strings for the default database encoding' d
|
|
72
69
|
end
|
73
70
|
|
74
71
|
it 'should return UTF-8 encoded String' do
|
75
|
-
@values.first.should
|
72
|
+
@values.first.should be_kind_of(String)
|
76
73
|
@values.first.encoding.name.should == 'UTF-8'
|
77
|
-
@values.last.should
|
74
|
+
@values.last.should be_kind_of(String)
|
78
75
|
@values.last.encoding.name.should == 'UTF-8'
|
79
76
|
end
|
80
77
|
end
|
@@ -93,7 +90,7 @@ shared 'returning correctly encoded strings for the default database encoding' d
|
|
93
90
|
end
|
94
91
|
|
95
92
|
it 'should return ASCII-8BIT encoded ByteArray' do
|
96
|
-
@values.first.should
|
93
|
+
@values.first.should be_kind_of(::Extlib::ByteArray)
|
97
94
|
@values.first.encoding.name.should == 'ASCII-8BIT'
|
98
95
|
end
|
99
96
|
end
|
@@ -102,25 +99,26 @@ shared 'returning correctly encoded strings for the default database encoding' d
|
|
102
99
|
|
103
100
|
end
|
104
101
|
|
105
|
-
|
102
|
+
shared_examples_for 'returning correctly encoded strings for the default internal encoding' do
|
106
103
|
|
107
104
|
if defined?(::Encoding)
|
108
105
|
|
106
|
+
before :all do
|
109
107
|
setup_test_environment
|
108
|
+
end
|
110
109
|
|
111
|
-
|
112
|
-
@connection.close if @connection
|
113
|
-
@encoding_before = Encoding.default_internal
|
114
|
-
Encoding.default_internal = 'ISO-8859-1'
|
115
|
-
@connection = DataObjects::Connection.new(CONFIG.uri)
|
116
|
-
end
|
110
|
+
describe 'with encoded string support' do
|
117
111
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
112
|
+
before do
|
113
|
+
@encoding_before = Encoding.default_internal
|
114
|
+
Encoding.default_internal = 'ISO-8859-1'
|
115
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
116
|
+
end
|
122
117
|
|
123
|
-
|
118
|
+
after do
|
119
|
+
@connection.close
|
120
|
+
Encoding.default_internal = @encoding_before
|
121
|
+
end
|
124
122
|
|
125
123
|
describe 'reading a String' do
|
126
124
|
before do
|
@@ -133,10 +131,10 @@ shared 'returning correctly encoded strings for the default internal encoding' d
|
|
133
131
|
@reader.close
|
134
132
|
end
|
135
133
|
|
136
|
-
it 'should return
|
137
|
-
@values.first.should
|
134
|
+
it 'should return ISO-8859-1 encoded String' do
|
135
|
+
@values.first.should be_kind_of(String)
|
138
136
|
@values.first.encoding.name.should == 'ISO-8859-1'
|
139
|
-
@values.last.should
|
137
|
+
@values.last.should be_kind_of(String)
|
140
138
|
@values.last.encoding.name.should == 'ISO-8859-1'
|
141
139
|
end
|
142
140
|
end
|
@@ -155,7 +153,7 @@ shared 'returning correctly encoded strings for the default internal encoding' d
|
|
155
153
|
end
|
156
154
|
|
157
155
|
it 'should return ASCII-8BIT encoded ByteArray' do
|
158
|
-
@values.first.should
|
156
|
+
@values.first.should be_kind_of(::Extlib::ByteArray)
|
159
157
|
@values.first.encoding.name.should == 'ASCII-8BIT'
|
160
158
|
end
|
161
159
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
shared_examples_for 'raising a SQLError' do
|
2
|
+
|
3
|
+
before :all do
|
4
|
+
setup_test_environment
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "an invalid query" do
|
8
|
+
|
9
|
+
it 'should raise an error' do
|
10
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
11
|
+
invalid_query = @connection.create_command("SLCT * FROM widgets WHERE ad_description = ? order by id")
|
12
|
+
expect { invalid_query.execute_reader('Buy this product now!') }.to raise_error(DataObjects::SQLError)
|
13
|
+
@connection.close
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "an invalid result set" do
|
20
|
+
|
21
|
+
it 'should raise an error' do
|
22
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
23
|
+
invalid_result = @connection.create_command("SELECT MAX((SELECT 1 UNION SELECT 2))")
|
24
|
+
expect { invalid_result.execute_reader }.to raise_error(DataObjects::SQLError)
|
25
|
+
@connection.close
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
File without changes
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
shared_examples_for 'a Reader' do
|
2
2
|
|
3
|
-
|
3
|
+
before :all do
|
4
|
+
setup_test_environment
|
5
|
+
end
|
4
6
|
|
5
7
|
before do
|
6
8
|
@connection = DataObjects::Connection.new(CONFIG.uri)
|
@@ -14,30 +16,33 @@ shared 'a Reader' do
|
|
14
16
|
@connection.close
|
15
17
|
end
|
16
18
|
|
17
|
-
it
|
19
|
+
it { @reader.should respond_to(:fields) }
|
18
20
|
|
19
21
|
describe 'fields' do
|
20
22
|
|
21
|
-
def array_case_insensitively_equal_to(arr)
|
22
|
-
lambda { |obj| obj.map { |f| f.downcase } == arr }
|
23
|
-
end
|
24
|
-
|
25
23
|
it 'should return the correct fields in the reader' do
|
26
24
|
# we downcase the field names as some drivers such as do_derby, do_h2,
|
27
25
|
# do_hsqldb, do_oracle return the field names as uppercase
|
28
|
-
@reader.fields.should
|
26
|
+
@reader.fields.should be_array_case_insensitively_equal_to(['code', 'name'])
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return the field alias as the name, when the SQL AS keyword is specified' do
|
30
|
+
reader = @connection.create_command("SELECT code AS codigo, name AS nombre FROM widgets WHERE ad_description = ? order by id").execute_reader('Buy this product now!')
|
31
|
+
reader.fields.should_not be_array_case_insensitively_equal_to(['code', 'name'])
|
32
|
+
reader.fields.should be_array_case_insensitively_equal_to(['codigo', 'nombre'])
|
33
|
+
reader.close
|
29
34
|
end
|
30
35
|
|
31
36
|
end
|
32
37
|
|
33
|
-
it
|
38
|
+
it { @reader.should respond_to(:values) }
|
34
39
|
|
35
40
|
describe 'values' do
|
36
41
|
|
37
42
|
describe 'when the reader is uninitialized' do
|
38
43
|
|
39
44
|
it 'should raise an error' do
|
40
|
-
|
45
|
+
expect { @reader.values }.to raise_error(DataObjects::DataError)
|
41
46
|
end
|
42
47
|
|
43
48
|
end
|
@@ -73,20 +78,20 @@ shared 'a Reader' do
|
|
73
78
|
end
|
74
79
|
|
75
80
|
it 'should raise an error again' do
|
76
|
-
|
81
|
+
expect { @reader.values }.to raise_error(DataObjects::DataError)
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
80
85
|
end
|
81
86
|
|
82
|
-
it
|
87
|
+
it { @reader.should respond_to(:close) }
|
83
88
|
|
84
89
|
describe 'close' do
|
85
90
|
|
86
91
|
describe 'on an open reader' do
|
87
92
|
|
88
93
|
it 'should return true' do
|
89
|
-
@reader.close.should
|
94
|
+
@reader.close.should be_true
|
90
95
|
end
|
91
96
|
|
92
97
|
end
|
@@ -98,21 +103,21 @@ shared 'a Reader' do
|
|
98
103
|
end
|
99
104
|
|
100
105
|
it 'should return false' do
|
101
|
-
@reader.close.should
|
106
|
+
@reader.close.should be_false
|
102
107
|
end
|
103
108
|
|
104
109
|
end
|
105
110
|
|
106
111
|
end
|
107
112
|
|
108
|
-
it
|
113
|
+
it { @reader.should respond_to(:next!) }
|
109
114
|
|
110
115
|
describe 'next!' do
|
111
116
|
|
112
117
|
describe 'successfully moving the cursor initially' do
|
113
118
|
|
114
119
|
it 'should return true' do
|
115
|
-
@reader.next!.should
|
120
|
+
@reader.next!.should be_true
|
116
121
|
end
|
117
122
|
|
118
123
|
end
|
@@ -125,7 +130,7 @@ shared 'a Reader' do
|
|
125
130
|
|
126
131
|
it 'should move the cursor to the next value' do
|
127
132
|
@reader.values.should == ["W0000001", "Widget 1"]
|
128
|
-
lambda { @reader.next! }.should
|
133
|
+
lambda { @reader.next! }.should change { @reader.values }
|
129
134
|
@reader.values.should == ["W0000002", "Widget 2"]
|
130
135
|
end
|
131
136
|
|
@@ -138,14 +143,14 @@ shared 'a Reader' do
|
|
138
143
|
end
|
139
144
|
|
140
145
|
it 'should return false when the end is reached' do
|
141
|
-
@reader.next!.should
|
146
|
+
@reader.next!.should be_false
|
142
147
|
end
|
143
148
|
|
144
149
|
end
|
145
150
|
|
146
151
|
end
|
147
152
|
|
148
|
-
it
|
153
|
+
it { @reader.should respond_to(:field_count) }
|
149
154
|
|
150
155
|
describe 'field_count' do
|
151
156
|
|
@@ -155,21 +160,21 @@ shared 'a Reader' do
|
|
155
160
|
|
156
161
|
end
|
157
162
|
|
158
|
-
it
|
163
|
+
it { @reader.should respond_to(:values) }
|
159
164
|
|
160
165
|
describe 'each' do
|
161
166
|
|
162
167
|
it 'should yield each row to the block for multiple columns' do
|
163
168
|
rows_yielded = 0
|
164
169
|
@reader.each do |row|
|
165
|
-
row.should
|
170
|
+
row.should respond_to(:[])
|
166
171
|
|
167
172
|
row.size.should == 2
|
168
173
|
|
169
174
|
# the field names need to be case insensitive as some drivers such as
|
170
175
|
# do_derby, do_h2, do_hsqldb return the field names as uppercase
|
171
|
-
(row['name'] || row['NAME']).should
|
172
|
-
(row['code'] || row['CODE']).should
|
176
|
+
(row['name'] || row['NAME']).should be_kind_of(String)
|
177
|
+
(row['code'] || row['CODE']).should be_kind_of(String)
|
173
178
|
|
174
179
|
rows_yielded += 1
|
175
180
|
end
|
@@ -179,13 +184,13 @@ shared 'a Reader' do
|
|
179
184
|
it 'should yield each row to the block for a single column' do
|
180
185
|
rows_yielded = 0
|
181
186
|
@reader2.each do |row|
|
182
|
-
row.should
|
187
|
+
row.should respond_to(:[])
|
183
188
|
|
184
189
|
row.size.should == 1
|
185
190
|
|
186
191
|
# the field names need to be case insensitive as some drivers such as
|
187
192
|
# do_derby, do_h2, do_hsqldb return the field names as uppercase
|
188
|
-
(row['code'] || row['CODE']).should
|
193
|
+
(row['code'] || row['CODE']).should be_kind_of(String)
|
189
194
|
|
190
195
|
rows_yielded += 1
|
191
196
|
end
|
@@ -193,7 +198,7 @@ shared 'a Reader' do
|
|
193
198
|
end
|
194
199
|
|
195
200
|
it 'should return the reader' do
|
196
|
-
@reader.each { |row| }.should
|
201
|
+
@reader.each { |row| }.should equal(@reader)
|
197
202
|
end
|
198
203
|
|
199
204
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
shared_examples_for 'a Result' do
|
2
|
+
|
3
|
+
before :all do
|
4
|
+
setup_test_environment
|
5
|
+
end
|
6
|
+
|
7
|
+
before do
|
8
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
9
|
+
@result = @connection.create_command("INSERT INTO users (name) VALUES (?)").execute_non_query("monkey")
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@connection.close
|
14
|
+
end
|
15
|
+
|
16
|
+
it { @result.should respond_to(:affected_rows) }
|
17
|
+
|
18
|
+
describe 'affected_rows' do
|
19
|
+
|
20
|
+
it 'should return the number of affected rows' do
|
21
|
+
@result.affected_rows.should == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
shared_examples_for 'a Result which returns inserted key with sequences' do
|
29
|
+
|
30
|
+
describe 'insert_id' do
|
31
|
+
|
32
|
+
before do
|
33
|
+
setup_test_environment
|
34
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
35
|
+
command = @connection.create_command("INSERT INTO users (name) VALUES (?)")
|
36
|
+
# execute the command twice and expose the second result
|
37
|
+
command.execute_non_query("monkey")
|
38
|
+
@result = command.execute_non_query("monkey")
|
39
|
+
end
|
40
|
+
|
41
|
+
after do
|
42
|
+
@connection.close
|
43
|
+
end
|
44
|
+
|
45
|
+
it { @result.should respond_to(:affected_rows) }
|
46
|
+
|
47
|
+
it 'should return the insert_id' do
|
48
|
+
# This is actually the 2nd record inserted
|
49
|
+
@result.insert_id.should == 2
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
shared_examples_for 'a Result which returns nil without sequences' do
|
57
|
+
|
58
|
+
describe 'insert_id' do
|
59
|
+
|
60
|
+
before do
|
61
|
+
setup_test_environment
|
62
|
+
@connection = DataObjects::Connection.new(CONFIG.uri)
|
63
|
+
command = @connection.create_command("INSERT INTO invoices (invoice_number) VALUES (?)")
|
64
|
+
# execute the command twice and expose the second result
|
65
|
+
@result = command.execute_non_query("monkey")
|
66
|
+
end
|
67
|
+
|
68
|
+
after do
|
69
|
+
@connection.close
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should return the insert_id' do
|
73
|
+
# This is actually the 2nd record inserted
|
74
|
+
@result.insert_id.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|