Class: PLSQL::Procedure
- Inherits:
-
Object
- Object
- PLSQL::Procedure
- Extended by:
- ProcedureClassMethods
- Defined in:
- lib/plsql/procedure.rb
Instance Method Summary collapse
- #exec(*args) ⇒ Object
-
#initialize(schema, procedure, package = nil) ⇒ Procedure
constructor
A new instance of Procedure.
- #overloaded? ⇒ Boolean
Methods included from ProcedureClassMethods
Constructor Details
#initialize(schema, procedure, package = nil) ⇒ Procedure
Returns a new instance of Procedure.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/plsql/procedure.rb', line 28 def initialize(schema, procedure, package = nil) @schema = schema @procedure = procedure.to_s.upcase @package = package @arguments = {} @argument_list = {} @out_list = {} @return = {} @overloaded = false # RSI: due to 10gR2 all_arguments performance issue SELECT split into two statements # added condition to ensure that if object is package then package specification not body is selected object_id = @schema.connection.select_first(" SELECT o.object_id FROM all_objects o WHERE o.owner = :owner AND o.object_name = :object_name AND o.object_type <> 'PACKAGE BODY' ", @schema.schema_name, @package ? @package : @procedure )[0] rescue nil num_rows = @schema.connection.select_all(" SELECT a.argument_name, a.position, a.data_type, a.in_out, a.data_length, a.data_precision, a.data_scale, a.overload FROM all_arguments a WHERE a.object_id = :object_id AND a.owner = :owner AND a.object_name = :procedure_name AND NVL(a.package_name,'nil') = :package ", object_id, @schema.schema_name, @procedure, @package ? @package : 'nil' ) do |r| argument_name, position, data_type, in_out, data_length, data_precision, data_scale, overload = r @overloaded ||= !overload.nil? # if not overloaded then store arguments at key 0 overload ||= 0 @arguments[overload] ||= {} @return[overload] ||= nil if argument_name @arguments[overload][argument_name.downcase.to_sym] = { :position => position, :data_type => data_type, :in_out => in_out, :data_length => data_length, :data_precision => data_precision, :data_scale => data_scale } # if function has return value elsif position == 0 && in_out == 'OUT' @return[overload] = { :data_type => data_type, :in_out => in_out, :data_length => data_length, :data_precision => data_precision, :data_scale => data_scale } end end @overloads = @arguments.keys.sort @overloads.each do |overload| @argument_list[overload] = @arguments[overload].keys.sort {|k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position]} @out_list[overload] = @argument_list[overload].select {|k| @arguments[overload][k][:in_out] =~ /OUT/} end end |
Instance Method Details
#exec(*args) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/plsql/procedure.rb', line 96 def exec(*args) # find which overloaded definition to use # if definition is overloaded then match by number of arguments if @overloaded # named arguments if args.size == 1 && args[0].is_a?(Hash) number_of_args = args[0].keys.size overload = @argument_list.keys.detect do |ov| @argument_list[ov].size == number_of_args && @arguments[ov].keys.sort_by{|k| k.to_s} == args[0].keys.sort_by{|k| k.to_s} end # sequential arguments # TODO: should try to implement matching by types of arguments else number_of_args = args.size overload = @argument_list.keys.detect do |ov| @argument_list[ov].size == number_of_args end end raise ArgumentError, "Wrong number of arguments passed to overloaded PL/SQL procedure" unless overload else overload = 0 end sql = "BEGIN\n" sql << ":return := " if @return[overload] sql << "#{@schema.schema_name}." if @schema sql << "#{@package}." if @package sql << "#{@procedure}(" # Named arguments args_list = [] args_hash = {} if args.size == 1 and args[0].is_a?(Hash) sql << args[0].map do |k,v| raise ArgumentError, "Wrong argument passed to PL/SQL procedure" unless @arguments[overload][k] args_list << k args_hash[k] = v "#{k.to_s} => :#{k.to_s}" end.join(', ') # Sequential arguments else raise ArgumentError, "Too many arguments passed to PL/SQL procedure" if args.size > @argument_list[overload].size # Add missing arguments with nil value args = args + [nil]*(@argument_list[overload].size-args.size) if args.size < @argument_list[overload].size i = 0 sql << args.map do |v| k = @argument_list[overload][i] i += 1 args_list << k args_hash[k] = v ":#{k.to_s}" end.join(', ') end sql << ");\n" sql << "END;\n" cursor = @schema.connection.parse(sql) args_list.each do |k| data_type, data_length = plsql_to_ruby_data_type(@arguments[overload][k]) cursor.bind_param(":#{k.to_s}", ruby_value_to_ora_value(args_hash[k], data_type), data_type, data_length, @arguments[overload][k][:in_out]) end if @return[overload] data_type, data_length = plsql_to_ruby_data_type(@return[overload]) cursor.bind_param(":return", nil, data_type, data_length, 'OUT') end cursor.exec # if function with output parameters if @return[overload] && @out_list[overload].size > 0 result = [ora_value_to_ruby_value(cursor[':return']), {}] @out_list[overload].each do |k| result[1][k] = ora_value_to_ruby_value(cursor[":#{k}"]) end # if function without output parameters elsif @return[overload] result = ora_value_to_ruby_value(cursor[':return']) # if procedure with output parameters elsif @out_list[overload].size > 0 result = {} @out_list[overload].each do |k| result[k] = ora_value_to_ruby_value(cursor[":#{k}"]) end # if procedure without output parameters else result = nil end cursor.close result end |
#overloaded? ⇒ Boolean
92 93 94 |
# File 'lib/plsql/procedure.rb', line 92 def overloaded? @overloaded end |