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.
Files changed (50) hide show
  1. data/LICENSE +1 -1
  2. data/README.markdown +1 -1
  3. data/Rakefile +6 -32
  4. data/lib/data_objects/connection.rb +9 -6
  5. data/lib/data_objects/pooling.rb +1 -1
  6. data/lib/data_objects/spec/lib/pending_helpers.rb +11 -0
  7. data/lib/data_objects/spec/{helpers → lib}/ssl.rb +0 -0
  8. data/lib/data_objects/spec/setup.rb +5 -0
  9. data/lib/data_objects/spec/{command_spec.rb → shared/command_spec.rb} +54 -50
  10. data/lib/data_objects/spec/shared/connection_spec.rb +245 -0
  11. data/lib/data_objects/spec/{encoding_spec.rb → shared/encoding_spec.rb} +41 -43
  12. data/lib/data_objects/spec/shared/error/sql_error_spec.rb +30 -0
  13. data/lib/data_objects/spec/{quoting_spec.rb → shared/quoting_spec.rb} +0 -0
  14. data/lib/data_objects/spec/{reader_spec.rb → shared/reader_spec.rb} +31 -26
  15. data/lib/data_objects/spec/shared/result_spec.rb +79 -0
  16. data/lib/data_objects/spec/{typecast → shared/typecast}/array_spec.rb +4 -2
  17. data/lib/data_objects/spec/{typecast → shared/typecast}/bigdecimal_spec.rb +12 -8
  18. data/lib/data_objects/spec/{typecast → shared/typecast}/boolean_spec.rb +14 -10
  19. data/lib/data_objects/spec/{typecast → shared/typecast}/byte_array_spec.rb +6 -4
  20. data/lib/data_objects/spec/{typecast → shared/typecast}/class_spec.rb +5 -3
  21. data/lib/data_objects/spec/{typecast → shared/typecast}/date_spec.rb +13 -9
  22. data/lib/data_objects/spec/{typecast → shared/typecast}/datetime_spec.rb +14 -11
  23. data/lib/data_objects/spec/{typecast → shared/typecast}/float_spec.rb +17 -13
  24. data/lib/data_objects/spec/{typecast → shared/typecast}/integer_spec.rb +7 -5
  25. data/lib/data_objects/spec/{typecast → shared/typecast}/ipaddr_spec.rb +0 -0
  26. data/lib/data_objects/spec/{typecast → shared/typecast}/nil_spec.rb +23 -17
  27. data/lib/data_objects/spec/{typecast → shared/typecast}/other_spec.rb +11 -9
  28. data/lib/data_objects/spec/{typecast → shared/typecast}/range_spec.rb +4 -2
  29. data/lib/data_objects/spec/{typecast → shared/typecast}/string_spec.rb +10 -8
  30. data/lib/data_objects/spec/{typecast → shared/typecast}/time_spec.rb +44 -6
  31. data/lib/data_objects/transaction.rb +9 -0
  32. data/lib/data_objects/uri.rb +62 -4
  33. data/lib/data_objects/version.rb +1 -1
  34. data/spec/command_spec.rb +2 -2
  35. data/spec/connection_spec.rb +45 -25
  36. data/spec/pooling_spec.rb +9 -9
  37. data/spec/reader_spec.rb +11 -12
  38. data/spec/result_spec.rb +13 -11
  39. data/spec/spec_helper.rb +1 -16
  40. data/spec/transaction_spec.rb +9 -11
  41. data/spec/uri_spec.rb +35 -27
  42. data/tasks/spec.rake +8 -17
  43. metadata +40 -56
  44. data/lib/data_objects/spec/bacon.rb +0 -9
  45. data/lib/data_objects/spec/connection_spec.rb +0 -217
  46. data/lib/data_objects/spec/error/sql_error_spec.rb +0 -19
  47. data/lib/data_objects/spec/helpers/immediate_red_green_output.rb +0 -59
  48. data/lib/data_objects/spec/helpers/pending.rb +0 -22
  49. data/lib/data_objects/spec/result_spec.rb +0 -79
  50. data/tasks/metrics.rake +0 -36
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 - 2010 Yehuda Katz, Dirkjan Bussink
1
+ Copyright (c) 2007 - 2011 Yehuda Katz, Dirkjan Bussink
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,4 +1,4 @@
1
- # do_derby
1
+ # data_objects
2
2
 
3
3
  * <http://dataobjects.info>
4
4
 
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'pathname'
2
- require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
3
5
  require 'rake'
4
6
  require 'rake/clean'
5
7
 
@@ -14,36 +16,8 @@ SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
14
16
 
15
17
  CLEAN.include(%w[ pkg/ **/*.rbc ])
16
18
 
17
- begin
18
- gem 'jeweler', '~> 1.4'
19
- require 'jeweler'
20
-
21
- Jeweler::Tasks.new do |gem|
22
- gem.name = 'data_objects'
23
- gem.version = DataObjects::VERSION
24
- gem.summary = 'DataObjects basic API and shared driver specifications'
25
- gem.description = 'Provide a standard and simplified API for communicating with RDBMS from Ruby'
26
- gem.platform = Gem::Platform::RUBY
27
- gem.files = FileList["lib/**/*.rb", "spec/**/*.rb", "tasks/**/*.rake",
28
- "LICENSE", "Rakefile", "*.{markdown,rdoc,txt,yml}"]
29
- gem.test_files = FileList['spec/**/*.rb']
30
-
31
- gem.add_dependency 'addressable', '~>2.1'
32
-
33
- gem.add_development_dependency 'bacon', '~>1.1'
34
- gem.add_development_dependency 'mocha', '~>0.9'
35
- gem.add_development_dependency 'yard', '~>0.5'
36
-
37
- gem.rubyforge_project = 'dorb'
38
-
39
- gem.authors = ['Dirkjan Bussink']
40
- gem.email = 'd.bussink@gmail.com'
41
- gem.homepage = 'http://github.com/datamapper/do'
42
- end
43
19
 
44
- Jeweler::GemcutterTasks.new
20
+ Rake::Task['build'].clear_actions if Rake::Task.task_defined?('build')
21
+ task :build => [ :java, :gem ]
45
22
 
46
- FileList['tasks/**/*.rake'].each { |task| import task }
47
- rescue LoadError
48
- puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
49
- end
23
+ FileList['tasks/**/*.rake'].each { |task| import task }
@@ -17,13 +17,16 @@ module DataObjects
17
17
  case uri.scheme.to_sym
18
18
  when :java
19
19
  warn 'JNDI URLs (connection strings) are only for use with JRuby' unless RUBY_PLATFORM =~ /java/
20
- driver_name = uri.query.delete("scheme")
20
+
21
+ driver = uri.query.delete('scheme')
22
+ driver = uri.query.delete('driver')
23
+
21
24
  conn_uri = uri.to_s.gsub(/\?$/, '')
22
25
  when :jdbc
23
26
  warn 'JDBC URLs (connection strings) are only for use with JRuby' unless RUBY_PLATFORM =~ /java/
24
27
 
25
- path = uri.path.sub(/jdbc:/, '')
26
- driver_name = if path.split(':').first == 'sqlite'
28
+ path = uri.subscheme
29
+ driver = if path.split(':').first == 'sqlite'
27
30
  'sqlite3'
28
31
  elsif path.split(':').first == 'postgresql'
29
32
  'postgres'
@@ -38,15 +41,15 @@ module DataObjects
38
41
  # java.sql.DriverManager.getConnection to throw a
39
42
  # 'No suitable driver found for...' exception.
40
43
  else
41
- driver_name = uri.scheme
44
+ driver = uri.scheme
42
45
  conn_uri = uri
43
46
  end
44
47
 
45
48
  # Exceptions to how a driver class is determined for a given URI
46
- driver_class = if driver_name == 'sqlserver'
49
+ driver_class = if driver == 'sqlserver'
47
50
  'SqlServer'
48
51
  else
49
- driver_name.capitalize
52
+ driver.capitalize
50
53
  end
51
54
 
52
55
  clazz = DataObjects.const_get(driver_class)::Connection
@@ -197,7 +197,7 @@ module DataObjects
197
197
  lock.synchronize do
198
198
  instance.instance_variable_set(:@__allocated_in_pool, Time.now)
199
199
  @used.delete(instance.object_id)
200
- @available.push(instance)
200
+ @available.push(instance) unless @available.include?(instance)
201
201
  wait.signal
202
202
  end
203
203
  nil
@@ -0,0 +1,11 @@
1
+ module DataObjects::Spec
2
+ module PendingHelpers
3
+ def pending_if(message, boolean)
4
+ if boolean
5
+ pending(message) { yield }
6
+ else
7
+ yield
8
+ end
9
+ end
10
+ end
11
+ end
File without changes
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :be_array_case_insensitively_equal_to do |attribute|
2
+ match do |model|
3
+ model.map { |f| f.downcase } == attribute
4
+ end
5
+ end
@@ -1,8 +1,10 @@
1
1
  WINDOWS = Gem.win_platform? || (JRUBY && ENV_JAVA['os.name'] =~ /windows/i)
2
2
 
3
- shared 'a Command' do
3
+ shared_examples_for 'a Command' do
4
4
 
5
- setup_test_environment
5
+ before :all do
6
+ setup_test_environment
7
+ end
6
8
 
7
9
  before do
8
10
  @connection = DataObjects::Connection.new(CONFIG.uri)
@@ -14,9 +16,9 @@ shared 'a Command' do
14
16
  @connection.close
15
17
  end
16
18
 
17
- it 'should be a kind of Command' do @command.should.be.kind_of(DataObjects::Command) end
19
+ it { @command.should be_kind_of(DataObjects::Command) }
18
20
 
19
- it 'should respond to #execute_non_query' do @command.should.respond_to(:execute_non_query) end
21
+ it { @command.should respond_to(:execute_non_query) }
20
22
 
21
23
  describe 'execute_non_query' do
22
24
 
@@ -27,17 +29,17 @@ shared 'a Command' do
27
29
  end
28
30
 
29
31
  it 'should raise an error on an invalid query' do
30
- should.raise(DataObjects::SQLError) { @invalid_command.execute_non_query }
32
+ expect { @invalid_command.execute_non_query }.to raise_error(DataObjects::SQLError)
31
33
  end
32
34
 
33
35
  it 'should raise an error with too few binding parameters' do
34
- lambda { @command.execute_non_query("Too", "Many") }.should.raise(ArgumentError).
35
- message.should.match(/Binding mismatch: 2 for 1/)
36
+ expect { @command.execute_non_query("Too", "Many") }.to raise_error(ArgumentError,
37
+ /Binding mismatch: 2 for 1/)
36
38
  end
37
39
 
38
40
  it 'should raise an error with too many binding parameters' do
39
- lambda { @command.execute_non_query }.should.raise(ArgumentError).
40
- message.should.match(/Binding mismatch: 0 for 1/)
41
+ expect { @command.execute_non_query }.to raise_error(ArgumentError,
42
+ /Binding mismatch: 0 for 1/)
41
43
  end
42
44
 
43
45
  end
@@ -45,7 +47,7 @@ shared 'a Command' do
45
47
  describe 'with a valid statement' do
46
48
 
47
49
  it 'should not raise an error with an explicit nil as parameter' do
48
- should.not.raise(ArgumentError) { @command.execute_non_query(nil) }
50
+ expect { @command.execute_non_query(nil) }.not_to raise_error(ArgumentError)
49
51
  end
50
52
 
51
53
  end
@@ -57,14 +59,14 @@ shared 'a Command' do
57
59
  end
58
60
 
59
61
  it 'should not raise an error' do
60
- should.not.raise(ArgumentError) { @command_with_quotes.execute_non_query }
62
+ expect { @command_with_quotes.execute_non_query }.not_to raise_error(ArgumentError)
61
63
  end
62
64
 
63
65
  end
64
66
 
65
67
  end
66
68
 
67
- it 'should respond to #execute_reader' do @command.should.respond_to(:execute_reader) end
69
+ it { @command.should respond_to(:execute_reader) }
68
70
 
69
71
  describe 'execute_reader' do
70
72
 
@@ -76,17 +78,17 @@ shared 'a Command' do
76
78
 
77
79
  it 'should raise an error on an invalid query' do
78
80
  # FIXME JRuby (and MRI): Should this be an ArgumentError or DataObjects::SQLError?
79
- should.raise(ArgumentError, DataObjects::SQLError) { @invalid_reader.execute_reader }
81
+ expect { @invalid_reader.execute_reader }.to raise_error # (ArgumentError, DataObjects::SQLError)
80
82
  end
81
83
 
82
84
  it 'should raise an error with too few binding parameters' do
83
- lambda { @reader.execute_reader("Too", "Many") }.should.raise(ArgumentError).
84
- message.should.match(/Binding mismatch: 2 for 1/)
85
+ expect { @reader.execute_reader("Too", "Many") }.to raise_error(ArgumentError,
86
+ /Binding mismatch: 2 for 1/)
85
87
  end
86
88
 
87
89
  it 'should raise an error with too many binding parameters' do
88
- lambda { @reader.execute_reader }.should.raise(ArgumentError).
89
- message.should.match(/Binding mismatch: 0 for 1/)
90
+ expect { @reader.execute_reader }.to raise_error(ArgumentError,
91
+ /Binding mismatch: 0 for 1/)
90
92
  end
91
93
 
92
94
  end
@@ -94,7 +96,7 @@ shared 'a Command' do
94
96
  describe 'with a valid reader' do
95
97
 
96
98
  it 'should not raise an error with an explicit nil as parameter' do
97
- should.not.raise(ArgumentError) { @reader.execute_reader(nil) }
99
+ expect { @reader.execute_reader(nil) }.not_to raise_error(ArgumentError)
98
100
  end
99
101
 
100
102
  end
@@ -106,7 +108,7 @@ shared 'a Command' do
106
108
  end
107
109
 
108
110
  it 'should not raise an error' do
109
- should.not.raise(ArgumentError) { @reader_with_quotes.execute_reader(nil) }
111
+ expect { @reader_with_quotes.execute_reader(nil) }.not_to raise_error(ArgumentError)
110
112
  end
111
113
 
112
114
  end
@@ -114,7 +116,7 @@ shared 'a Command' do
114
116
 
115
117
  end
116
118
 
117
- it 'should respond to #set_types' do @command.should.respond_to(:set_types) end
119
+ it { @command.should respond_to(:set_types) }
118
120
 
119
121
  describe 'set_types' do
120
122
 
@@ -125,7 +127,7 @@ shared 'a Command' do
125
127
  end
126
128
 
127
129
  it 'should raise an error when types are set' do
128
- should.raise(ArgumentError) { @command.execute_non_query }
130
+ expect { @command.execute_non_query }.to raise_error(ArgumentError)
129
131
  end
130
132
 
131
133
  end
@@ -134,14 +136,14 @@ shared 'a Command' do
134
136
 
135
137
  it 'should raise an error with too few types' do
136
138
  @reader.set_types(String)
137
- lambda { @reader.execute_reader("One parameter") }.should.raise(ArgumentError).
138
- message.should.match(/Field-count mismatch. Expected 1 fields, but the query yielded 2/)
139
+ expect { @reader.execute_reader("One parameter") }.to raise_error(ArgumentError,
140
+ /Field-count mismatch. Expected 1 fields, but the query yielded 2/)
139
141
  end
140
142
 
141
143
  it 'should raise an error with too many types' do
142
144
  @reader.set_types(String, String, BigDecimal)
143
- lambda { @reader.execute_reader("One parameter") }.should.raise(ArgumentError).
144
- message.should.match(/Field-count mismatch. Expected 3 fields, but the query yielded 2/)
145
+ expect { @reader.execute_reader("One parameter") }.to raise_error(ArgumentError,
146
+ /Field-count mismatch. Expected 3 fields, but the query yielded 2/)
145
147
  end
146
148
 
147
149
  end
@@ -150,33 +152,33 @@ shared 'a Command' do
150
152
 
151
153
  it 'should not raise an error with correct number of types' do
152
154
  @reader.set_types(String, String)
153
- should.not.raise(ArgumentError) { @result = @reader.execute_reader('Buy this product now!') }
154
- should.not.raise(DataObjects::SQLError) { @result.next! }
155
- should.not.raise(DataObjects::DataError) { @result.values }
155
+ expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError)
156
+ expect { @result.next! }.not_to raise_error(DataObjects::DataError)
157
+ expect { @result.values }.not_to raise_error(DataObjects::DataError)
156
158
  @result.close
157
159
  end
158
160
 
159
161
  it 'should also support old style array argument types' do
160
162
  @reader.set_types([String, String])
161
- should.not.raise(ArgumentError) { @result = @reader.execute_reader('Buy this product now!') }
162
- should.not.raise(DataObjects::DataError) { @result.next! }
163
- should.not.raise(DataObjects::DataError) { @result.values }
163
+ expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError)
164
+ expect { @result.next! }.not_to raise_error(DataObjects::DataError)
165
+ expect { @result.values }.not_to raise_error(DataObjects::DataError)
164
166
  @result.close
165
167
  end
166
168
 
167
169
  it 'should allow subtype types' do
168
170
  class MyString < String; end
169
171
  @reader.set_types(MyString, String)
170
- should.not.raise(ArgumentError) { @result = @reader.execute_reader('Buy this product now!') }
171
- should.not.raise(DataObjects::DataError) { @result.next! }
172
- should.not.raise(DataObjects::DataError) { @result.values }
172
+ expect { @result = @reader.execute_reader('Buy this product now!') }.not_to raise_error(ArgumentError)
173
+ expect { @result.next! }.not_to raise_error(DataObjects::DataError)
174
+ expect { @result.values }.not_to raise_error(DataObjects::DataError)
173
175
  @result.close
174
176
  end
175
177
  end
176
178
 
177
179
  end
178
180
 
179
- it 'should respond to #to_s' do @command.should.respond_to(:to_s) end
181
+ it { @command.should respond_to(:to_s) }
180
182
 
181
183
  describe 'to_s' do
182
184
 
@@ -185,9 +187,11 @@ shared 'a Command' do
185
187
 
186
188
  end
187
189
 
188
- shared 'a Command with async' do
190
+ shared_examples_for 'a Command with async' do
189
191
 
190
- setup_test_environment
192
+ before :all do
193
+ setup_test_environment
194
+ end
191
195
 
192
196
  describe 'running queries in parallel' do
193
197
 
@@ -198,16 +202,20 @@ shared 'a Command with async' do
198
202
  @start = Time.now
199
203
  4.times do |i|
200
204
  threads << Thread.new do
201
- connection = DataObjects::Connection.new(CONFIG.uri)
202
- command = connection.create_command(CONFIG.sleep)
203
- if CONFIG.sleep =~ /^SELECT/i
204
- reader = command.execute_reader
205
- reader.next!
206
- reader.close
207
- else
208
- result = command.execute_non_query
205
+ begin
206
+ connection = DataObjects::Connection.new(CONFIG.uri)
207
+ command = connection.create_command(CONFIG.sleep)
208
+ if CONFIG.sleep =~ /^SELECT/i
209
+ reader = command.execute_reader
210
+ reader.next!
211
+ reader.close
212
+ else
213
+ result = command.execute_non_query
214
+ end
215
+ ensure
216
+ # Always make sure the connection gets released back into the pool.
217
+ connection.close
209
218
  end
210
- connection.close
211
219
  end
212
220
  end
213
221
 
@@ -215,10 +223,6 @@ shared 'a Command with async' do
215
223
  @finish = Time.now
216
224
  end
217
225
 
218
- after do
219
- @connection.close
220
- end
221
-
222
226
  it "should finish within 2 seconds" do
223
227
  pending_if("Ruby on Windows doesn't support asynchronous operations", WINDOWS) do
224
228
  (@finish - @start).should < 2
@@ -0,0 +1,245 @@
1
+ shared_examples_for 'a Connection' do
2
+
3
+ before :all do
4
+ setup_test_environment
5
+ end
6
+
7
+ before do
8
+ @connection = DataObjects::Connection.new(CONFIG.uri)
9
+ end
10
+
11
+ after do
12
+ @connection.close
13
+ end
14
+
15
+ it { @connection.should be_kind_of(DataObjects::Connection) }
16
+ it { @connection.should be_kind_of(DataObjects::Pooling) }
17
+
18
+ it { @connection.should respond_to(:dispose) }
19
+ it 'should respond to #create_command' do @connection.should respond_to(:create_command) end
20
+
21
+ describe 'create_command' do
22
+ it 'should be a kind of Command' do
23
+ @connection.create_command('This is a dummy command').should be_kind_of(DataObjects::Command)
24
+ end
25
+ end
26
+
27
+ describe 'various connection URIs' do
28
+ def test_connection(conn)
29
+ reader = conn.create_command(CONFIG.testsql || "SELECT 1").execute_reader
30
+ reader.next!
31
+ reader.values[0]
32
+ end
33
+
34
+ it 'should open with an uri object' do
35
+ uri = DataObjects::URI.new(
36
+ @driver,
37
+ @user,
38
+ @password,
39
+ @host,
40
+ @port && @port.to_i,
41
+ @database,
42
+ nil, nil
43
+ )
44
+ conn = DataObjects::Connection.new(uri)
45
+ test_connection(conn).should == 1
46
+ conn.close
47
+ end
48
+
49
+ it 'should work with non-JDBC URLs' do
50
+ conn = DataObjects::Connection.new("#{CONFIG.uri.sub(/jdbc:/, '')}")
51
+ test_connection(conn).should == 1
52
+ conn.close
53
+ end
54
+
55
+ end
56
+
57
+ describe 'dispose' do
58
+
59
+ describe 'on open connection' do
60
+
61
+ it 'dispose should be true' do
62
+ conn = DataObjects::Connection.new(CONFIG.uri)
63
+ conn.detach
64
+ conn.dispose.should be_true
65
+ conn.close
66
+ end
67
+
68
+ end
69
+
70
+ describe 'on closed connection' do
71
+
72
+ before do
73
+ @closed_connection = DataObjects::Connection.new(CONFIG.uri)
74
+ @closed_connection.detach
75
+ @closed_connection.dispose
76
+ end
77
+
78
+ after do
79
+ @closed_connection.close
80
+ @closed_connection = nil
81
+ end
82
+
83
+ it { @closed_connection.dispose.should be_false }
84
+
85
+ it 'should raise an error on creating a command' do
86
+ expect {
87
+ @closed_connection.create_command("INSERT INTO non_existent_table (tester) VALUES (1)").execute_non_query
88
+ }.to raise_error(DataObjects::ConnectionError)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ shared_examples_for 'a Connection with authentication support' do
97
+
98
+ before :all do
99
+ %w[ @driver @user @password @host @port @database ].each do |ivar|
100
+ raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
101
+ end
102
+ end
103
+
104
+ describe 'with an invalid URI' do
105
+
106
+ # FIXME JRuby (and MRI): Should these be ArgumentError or DataObjects::SQLError?
107
+
108
+ def connecting_with(uri)
109
+ lambda { DataObjects::Connection.new(uri) }
110
+ end
111
+
112
+ it 'should raise an error if no database specified' do
113
+ connecting_with("#{@driver}://#{@user}:#{@password}@#{@host}:#{@port}").should raise_error #(ArgumentError, DataObjects::Error)
114
+ end
115
+
116
+ it 'should raise an error if bad username is given' do
117
+ connecting_with("#{@driver}://thisreallyshouldntexist:#{@password}@#{@host}:#{@port}#{@database}").should raise_error #(ArgumentError, DataObjects::Error)
118
+ end
119
+
120
+ it 'should raise an error if bad password is given' do
121
+ connecting_with("#{@driver}://#{@user}:completelyincorrectpassword:#{@host}:#{@port}#{@database}").should raise_error #(ArgumentError, DataObjects::Error)
122
+ end
123
+
124
+ it 'should raise an error if an invalid port is given' do
125
+ connecting_with("#{@driver}://#{@user}:#{@password}:#{@host}:648646543#{@database}").should raise_error #(ArgumentError, DataObjects::Error)
126
+ end
127
+
128
+ it 'should raise an error if an invalid database is given' do
129
+ connecting_with("#{@driver}://#{@user}:#{@password}:#{@host}:#{@port}/someweirddatabase").should raise_error #(ArgumentError, DataObjects::Error)
130
+ end
131
+
132
+ it 'should raise an error with a meaningless URI' do
133
+ connecting_with("#{@driver}://peekaboo$2!@#4543").should raise_error(Addressable::URI::InvalidURIError)
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+
140
+ def test_connection(conn)
141
+ reader = conn.create_command(CONFIG.testsql || "SELECT 1").execute_reader
142
+ reader.next!
143
+ result = reader.values[0]
144
+ result
145
+ ensure
146
+ reader.close
147
+ conn.close
148
+ end
149
+
150
+ shared_examples_for 'a Connection with JDBC URL support' do
151
+
152
+ it 'should work with JDBC URLs' do
153
+ conn = DataObjects::Connection.new(CONFIG.jdbc_uri || "jdbc:#{CONFIG.uri.sub(/jdbc:/, '')}")
154
+ test_connection(conn).should == 1
155
+ end
156
+
157
+ end if defined? JRUBY_VERSION
158
+
159
+ shared_examples_for 'a Connection with SSL support' do
160
+
161
+ if DataObjectsSpecHelpers.test_environment_supports_ssl?
162
+ describe 'connecting with SSL' do
163
+
164
+ it 'should connect securely' do
165
+ conn = DataObjects::Connection.new("#{CONFIG.uri}?#{CONFIG.ssl}")
166
+ conn.secure?.should be_true
167
+ conn.close
168
+ end
169
+
170
+ end
171
+ end
172
+
173
+ describe 'connecting without SSL' do
174
+
175
+ it 'should not connect securely' do
176
+ conn = DataObjects::Connection.new(CONFIG.uri)
177
+ conn.secure?.should be_false
178
+ conn.close
179
+ end
180
+
181
+ end
182
+
183
+ end
184
+
185
+ shared_examples_for 'a Connection via JDNI' do
186
+
187
+ if defined? JRUBY_VERSION
188
+ require 'java'
189
+ begin
190
+ require 'do_jdbc/spec/lib/tyrex-1.0.3.jar'
191
+ require 'do_jdbc/spec/lib/javaee-api-6.0.jar'
192
+ require 'do_jdbc/spec/lib/commons-dbcp-1.2.2.jar'
193
+ require 'do_jdbc/spec/lib/commons-pool-1.3.jar'
194
+ rescue LoadError
195
+ pending 'JNDI specs currently require manual download of Tyrex and Apache Commons JARs'
196
+ break
197
+ end
198
+
199
+ describe 'connecting with JNDI' do
200
+
201
+ before(:all) do
202
+ java_import java.lang.System
203
+ java_import javax.naming.Context
204
+ java_import javax.naming.NamingException
205
+ java_import javax.naming.Reference
206
+ java_import javax.naming.StringRefAddr
207
+ java_import 'tyrex.naming.MemoryContext'
208
+ java_import 'tyrex.tm.RuntimeContext'
209
+
210
+ System.set_property(Context.INITIAL_CONTEXT_FACTORY, 'tyrex.naming.MemoryContextFactory')
211
+ ref = Reference.new('javax.sql.DataSource',
212
+ 'org.apache.commons.dbcp.BasicDataSourceFactory', nil)
213
+ ref.add(StringRefAddr.new('driverClassName', CONFIG.jdbc_driver))
214
+ ref.add(StringRefAddr.new('url', (CONFIG.jdbc_uri || CONFIG.uri)))
215
+ ref.add(StringRefAddr.new('username', CONFIG.user))
216
+ ref.add(StringRefAddr.new('password', CONFIG.pass))
217
+
218
+ @root = MemoryContext.new(nil)
219
+ ctx = @root.createSubcontext('comp')
220
+ ctx = ctx.createSubcontext('env')
221
+ ctx = ctx.createSubcontext('jdbc')
222
+ ctx.bind('mydb', ref)
223
+ end
224
+
225
+ before do
226
+ runCtx = RuntimeContext.newRuntimeContext(@root, nil)
227
+ RuntimeContext.setRuntimeContext(runCtx)
228
+ end
229
+
230
+ after do
231
+ RuntimeContext.unsetRuntimeContext()
232
+ end
233
+
234
+ it 'should connect' do
235
+ begin
236
+ c = DataObjects::Connection.new("java:comp/env/jdbc/mydb?driver=#{CONFIG.driver}")
237
+ c.should_not be_nil
238
+ test_connection(c).should == 1
239
+ ensure
240
+ c.close if c
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end