data_objects 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/ChangeLog.markdown +20 -0
  2. data/LICENSE +1 -29
  3. data/README.markdown +16 -2
  4. data/Rakefile +41 -7
  5. data/lib/data_objects.rb +3 -2
  6. data/lib/data_objects/byte_array.rb +6 -0
  7. data/lib/data_objects/connection.rb +21 -9
  8. data/lib/data_objects/logger.rb +15 -15
  9. data/lib/data_objects/pooling.rb +250 -0
  10. data/lib/data_objects/reader.rb +16 -0
  11. data/lib/data_objects/spec/bacon.rb +9 -0
  12. data/lib/data_objects/spec/command_spec.rb +54 -47
  13. data/lib/data_objects/spec/connection_spec.rb +119 -30
  14. data/lib/data_objects/spec/encoding_spec.rb +64 -6
  15. data/lib/data_objects/spec/helpers/immediate_red_green_output.rb +59 -0
  16. data/lib/data_objects/spec/helpers/pending.rb +22 -0
  17. data/lib/data_objects/spec/helpers/ssl.rb +21 -0
  18. data/lib/data_objects/spec/reader_spec.rb +47 -24
  19. data/lib/data_objects/spec/result_spec.rb +10 -19
  20. data/lib/data_objects/spec/typecast/array_spec.rb +16 -20
  21. data/lib/data_objects/spec/typecast/bigdecimal_spec.rb +16 -24
  22. data/lib/data_objects/spec/typecast/boolean_spec.rb +16 -24
  23. data/lib/data_objects/spec/typecast/byte_array_spec.rb +11 -15
  24. data/lib/data_objects/spec/typecast/class_spec.rb +7 -11
  25. data/lib/data_objects/spec/typecast/date_spec.rb +17 -25
  26. data/lib/data_objects/spec/typecast/datetime_spec.rb +18 -26
  27. data/lib/data_objects/spec/typecast/float_spec.rb +19 -27
  28. data/lib/data_objects/spec/typecast/integer_spec.rb +10 -14
  29. data/lib/data_objects/spec/typecast/nil_spec.rb +18 -30
  30. data/lib/data_objects/spec/typecast/other_spec.rb +45 -0
  31. data/lib/data_objects/spec/typecast/range_spec.rb +16 -20
  32. data/lib/data_objects/spec/typecast/string_spec.rb +72 -13
  33. data/lib/data_objects/spec/typecast/time_spec.rb +11 -15
  34. data/lib/data_objects/utilities.rb +18 -0
  35. data/lib/data_objects/version.rb +1 -2
  36. data/spec/command_spec.rb +2 -2
  37. data/spec/connection_spec.rb +7 -5
  38. data/spec/do_mock2.rb +31 -0
  39. data/spec/pooling_spec.rb +162 -0
  40. data/spec/reader_spec.rb +7 -4
  41. data/spec/result_spec.rb +2 -2
  42. data/spec/spec_helper.rb +26 -5
  43. data/spec/transaction_spec.rb +11 -9
  44. data/tasks/metrics.rake +36 -0
  45. data/tasks/release.rake +10 -70
  46. data/tasks/spec.rake +16 -14
  47. data/tasks/yard.rake +9 -0
  48. data/tasks/yardstick.rake +19 -0
  49. metadata +53 -27
  50. data/HISTORY.markdown +0 -7
  51. data/Manifest.txt +0 -44
  52. data/spec/lib/pending_helpers.rb +0 -11
  53. data/spec/lib/rspec_immediate_feedback_formatter.rb +0 -53
  54. data/spec/lib/ssl_helpers.rb +0 -20
  55. data/tasks/gem.rake +0 -8
  56. data/tasks/install.rake +0 -13
@@ -1,15 +1,15 @@
1
- share_examples_for 'a driver supporting encodings' do
1
+ shared 'a driver supporting different encodings' do
2
2
 
3
- before :each do
3
+ before do
4
4
  @connection = DataObjects::Connection.new(CONFIG.uri)
5
5
  end
6
6
 
7
- after :each do
7
+ after do
8
8
  @connection.close
9
9
  end
10
10
 
11
11
 
12
- it { @connection.should respond_to(:character_set) }
12
+ it 'should respond to #character_set' do @connection.should.respond_to(:character_set) end
13
13
 
14
14
  describe 'character_set' do
15
15
 
@@ -25,7 +25,9 @@ share_examples_for 'a driver supporting encodings' do
25
25
 
26
26
  after { @latin1_connection.close }
27
27
 
28
- it { @latin1_connection.character_set.should == 'ISO-8859-1' }
28
+ it 'the character set should be ISO-8859-1' do
29
+ @latin1_connection.character_set.should == 'ISO-8859-1'
30
+ end
29
31
  end
30
32
 
31
33
  describe 'uses UTF-8 when an invalid encoding is given' do
@@ -35,9 +37,65 @@ share_examples_for 'a driver supporting encodings' do
35
37
 
36
38
  after { @latin1_connection.close }
37
39
 
38
- it { @latin1_connection.character_set.should == 'UTF-8' }
40
+ it 'the character set should be UTF-8' do
41
+ @latin1_connection.character_set.should == 'UTF-8'
42
+ end
39
43
  end
44
+ end
45
+ end
46
+
47
+ shared 'returning correctly encoded strings for the default encoding' do
48
+
49
+
50
+ setup_test_environment
51
+
52
+ before do
53
+ @connection = DataObjects::Connection.new(CONFIG.uri)
54
+ end
55
+
56
+ after do
57
+ @connection.close
58
+ end
59
+
60
+ if defined?(::Encoding)
61
+ describe 'with encoded string support' do
40
62
 
63
+ describe 'reading a String' do
64
+ before do
65
+ @reader = @connection.create_command("SELECT name FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!')
66
+ @reader.next!
67
+ @values = @reader.values
68
+ end
69
+
70
+ after do
71
+ @reader.close
72
+ end
73
+
74
+ it 'should return UTF-8 encoded String' do
75
+ @values.first.should.be.kind_of(String)
76
+ @values.first.encoding.name.should == 'UTF-8'
77
+ end
78
+ end
41
79
 
80
+ describe 'reading a ByteArray' do
81
+ before do
82
+ @command = @connection.create_command("SELECT ad_image FROM widgets WHERE ad_description = ?")
83
+ @command.set_types(Extlib::ByteArray)
84
+ @reader = @command.execute_reader('Buy this product now!')
85
+ @reader.next!
86
+ @values = @reader.values
87
+ end
88
+
89
+ after do
90
+ @reader.close
91
+ end
92
+
93
+ it 'should return ASCII-8BIT encoded ByteArray' do
94
+ @values.first.should.be.kind_of(::Extlib::ByteArray)
95
+ @values.first.encoding.name.should == 'ASCII-8BIT'
96
+ end
97
+ end
98
+ end
42
99
  end
100
+
43
101
  end
@@ -0,0 +1,59 @@
1
+ module Bacon
2
+ module ImmediateRedGreenOutput
3
+
4
+ def handle_specification(name)
5
+ yield
6
+ @current_group = name
7
+ end
8
+
9
+ def handle_requirement(description)
10
+ error = yield
11
+ if error.empty?
12
+ example_passed
13
+ elsif error == 'PENDING'
14
+ example_pending
15
+ else
16
+ example_failed(error, description, Counter[:specifications])
17
+ end
18
+ end
19
+
20
+ def handle_summary
21
+ puts
22
+ puts ErrorLog
23
+ counter = Counter.values_at(:specifications, :requirements, :failed, :errors, :pending)
24
+ message = ("%d tests, %d assertions, %d failures, %d errors, %d pending" % counter)
25
+ color = (counter[2].to_i != 0 || counter[3].to_i != 0 ? :red : (counter[4].to_i != 0 ? :yellow : :green))
26
+ puts self.send(color, message)
27
+ end
28
+
29
+ private
30
+
31
+ def example_failed(error, description, counter)
32
+ if @current_group
33
+ puts
34
+ puts @current_group
35
+ @current_group = nil # only print the group name once
36
+ end
37
+
38
+ if error == 'FAILED'
39
+ puts red("- #{description} (FAILED - #{counter})")
40
+ puts ErrorLog if Backtraces # dump stacktrace immediately
41
+ else
42
+ puts red("- #{description} (ERROR - #{counter})")
43
+ end
44
+ end
45
+
46
+ def example_passed
47
+ print green('.')
48
+ end
49
+
50
+ def example_pending
51
+ print yellow('*')
52
+ end
53
+
54
+ def red(s) "\e[31m#{s}\e[0m"; end
55
+ def green(s) "\e[32m#{s}\e[0m"; end
56
+ def yellow(s) "\e[33m#{s}\e[0m"; end
57
+
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ module DataObjects::Spec
2
+ module Pending
3
+
4
+ def pending(message = '')
5
+ raise Bacon::Error.new(:pending, message)
6
+ end
7
+
8
+ def pending_if(message, boolean)
9
+ if boolean
10
+ pending(message) { yield }
11
+ else
12
+ yield
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ module Bacon
19
+ class Context
20
+ include DataObjects::Spec::Pending
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'pathname'
2
+ require 'cgi'
3
+
4
+ module SSLHelpers
5
+
6
+ CERTS_DIR = Pathname(__FILE__).dirname.join('ssl_certs').to_s
7
+
8
+ CONFIG = OpenStruct.new
9
+ CONFIG.ca_cert = File.join(CERTS_DIR, 'ca-cert.pem')
10
+ CONFIG.ca_key = File.join(CERTS_DIR, 'ca-key.pem')
11
+ CONFIG.server_cert = File.join(CERTS_DIR, 'server-cert.pem')
12
+ CONFIG.server_key = File.join(CERTS_DIR, 'server-key.pem')
13
+ CONFIG.client_cert = File.join(CERTS_DIR, 'client-cert.pem')
14
+ CONFIG.client_key = File.join(CERTS_DIR, 'client-key.pem')
15
+ CONFIG.cipher = 'AES128-SHA'
16
+
17
+ def self.query(*keys)
18
+ keys.map { |key| "ssl[#{key}]=#{CGI::escape(CONFIG.send(key))}" }.join('&')
19
+ end
20
+
21
+ end
@@ -1,22 +1,18 @@
1
- share_examples_for 'a Reader' do
1
+ shared 'a Reader' do
2
2
 
3
- include DataObjectsSpecHelpers
3
+ setup_test_environment
4
4
 
5
- before :all do
6
- setup_test_environment
7
- end
8
-
9
- before :each do
5
+ before do
10
6
  @connection = DataObjects::Connection.new(CONFIG.uri)
11
7
  @reader = @connection.create_command("SELECT code, name FROM widgets WHERE ad_description = ? order by id").execute_reader('Buy this product now!')
12
8
  end
13
9
 
14
- after :each do
10
+ after do
15
11
  @reader.close
16
12
  @connection.close
17
13
  end
18
14
 
19
- it { @reader.should respond_to(:fields) }
15
+ it 'should respond to #fields' do @reader.should.respond_to(:fields) end
20
16
 
21
17
  describe 'fields' do
22
18
 
@@ -28,21 +24,21 @@ share_examples_for 'a Reader' do
28
24
 
29
25
  end
30
26
 
31
- it { @reader.should respond_to(:values) }
27
+ it 'should respond to #values' do @reader.should.respond_to(:values) end
32
28
 
33
29
  describe 'values' do
34
30
 
35
31
  describe 'when the reader is uninitialized' do
36
32
 
37
33
  it 'should raise an error' do
38
- lambda { @reader.values }.should raise_error
34
+ should.raise(DataObjects::DataError) { @reader.values }
39
35
  end
40
36
 
41
37
  end
42
38
 
43
39
  describe 'when the reader is moved to the first result' do
44
40
 
45
- before do
41
+ before do
46
42
  @reader.next!
47
43
  end
48
44
 
@@ -54,7 +50,7 @@ share_examples_for 'a Reader' do
54
50
 
55
51
  describe 'when the reader is moved to the second result' do
56
52
 
57
- before do
53
+ before do
58
54
  @reader.next!; @reader.next!
59
55
  end
60
56
 
@@ -71,20 +67,20 @@ share_examples_for 'a Reader' do
71
67
  end
72
68
 
73
69
  it 'should raise an error again' do
74
- lambda { @reader.values }.should raise_error
70
+ should.raise(DataObjects::DataError) { @reader.values }
75
71
  end
76
72
  end
77
73
 
78
74
  end
79
75
 
80
- it { @reader.should respond_to(:close) }
76
+ it 'should respond to #close' do @reader.should.respond_to(:close) end
81
77
 
82
78
  describe 'close' do
83
79
 
84
80
  describe 'on an open reader' do
85
81
 
86
82
  it 'should return true' do
87
- @reader.close.should be_true
83
+ @reader.close.should.be.true
88
84
  end
89
85
 
90
86
  end
@@ -96,21 +92,21 @@ share_examples_for 'a Reader' do
96
92
  end
97
93
 
98
94
  it 'should return false' do
99
- @reader.close.should be_false
95
+ @reader.close.should.be.false
100
96
  end
101
97
 
102
98
  end
103
99
 
104
100
  end
105
101
 
106
- it { @reader.should respond_to(:next!) }
102
+ it 'should respond to #next!' do @reader.should.respond_to(:next!) end
107
103
 
108
104
  describe 'next!' do
109
105
 
110
106
  describe 'successfully moving the cursor initially' do
111
107
 
112
108
  it 'should return true' do
113
- @reader.next!.should be_true
109
+ @reader.next!.should.be.true
114
110
  end
115
111
 
116
112
  end
@@ -122,9 +118,9 @@ share_examples_for 'a Reader' do
122
118
  end
123
119
 
124
120
  it 'should move the cursor to the next value' do
125
- lambda { @reader.next! }.should change(@reader, :values).
126
- from(["W0000001", "Widget 1"]).
127
- to(["W0000002", "Widget 2"])
121
+ @reader.values.should == ["W0000001", "Widget 1"]
122
+ lambda { @reader.next! }.should.change { @reader.values }
123
+ @reader.values.should == ["W0000002", "Widget 2"]
128
124
  end
129
125
 
130
126
  end
@@ -136,14 +132,14 @@ share_examples_for 'a Reader' do
136
132
  end
137
133
 
138
134
  it 'should return false when the end is reached' do
139
- @reader.next!.should be_false
135
+ @reader.next!.should.be.false
140
136
  end
141
137
 
142
138
  end
143
139
 
144
140
  end
145
141
 
146
- it { @reader.should respond_to(:field_count) }
142
+ it 'should respond to #field_count' do @reader.should.respond_to(:field_count) end
147
143
 
148
144
  describe 'field_count' do
149
145
 
@@ -153,4 +149,31 @@ share_examples_for 'a Reader' do
153
149
 
154
150
  end
155
151
 
152
+ it 'should respond to #values' do @reader.should.respond_to(:values) end
153
+
154
+ describe 'each' do
155
+
156
+ it 'should yield each row to the block' do
157
+ rows_yielded = 0
158
+ @reader.each do |row|
159
+ row.should.respond_to(:[])
160
+
161
+ row.size.should == 2
162
+
163
+ # the field names need to be case insensitive as some drivers such as
164
+ # do_derby, do_h2, do_hsqldb return the field names as uppercase
165
+ (row['name'] || row['NAME']).should.be.kind_of(String)
166
+ (row['code'] || row['CODE']).should.be.kind_of(String)
167
+
168
+ rows_yielded += 1
169
+ end
170
+ rows_yielded.should == 15
171
+ end
172
+
173
+ it 'should return the reader' do
174
+ @reader.each { |row| }.should.equal(@reader)
175
+ end
176
+
177
+ end
178
+
156
179
  end
@@ -1,21 +1,17 @@
1
- share_examples_for 'a Result' do
1
+ shared 'a Result' do
2
2
 
3
- include DataObjectsSpecHelpers
3
+ setup_test_environment
4
4
 
5
- before :all do
6
- setup_test_environment
7
- end
8
-
9
- before :each do
5
+ before do
10
6
  @connection = DataObjects::Connection.new(CONFIG.uri)
11
7
  @result = @connection.create_command("INSERT INTO users (name) VALUES (?)").execute_non_query("monkey")
12
8
  end
13
9
 
14
- after :each do
10
+ after do
15
11
  @connection.close
16
12
  end
17
13
 
18
- it { @result.should respond_to(:affected_rows) }
14
+ it 'should respond to #affected_rows' do @result.should.respond_to(:affected_rows) end
19
15
 
20
16
  describe 'affected_rows' do
21
17
 
@@ -27,15 +23,10 @@ share_examples_for 'a Result' do
27
23
 
28
24
  end
29
25
 
30
- share_examples_for 'a Result which returns inserted keys' do
31
-
32
- include DataObjectsSpecHelpers
26
+ shared 'a Result which returns inserted keys' do
33
27
 
34
- before :all do
28
+ before do
35
29
  setup_test_environment
36
- end
37
-
38
- before :each do
39
30
  @connection = DataObjects::Connection.new(CONFIG.uri)
40
31
  command = @connection.create_command("INSERT INTO users (name) VALUES (?)")
41
32
  # execute the command twice and expose the second result
@@ -43,15 +34,15 @@ share_examples_for 'a Result which returns inserted keys' do
43
34
  @result = command.execute_non_query("monkey")
44
35
  end
45
36
 
46
- after :each do
37
+ after do
47
38
  @connection.close
48
39
  end
49
40
 
50
- it { @result.should respond_to(:affected_rows) }
41
+ it 'should respond to #affected_rows' do @result.should.respond_to(:affected_rows) end
51
42
 
52
43
  describe 'insert_id' do
53
44
 
54
- it 'should return the number of affected rows' do
45
+ it 'should return the insert_id' do
55
46
  # This is actually the 2nd record inserted
56
47
  @result.insert_id.should == 2
57
48
  end
@@ -1,36 +1,32 @@
1
- share_examples_for 'supporting Array' do
1
+ shared 'supporting Array' do
2
2
 
3
- include DataObjectsSpecHelpers
3
+ setup_test_environment
4
4
 
5
- before :all do
6
- setup_test_environment
7
- end
8
-
9
- before :each do
5
+ before do
10
6
  @connection = DataObjects::Connection.new(CONFIG.uri)
11
7
  end
12
8
 
13
- after :each do
9
+ after do
14
10
  @connection.close
15
11
  end
16
12
 
17
13
  describe 'passing an Array as a parameter in execute_reader' do
18
14
 
19
- before do
20
- @reader = @connection.create_command("SELECT * FROM widgets WHERE id in ?").execute_reader([2,3,4,5])
21
- end
15
+ before do
16
+ @reader = @connection.create_command("SELECT * FROM widgets WHERE id in ?").execute_reader([2,3,4,5])
17
+ end
22
18
 
23
- after do
24
- @reader.close
25
- end
19
+ after do
20
+ @reader.close
21
+ end
26
22
 
27
- it 'should return correct number of rows' do
28
- counter = 0
29
- while(@reader.next!) do
30
- counter += 1
31
- end
32
- counter.should == 4
23
+ it 'should return correct number of rows' do
24
+ counter = 0
25
+ while(@reader.next!) do
26
+ counter += 1
33
27
  end
28
+ counter.should == 4
29
+ end
34
30
 
35
31
  end
36
32
  end