ruby-plsql 0.5.2 → 0.5.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6146c4b4e96437d80996671df0f6ca68829dfc0a
4
- data.tar.gz: f058454a9f207d41ef3a98e05c9aad90857da253
3
+ metadata.gz: f9c79fd3f97babd3bfa0f5a54b0830a12a6510c9
4
+ data.tar.gz: b3ec4ad1f9db5aa761fc751b1db9a1263c2dd6f1
5
5
  SHA512:
6
- metadata.gz: e1b0537e8c4b32233661d316e93f91e2aa53dc5515e0e4c6b82b4dbb3049f782e85cc4ae78e52b47fb4cf05b7cc5c64aa4b585dd8b840622839730baaf37fdfa
7
- data.tar.gz: eb17b6511c06ebe93ad09c9c5fefe19bd7aa298651802f54f41fdaae5b5b03308fe4ec2a141b17ac762e109e8838ff99c3303b51e58e3b0a7ba04253d4e5ae5c
6
+ metadata.gz: 88a0bf576dd829b0cbd7102a72a7a9d8bdfe3aee2e8771353756887f292c5c364ea9b24004c41e4cb14882cfd82c4d8ef7a9cd3709e04ab4693236dd163011c7
7
+ data.tar.gz: ac9bde40f6690697c63acb443a8a9f02afa9fc1bb1670e477c09b21f6c4aa368c61326047ae8733860d337dd862efe4432fba81f3eee35d9a9affc72c60e32ff
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ group :development do
5
5
  gem 'rspec', '~> 3.1'
6
6
 
7
7
  unless ENV['NO_ACTIVERECORD']
8
- gem 'activerecord', '>= 3.2.3', '< 4.2.0'
8
+ gem 'activerecord', '>= 3.2.3', '< 4.3.0'
9
9
  gem 'activerecord-oracle_enhanced-adapter', '>= 1.4.1', '< 1.6.0'
10
10
  gem 'simplecov', '>= 0'
11
11
  end
@@ -1,3 +1,15 @@
1
+ == 0.5.3 2015-05-07
2
+
3
+ * Improvements
4
+ * Support for ActiveRecord 4.2
5
+ * Docs
6
+ * README formatting fixed (Usage with Rails section)
7
+ * Bug fixes
8
+ * Force to convert String type value as real string to avoid error when used JRuby and for VARCHAR2 parameter is assigned non String value
9
+ * Fix dbms_output functionality in case when database exception is raised
10
+ * Internal (development) improvements
11
+ * Vagrant box provisioning added
12
+
1
13
  == 0.5.2 2014-10-23
2
14
 
3
15
  * Bug fixes
data/README.md CHANGED
@@ -59,6 +59,7 @@ plsql.logoff
59
59
 
60
60
  Look at RSpec tests under spec directory for more usage examples.
61
61
 
62
+ Note: named arguments in procedures calls should be in lower case.
62
63
 
63
64
  ### Table operations:
64
65
 
@@ -69,7 +70,7 @@ ruby-plsql also provides simple API for select/insert/update/delete table operat
69
70
  employee = { :employee_id => 1, :first_name => 'First', :last_name => 'Last', :hire_date => Time.local(2000,01,31) }
70
71
  plsql.employees.insert employee # INSERT INTO employees VALUES (1, 'First', 'Last', ...)
71
72
 
72
- # insert many records
73
+ # insert many records
73
74
  employees = [employee1, employee2, ... ] # array of many Hashes
74
75
  plsql.employees.insert employees
75
76
 
@@ -104,7 +105,7 @@ plsql.employees.delete(:employee_id => 1) # DELETE FROM employees WHERE employee
104
105
  # select from sequences
105
106
  plsql.employees_seq.nextval # SELECT employees_seq.NEXTVAL FROM dual
106
107
  plsql.employees_seq.currval # SELECT employees_seq.CURRVAL FROM dual
107
-
108
+ ```
108
109
 
109
110
  ### Usage with Rails:
110
111
 
@@ -140,7 +141,17 @@ If you are using JRuby then you need to download latest [Oracle JDBC driver](htt
140
141
  TESTS
141
142
  -----
142
143
 
143
- * Create Oracle database schema for test purposes. Review `spec/spec_helper.rb` to see default schema/user names and database names (use environment variables to override defaults)
144
+ Review `spec/spec_helper.rb` to see default schema/user names and database names (use environment variables to override defaults)
145
+
146
+ ##### Prepare database
147
+
148
+ * With local [Vagrant](https://www.vagrantup.com) based Oracle XE database.
149
+
150
+ Download Oracle XE database ```oracle-xe-11.2.0-1.0.x86_64.rpm.zip``` from [Oracle Home page](http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html) and put it into project home directory.
151
+
152
+ From project home directory run ```vagrant up``` command to build fully functioning **Centos 6.6** virtual machine with installed Oracle XE database.
153
+
154
+ * Within other Oracle Database create Oracle database schema for test purposes.
144
155
 
145
156
  SQL> CREATE USER hr IDENTIFIED BY hr;
146
157
  SQL> GRANT unlimited tablespace, create session, create table, create sequence, create procedure, create type, create view, create synonym TO hr;
@@ -148,6 +159,8 @@ TESTS
148
159
  SQL> CREATE USER arunit IDENTIFIED BY arunit;
149
160
  SQL> GRANT create session TO arunit;
150
161
 
162
+ ##### Prepare dependencies
163
+
151
164
  * Install bundler with
152
165
 
153
166
  gem install bundler
@@ -156,7 +169,13 @@ TESTS
156
169
 
157
170
  bundle install
158
171
 
159
- * Run tests with
172
+ ##### Run tests
173
+
174
+ * Run tests with local Vagrant based Oracle XE database
175
+
176
+ USE_VM_DATABASE=Y rake spec
177
+
178
+ * Run tests with other Oracle database
160
179
 
161
180
  rake spec
162
181
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.5.3
@@ -0,0 +1,38 @@
1
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
2
+ VAGRANTFILE_API_VERSION = "2"
3
+
4
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
5
+
6
+ # Every Vagrant virtual environment requires a box to build off of.
7
+ config.vm.box = "chef/centos-6.6"
8
+ config.vm.hostname = "vagrant.oracle"
9
+ config.vm.network :forwarded_port, guest: 1521, host: 1521
10
+
11
+ config.vm.provider :virtualbox do |vb|
12
+ vb.name = "Ruby-PLSQL Oracle XE box"
13
+ # Speed up network
14
+ # http://serverfault.com/a/453260/105586
15
+ # http://serverfault.com/a/595010/105586
16
+ vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
17
+ vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
18
+ end
19
+
20
+ # Check for Oracle XE installation file
21
+ config.vm.provision :shell, path: "./spec/support/file_check_script.sh"
22
+
23
+ config.vm.provision :shell, inline: "yum update -y"
24
+ config.vm.provision :shell, inline: "yum install -y libaio bc flex unzip"
25
+ config.vm.provision :shell, inline: "mkdir -p /opt/oracle"
26
+ config.vm.provision :shell, inline: "unzip -q -d /opt/oracle /vagrant/oracle-xe-11.2.0-1.0.x86_64.rpm.zip"
27
+ config.vm.provision :shell, inline: "cd /opt/oracle/Disk1 && rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm"
28
+ config.vm.provision :shell, inline: %q{sed -i -E "s/<value required>/oracle/" /opt/oracle/Disk1/response/xe.rsp}
29
+ config.vm.provision :shell, inline: "/etc/init.d/oracle-xe configure responseFile=/opt/oracle/Disk1/response/xe.rsp >> /opt/oracle/XEsilentinstall.log"
30
+ config.vm.provision :shell, inline: ". /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh"
31
+ config.vm.provision :shell, inline: "touch /etc/profile.d/oracle_profile.sh && cat /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh >> /etc/profile.d/oracle_profile.sh"
32
+ config.vm.provision :shell, inline: %q{sed -i -E "s/HOST = [^)]+/HOST = $HOSTNAME/g" /u01/app/oracle/product/11.2.0/xe/network/admin/listener.ora}
33
+ config.vm.provision :shell, inline: %q{sed -i -E "s/<ORACLE_BASE>/\/u01\/app\/oracle/" /u01/app/oracle/product/11.2.0/xe/dbs/init.ora}
34
+
35
+ # Change password for Oracle user
36
+ config.vm.provision :shell, inline: "echo -e \"oracle\noracle\" | passwd oracle"
37
+
38
+ end
@@ -109,14 +109,14 @@ module PLSQL
109
109
  @out_types[arg] = type || ora_value.class
110
110
  @out_index[arg] = bind_param_index(arg)
111
111
  if ['TABLE','VARRAY','OBJECT'].include?(metadata[:data_type])
112
- @statement.registerOutParameter(@out_index[arg], @connection.get_java_sql_type(ora_value,type),
112
+ @statement.registerOutParameter(@out_index[arg], @connection.get_java_sql_type(ora_value,type),
113
113
  metadata[:sql_type_name])
114
114
  else
115
115
  @statement.registerOutParameter(@out_index[arg],@connection.get_java_sql_type(ora_value,type))
116
116
  end
117
117
  end
118
118
  end
119
-
119
+
120
120
  def exec
121
121
  @statement.execute
122
122
  end
@@ -128,9 +128,9 @@ module PLSQL
128
128
  def close
129
129
  @statement.close
130
130
  end
131
-
131
+
132
132
  private
133
-
133
+
134
134
  def bind_param_index(key)
135
135
  return key if key.kind_of? Integer
136
136
  key = ":#{key.to_s}" unless key.to_s =~ /^:/
@@ -301,7 +301,7 @@ module PLSQL
301
301
  raise ArgumentError, "Don't know how to bind variable with type #{type_symbol}"
302
302
  end
303
303
  end
304
-
304
+
305
305
  def get_bind_variable(stmt, i, type)
306
306
  case type.to_s.to_sym
307
307
  when :Fixnum, :Bignum, :Integer
@@ -337,7 +337,7 @@ module PLSQL
337
337
  end
338
338
 
339
339
  def result_set_to_ruby_data_type(column_type, column_type_name)
340
-
340
+
341
341
  end
342
342
 
343
343
  def plsql_to_ruby_data_type(metadata)
@@ -371,8 +371,10 @@ module PLSQL
371
371
  def ruby_value_to_ora_value(value, type=nil, metadata={})
372
372
  type ||= value.class
373
373
  case type.to_s.to_sym
374
- when :Fixnum, :String
374
+ when :Fixnum
375
375
  value
376
+ when :String
377
+ value.to_s
376
378
  when :BigDecimal
377
379
  case value
378
380
  when TrueClass
@@ -521,7 +523,7 @@ module PLSQL
521
523
  end
522
524
 
523
525
  private
524
-
526
+
525
527
  def java_date(value)
526
528
  value && Java::oracle.sql.DATE.new(value.strftime("%Y-%m-%d %H:%M:%S"))
527
529
  end
@@ -538,7 +540,7 @@ module PLSQL
538
540
  # return BigDecimal instead of Float to avoid rounding errors
539
541
  num == (num_to_i = num.to_i) ? num_to_i : (num.is_a?(BigDecimal) ? num : BigDecimal.new(num.to_s))
540
542
  end
541
-
543
+
542
544
  end
543
-
545
+
544
546
  end
@@ -37,6 +37,10 @@ module PLSQL
37
37
  @package_objects = {}
38
38
  end
39
39
 
40
+ def procedure_defined?(name)
41
+ PLSQL::Procedure.find(@schema, name, @package) ? true : false
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def method_missing(method, *args, &block)
@@ -26,8 +26,6 @@ module PLSQL
26
26
 
27
27
  @cursor.exec
28
28
 
29
- dbms_output_log
30
-
31
29
  if block_given?
32
30
  yield get_return_value
33
31
  nil
@@ -36,6 +34,7 @@ module PLSQL
36
34
  end
37
35
  ensure
38
36
  @cursor.close if @cursor
37
+ dbms_output_log
39
38
  end
40
39
 
41
40
  private
@@ -215,10 +214,8 @@ module PLSQL
215
214
  end
216
215
  add_out_variables
217
216
 
218
- dbms_output_enable_sql, dbms_output_get_sql = dbms_output_sql
219
-
220
217
  @sql = @declare_sql.empty? ? "" : "DECLARE\n" << @declare_sql
221
- @sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql << dbms_output_get_sql << @return_sql << "END;\n"
218
+ @sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql << @return_sql << "END;\n"
222
219
  end
223
220
 
224
221
  def add_argument(argument, value, argument_metadata=nil)
@@ -539,34 +536,24 @@ module PLSQL
539
536
  @procedure_name ||= @procedure.procedure
540
537
  end
541
538
 
542
- def dbms_output_sql
543
- if @dbms_output_stream
544
- dbms_output_enable_sql = "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n"
545
- # if database version is at least 10.2 then use DBMS_OUTPUT.GET_LINES with SYS.DBMSOUTPUT_LINESARRAY
546
- if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
547
- @declare_sql << "l_dbms_output_numlines INTEGER := #{Schema::DBMS_OUTPUT_MAX_LINES};\n"
548
- dbms_output_get_sql = "DBMS_OUTPUT.GET_LINES(:dbms_output_lines, l_dbms_output_numlines);\n"
549
- @bind_values[:dbms_output_lines] = nil
550
- @bind_metadata[:dbms_output_lines] = {:data_type => 'TABLE', :data_length => nil,
551
- :sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY", :in_out => 'OUT'}
552
- # if database version is less than 10.2 then use individual DBMS_OUTPUT.GET_LINE calls
553
- else
554
- dbms_output_get_sql = ""
555
- end
556
- [dbms_output_enable_sql, dbms_output_get_sql]
557
- else
558
- ["", ""]
559
- end
539
+ def dbms_output_enable_sql
540
+ @dbms_output_stream ? "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n" : ""
560
541
  end
561
542
 
562
- def dbms_output_log
543
+ def dbms_output_lines
544
+ lines = []
563
545
  if @dbms_output_stream
564
- # if database version is at least 10.2 then :dbms_output_lines output bind variable has dbms_output lines
565
- if @bind_metadata[:dbms_output_lines]
566
- @cursor[':dbms_output_lines'].each do |line|
567
- @dbms_output_stream.puts "DBMS_OUTPUT: #{line}" if line
568
- end
569
- # if database version is less than 10.2 then use individual DBMS_OUTPUT.GET_LINE calls
546
+ if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
547
+ cursor = @schema.connection.parse("BEGIN DBMS_OUTPUT.GET_LINES(:dbms_output_lines, :dbms_output_numlines); END;\n")
548
+ cursor.bind_param(':dbms_output_lines', nil,
549
+ :data_type => 'TABLE',
550
+ :data_length => nil,
551
+ :sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY",
552
+ :in_out => 'OUT')
553
+ cursor.bind_param(':dbms_output_numlines', Schema::DBMS_OUTPUT_MAX_LINES, :data_type => 'NUMBER', :in_out => 'IN/OUT')
554
+ cursor.exec
555
+ lines = cursor[':dbms_output_lines']
556
+ cursor.close
570
557
  else
571
558
  cursor = @schema.connection.parse("BEGIN sys.dbms_output.get_line(:line, :status); END;")
572
559
  while true do
@@ -574,14 +561,21 @@ module PLSQL
574
561
  cursor.bind_param(':status', nil, :data_type => 'NUMBER', :in_out => 'OUT')
575
562
  cursor.exec
576
563
  break unless cursor[':status'] == 0
577
- @dbms_output_stream.puts "DBMS_OUTPUT: #{cursor[':line']}"
564
+ lines << cursor[':line']
578
565
  end
579
566
  cursor.close
580
567
  end
581
- @dbms_output_stream.flush
582
568
  end
569
+ lines
570
+ end
571
+
572
+ def dbms_output_log
573
+ dbms_output_lines.each do |line|
574
+ @dbms_output_stream.puts "DBMS_OUTPUT: #{line}" if line
575
+ end
576
+ @dbms_output_stream.flush if @dbms_output_stream
583
577
  end
584
578
 
585
579
  end
586
580
 
587
- end
581
+ end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: ruby-plsql 0.5.2 ruby lib
5
+ # stub: ruby-plsql 0.5.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "ruby-plsql"
9
- s.version = "0.5.2"
9
+ s.version = "0.5.3"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Raimonds Simanovskis"]
14
- s.date = "2014-10-23"
14
+ s.date = "2015-05-07"
15
15
  s.description = "ruby-plsql gem provides simple Ruby API for calling Oracle PL/SQL procedures.\nIt could be used both for accessing Oracle PL/SQL API procedures in legacy applications\nas well as it could be used to create PL/SQL unit tests using Ruby testing libraries.\n"
16
16
  s.email = "raimonds.simanovskis@gmail.com"
17
17
  s.extra_rdoc_files = [
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  "README.md",
25
25
  "Rakefile",
26
26
  "VERSION",
27
+ "Vagrantfile",
27
28
  "lib/plsql/connection.rb",
28
29
  "lib/plsql/helpers.rb",
29
30
  "lib/plsql/jdbc_connection.rb",
@@ -55,10 +56,12 @@ Gem::Specification.new do |s|
55
56
  "spec/plsql/version_spec.rb",
56
57
  "spec/plsql/view_spec.rb",
57
58
  "spec/spec.opts",
58
- "spec/spec_helper.rb"
59
+ "spec/spec_helper.rb",
60
+ "spec/support/file_check_script.sh",
61
+ "spec/support/test_db.rb"
59
62
  ]
60
63
  s.homepage = "http://github.com/rsim/ruby-plsql"
61
- s.rubygems_version = "2.2.2"
64
+ s.rubygems_version = "2.4.6"
62
65
  s.summary = "Ruby API for calling Oracle PL/SQL procedures."
63
66
 
64
67
  if s.respond_to? :specification_version then
@@ -67,14 +70,14 @@ Gem::Specification.new do |s|
67
70
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
71
  s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
69
72
  s.add_development_dependency(%q<rspec>, ["~> 3.1"])
70
- s.add_development_dependency(%q<activerecord>, ["< 4.2.0", ">= 3.2.3"])
73
+ s.add_development_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
71
74
  s.add_development_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
72
75
  s.add_development_dependency(%q<simplecov>, [">= 0"])
73
76
  s.add_development_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
74
77
  else
75
78
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
76
79
  s.add_dependency(%q<rspec>, ["~> 3.1"])
77
- s.add_dependency(%q<activerecord>, ["< 4.2.0", ">= 3.2.3"])
80
+ s.add_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
78
81
  s.add_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
79
82
  s.add_dependency(%q<simplecov>, [">= 0"])
80
83
  s.add_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
@@ -82,7 +85,7 @@ Gem::Specification.new do |s|
82
85
  else
83
86
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
84
87
  s.add_dependency(%q<rspec>, ["~> 3.1"])
85
- s.add_dependency(%q<activerecord>, ["< 4.2.0", ">= 3.2.3"])
88
+ s.add_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
86
89
  s.add_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
87
90
  s.add_dependency(%q<simplecov>, [">= 0"])
88
91
  s.add_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
@@ -117,7 +117,7 @@ describe "Connection" do
117
117
  clob = OCI8::CLOB.new(@raw_conn, large_text)
118
118
  expect(@conn.ora_value_to_ruby_value(clob)).to eq large_text
119
119
  end
120
-
120
+
121
121
  end
122
122
 
123
123
  # JRuby
@@ -132,19 +132,23 @@ describe "Connection" do
132
132
  it "should translate PL/SQL NUMBER to Ruby BigDecimal" do
133
133
  expect(@conn.plsql_to_ruby_data_type(:data_type => "NUMBER", :data_length => 15)).to eq [BigDecimal, nil]
134
134
  end
135
-
135
+
136
136
  it "should translate PL/SQL DATE to Ruby DateTime" do
137
137
  expect(@conn.plsql_to_ruby_data_type(:data_type => "DATE", :data_length => nil)).to eq [DateTime, nil]
138
138
  end
139
-
139
+
140
140
  it "should translate PL/SQL TIMESTAMP to Ruby Time" do
141
141
  expect(@conn.plsql_to_ruby_data_type(:data_type => "TIMESTAMP", :data_length => nil)).to eq [Time, nil]
142
142
  end
143
-
143
+
144
144
  it "should not translate Ruby Fixnum when BigDecimal type specified" do
145
145
  expect(@conn.ruby_value_to_ora_value(100, BigDecimal)).to eq java.math.BigDecimal.new(100)
146
146
  end
147
-
147
+
148
+ it "should translate Ruby String to string value" do
149
+ expect(@conn.ruby_value_to_ora_value(1.1, String)).to eq '1.1'
150
+ end
151
+
148
152
  it "should translate Ruby Bignum value to BigDecimal when BigDecimal type specified" do
149
153
  big_decimal = @conn.ruby_value_to_ora_value(12345678901234567890, BigDecimal)
150
154
  expect(big_decimal).to eq java.math.BigDecimal.new("12345678901234567890")
@@ -167,7 +171,7 @@ describe "Connection" do
167
171
  it "should translate Oracle BigDecimal integer value to Fixnum" do
168
172
  expect(@conn.ora_value_to_ruby_value(BigDecimal("100"))).to eql(100)
169
173
  end
170
-
174
+
171
175
  it "should translate Oracle BigDecimal float value to BigDecimal" do
172
176
  expect(@conn.ora_value_to_ruby_value(BigDecimal("100.11"))).to eql(BigDecimal("100.11"))
173
177
  end
@@ -210,7 +214,7 @@ describe "Connection" do
210
214
  expect(@conn.select_first("SELECT :1,:2,:3,:4,:5 FROM dual",
211
215
  'abc',123,123.456,@now,@today)).to eq ["abc",123,123.456,@now,Time.parse(@today.to_s)]
212
216
  end
213
-
217
+
214
218
  it "should execute SQL statement with NULL values and return first result" do
215
219
  @now = Time.local(2008,05,31,23,22,11)
216
220
  expect(@conn.select_first("SELECT NULL,123,123.456,
@@ -226,7 +230,7 @@ describe "Connection" do
226
230
  expect(@conn.select_first("SELECT :1,:2,:3,:4,:5 FROM dual",
227
231
  nil,123,123.456,@now,@today)).to eq [nil,123,123.456,@now,Time.parse(@today.to_s)]
228
232
  end
229
-
233
+
230
234
  end
231
235
 
232
236
  it "should execute SQL statement and return all results" do
@@ -254,7 +258,7 @@ describe "Connection" do
254
258
  expect(@conn.select_all("SELECT :1,:2,:3,:4 FROM dual UNION ALL SELECT :1,:2,:3,:4 FROM dual",
255
259
  'abc',123,123.456,@now,'abc',123,123.456,@now)).to eq [["abc",123,123.456,@now],["abc",123,123.456,@now]]
256
260
  end
257
-
261
+
258
262
  it "should execute SQL statement and yield all results in block" do
259
263
  @now = Time.local(2008,05,31,23,22,11)
260
264
  expect(@conn.select_all("SELECT 'abc',123,123.456,
@@ -266,7 +270,7 @@ describe "Connection" do
266
270
  expect(r).to eq ["abc",123,123.456,@now]
267
271
  end).to eq 2
268
272
  end
269
-
273
+
270
274
  it "should execute SQL statement with bind parameters and yield all results in block" do
271
275
  @now = Time.local(2008,05,31,23,22,11)
272
276
  expect(@conn.select_all("SELECT :1,:2,:3,:4 FROM dual UNION ALL SELECT :1,:2,:3,:4 FROM dual",
@@ -276,7 +280,7 @@ describe "Connection" do
276
280
  end
277
281
 
278
282
  end
279
-
283
+
280
284
  describe "PL/SQL procedures" do
281
285
  before(:all) do
282
286
  @random = rand(1000)
@@ -313,9 +317,9 @@ describe "Connection" do
313
317
  expect(cursor[":p_date"]).to eq @now
314
318
  expect(cursor.close).to be_nil
315
319
  end
316
-
320
+
317
321
  end
318
-
322
+
319
323
  describe "commit and rollback" do
320
324
  before(:all) do
321
325
  expect(@conn.exec("CREATE TABLE test_commit (dummy VARCHAR2(100))")).to be true
@@ -47,6 +47,14 @@ describe "Package" do
47
47
  expect(plsql.test_package.test_procedure('xxx')).to eq('XXX')
48
48
  end
49
49
 
50
+ it "should report an existing procedure as existing" do
51
+ expect(plsql.test_package.procedure_defined?(:test_procedure)).to be_truthy
52
+ end
53
+
54
+ it "should report an inexistent procedure as not existing" do
55
+ expect(plsql.test_package.procedure_defined?(:inexistent_procedure)).to be_falsey
56
+ end
57
+
50
58
  describe "variables" do
51
59
  it "should set and get package variable value" do
52
60
  plsql.test_package.test_variable = 1
@@ -227,10 +227,13 @@ describe "DBMS_OUTPUT logging" do
227
227
  before(:all) do
228
228
  plsql.connection = get_connection
229
229
  plsql.execute <<-SQL
230
- CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2)
230
+ CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2, p_raise_error BOOLEAN := false)
231
231
  IS
232
232
  BEGIN
233
233
  DBMS_OUTPUT.PUT_LINE(p_string);
234
+ IF p_raise_error THEN
235
+ RAISE_APPLICATION_ERROR(-20000 - 12, 'Test Error');
236
+ END IF;
234
237
  END;
235
238
  SQL
236
239
  plsql.execute <<-SQL
@@ -272,6 +275,11 @@ describe "DBMS_OUTPUT logging" do
272
275
  expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
273
276
  end
274
277
 
278
+ it "should log output to specified stream in case of exception" do
279
+ expect { plsql.test_dbms_output("test_dbms_output", true) }.to raise_error /Test Error/
280
+ expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
281
+ end
282
+
275
283
  it "should not log output to stream when output is disabled" do
276
284
  plsql.test_dbms_output("enabled")
277
285
  plsql.dbms_output_stream = nil
@@ -23,7 +23,16 @@ end
23
23
 
24
24
  require 'ruby-plsql'
25
25
 
26
- DATABASE_NAME = ENV['DATABASE_NAME'] || 'orcl'
26
+ # Requires supporting ruby files with custom matchers and macros, etc,
27
+ # in spec/support/ and its subdirectories.
28
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each {|f| require f}
29
+
30
+ if ENV['USE_VM_DATABASE'] == 'Y'
31
+ DATABASE_NAME = 'XE'
32
+ else
33
+ DATABASE_NAME = ENV['DATABASE_NAME'] || 'orcl'
34
+ end
35
+
27
36
  DATABASE_SERVICE_NAME = (defined?(JRUBY_VERSION) ? "/" : "") +
28
37
  (ENV['DATABASE_SERVICE_NAME'] || DATABASE_NAME)
29
38
  DATABASE_HOST = ENV['DATABASE_HOST'] || 'localhost'
@@ -35,6 +44,20 @@ DATABASE_USERS_AND_PASSWORDS = [
35
44
  # specify which database version is used (will be verified in one test)
36
45
  DATABASE_VERSION = ENV['DATABASE_VERSION'] || '10.2.0.4'
37
46
 
47
+ if ENV['USE_VM_DATABASE'] == 'Y'
48
+ RSpec.configure do |config|
49
+ config.before(:suite) do
50
+ TestDb.build
51
+
52
+ # Set Verbose off to hide warning: already initialized constant DATABASE_VERSION
53
+ original_verbosity = $VERBOSE
54
+ $VERBOSE = nil
55
+ DATABASE_VERSION = TestDb.database_version
56
+ $VERBOSE = original_verbosity
57
+ end
58
+ end
59
+ end
60
+
38
61
  def get_eazy_connect_url(svc_separator = "")
39
62
  "#{DATABASE_HOST}:#{DATABASE_PORT}#{svc_separator}#{DATABASE_SERVICE_NAME}"
40
63
  end
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ FILE=/vagrant/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
5
+
6
+ if [ ! -f "$FILE" ] ; then
7
+ echo "Oracle XE database installation (oracle-xe-11.2.0-1.0.x86_64.rpm.zip) can not be found. Please download from Oracle homepage and put it into project home directory."
8
+ exit 1
9
+ fi
@@ -0,0 +1,150 @@
1
+ class TestDb
2
+
3
+ DATABASE_USERS = %w{hr arunit}
4
+
5
+ def self.build
6
+ db = self.new
7
+ db.cleanup_database_users
8
+ db.create_user_tablespace
9
+ db.setup_database_users
10
+ db.connection.logoff
11
+ end
12
+
13
+ def self.database_version
14
+ db = self.new
15
+ db.database_version
16
+ end
17
+
18
+ def connection
19
+ unless defined?(@connection)
20
+ begin
21
+ Timeout::timeout(5) {
22
+ if defined?(JRUBY_VERSION)
23
+ @connection = java.sql.DriverManager.get_connection(
24
+ 'jdbc:oracle:thin:@127.0.0.1:1521/XE',
25
+ 'system',
26
+ 'oracle'
27
+ );
28
+ else
29
+ @connection = OCI8.new(
30
+ 'system',
31
+ 'oracle',
32
+ '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)))'
33
+ )
34
+ end
35
+ }
36
+ rescue Timeout::Error
37
+ raise "Cannot establish connection with Oracle database as SYSTEM user. Seams you need to start local Oracle database"
38
+ end
39
+ end
40
+ @connection
41
+ end
42
+
43
+ def create_user_tablespace
44
+ return unless connection
45
+ execute_statement(<<-STATEMENT
46
+ DECLARE
47
+ v_exists number;
48
+ BEGIN
49
+ SELECT count(1)
50
+ INTO v_exists
51
+ FROM dba_tablespaces
52
+ WHERE tablespace_name = 'TBS_USERS';
53
+
54
+ IF v_exists = 0 THEN
55
+ EXECUTE IMMEDIATE 'ALTER SYSTEM SET DB_CREATE_FILE_DEST = ''/u01/app/oracle/oradata/XE''';
56
+ EXECUTE IMMEDIATE 'CREATE TABLESPACE TBS_USERS DATAFILE ''tbs_users.dat'' SIZE 10M REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 200M';
57
+ END IF;
58
+ END;
59
+ STATEMENT
60
+ )
61
+ end
62
+
63
+ def database_users
64
+ DATABASE_USERS.inject([]){|array, user| array << [user.upcase, user]}
65
+ end
66
+
67
+ def cleanup_database_users
68
+ return unless connection
69
+ database_users.each do | db, _ |
70
+ execute_statement(<<-STATEMENT
71
+ DECLARE
72
+ v_count INTEGER := 0;
73
+ l_cnt INTEGER;
74
+ BEGIN
75
+
76
+ SELECT COUNT (1)
77
+ INTO v_count
78
+ FROM dba_users
79
+ WHERE username = '#{db}';
80
+
81
+ IF v_count != 0 THEN
82
+ FOR x IN (SELECT *
83
+ FROM v$session
84
+ WHERE username = '#{db}')
85
+ LOOP
86
+ EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION ''' || x.sid || ',' || x.serial# || ''' IMMEDIATE';
87
+ END LOOP;
88
+
89
+ EXECUTE IMMEDIATE ('DROP USER #{db} CASCADE');
90
+ END IF;
91
+ END;
92
+ STATEMENT
93
+ )
94
+ end
95
+ end
96
+
97
+ def setup_database_users
98
+ return unless connection
99
+ database_users.each do | db, passwd |
100
+ execute_statement(<<-STATEMENT
101
+ DECLARE
102
+ v_count INTEGER := 0;
103
+ BEGIN
104
+
105
+ SELECT COUNT (1)
106
+ INTO v_count
107
+ FROM dba_users
108
+ WHERE username = '#{db}';
109
+
110
+ IF v_count = 0 THEN
111
+ EXECUTE IMMEDIATE ('CREATE USER #{db} IDENTIFIED BY #{passwd} DEFAULT TABLESPACE TBS_USERS QUOTA 10m ON TBS_USERS');
112
+ EXECUTE IMMEDIATE ('GRANT create session, create table, create sequence, create procedure, create type, create view, create synonym TO #{db}');
113
+ END IF;
114
+ END;
115
+ STATEMENT
116
+ )
117
+ end
118
+ end
119
+
120
+ def database_version
121
+ query = 'SELECT version FROM V$INSTANCE'
122
+
123
+ if defined?(JRUBY_VERSION)
124
+ statement = connection.create_statement
125
+ resource = statement.execute_query(query)
126
+
127
+ resource.next
128
+ value = resource.get_string('VERSION')
129
+
130
+ resource.close
131
+ statement.close
132
+ else
133
+ cursor = execute_statement(query)
134
+ value = cursor.fetch()[0]
135
+ cursor.close
136
+ end
137
+
138
+ value.match(/(.*)\.\d$/)[1]
139
+ end
140
+
141
+ def execute_statement(statement)
142
+ if defined?(JRUBY_VERSION)
143
+ statement = connection.prepare_call(statement)
144
+ statement.execute
145
+ statement.close
146
+ else
147
+ connection.exec(statement)
148
+ end
149
+ end
150
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-plsql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raimonds Simanovskis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2015-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jeweler
@@ -44,7 +44,7 @@ dependencies:
44
44
  requirements:
45
45
  - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: 4.2.0
47
+ version: 4.3.0
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
50
  version: 3.2.3
@@ -54,7 +54,7 @@ dependencies:
54
54
  requirements:
55
55
  - - "<"
56
56
  - !ruby/object:Gem::Version
57
- version: 4.2.0
57
+ version: 4.3.0
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 3.2.3
@@ -122,6 +122,7 @@ files:
122
122
  - README.md
123
123
  - Rakefile
124
124
  - VERSION
125
+ - Vagrantfile
125
126
  - lib/plsql/connection.rb
126
127
  - lib/plsql/helpers.rb
127
128
  - lib/plsql/jdbc_connection.rb
@@ -154,6 +155,8 @@ files:
154
155
  - spec/plsql/view_spec.rb
155
156
  - spec/spec.opts
156
157
  - spec/spec_helper.rb
158
+ - spec/support/file_check_script.sh
159
+ - spec/support/test_db.rb
157
160
  homepage: http://github.com/rsim/ruby-plsql
158
161
  licenses: []
159
162
  metadata: {}
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
176
  version: '0'
174
177
  requirements: []
175
178
  rubyforge_project:
176
- rubygems_version: 2.2.2
179
+ rubygems_version: 2.4.6
177
180
  signing_key:
178
181
  specification_version: 4
179
182
  summary: Ruby API for calling Oracle PL/SQL procedures.