ruby-plsql 0.9.9-java

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.
@@ -0,0 +1,230 @@
1
+ module PLSQL
2
+ class Connection
3
+ attr_reader :raw_driver
4
+ attr_reader :activerecord_class
5
+
6
+ def initialize(raw_conn, ar_class = nil) # :nodoc:
7
+ @raw_driver = self.class.driver_type
8
+ @raw_connection = raw_conn
9
+ @activerecord_class = ar_class
10
+ end
11
+
12
+ def self.create(raw_conn, ar_class = nil) # :nodoc:
13
+ if ar_class && !(defined?(::ActiveRecord) && ar_class.ancestors.include?(::ActiveRecord::Base))
14
+ raise ArgumentError, "Wrong ActiveRecord class"
15
+ end
16
+ case driver_type
17
+ when :oci
18
+ OCIConnection.new(raw_conn, ar_class)
19
+ when :jdbc
20
+ JDBCConnection.new(raw_conn, ar_class)
21
+ else
22
+ raise ArgumentError, "Unknown raw driver"
23
+ end
24
+ end
25
+
26
+ def self.create_new(params) # :nodoc:
27
+ conn = case driver_type
28
+ when :oci
29
+ OCIConnection.create_raw(params)
30
+ when :jdbc
31
+ JDBCConnection.create_raw(params)
32
+ else
33
+ raise ArgumentError, "Unknown raw driver"
34
+ end
35
+ conn.set_time_zone(params[:time_zone] || ENV["ORA_SDTZ"])
36
+ conn
37
+ end
38
+
39
+ def self.driver_type # :nodoc:
40
+ # MRI 1.8.6 or YARV 1.9.1 or TruffleRuby
41
+ @driver_type ||= if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby") && defined?(OCI8)
42
+ :oci
43
+ # JRuby
44
+ elsif (defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby")
45
+ :jdbc
46
+ else
47
+ nil
48
+ end
49
+ end
50
+
51
+ # Returns OCI8 or JDBC connection
52
+ def raw_connection
53
+ if @activerecord_class
54
+ @activerecord_class.connection.raw_connection
55
+ else
56
+ @raw_connection
57
+ end
58
+ end
59
+
60
+ # Is it OCI8 connection
61
+ def oci?
62
+ @raw_driver == :oci
63
+ end
64
+
65
+ # Is it JDBC connection
66
+ def jdbc?
67
+ @raw_driver == :jdbc
68
+ end
69
+
70
+ def logoff # :nodoc:
71
+ # Rollback any uncommited transactions
72
+ rollback
73
+ # Common cleanup activities before logoff, should be called from particular driver method
74
+ drop_session_ruby_temporary_tables
75
+ end
76
+
77
+ def commit # :nodoc:
78
+ raise NoMethodError, "Not implemented for this raw driver"
79
+ end
80
+
81
+ def rollback # :nodoc:
82
+ raise NoMethodError, "Not implemented for this raw driver"
83
+ end
84
+
85
+ # Current autocommit mode (true or false)
86
+ def autocommit?
87
+ raise NoMethodError, "Not implemented for this raw driver"
88
+ end
89
+
90
+ # Set autocommit mode (true or false)
91
+ def autocommit=(value)
92
+ raise NoMethodError, "Not implemented for this raw driver"
93
+ end
94
+
95
+ # Set number of rows to be prefetched. This can reduce the number of network round trips when fetching many rows.
96
+ # The default value is one. (If ActiveRecord oracle_enhanced connection is used then default is 100)
97
+ def prefetch_rows=(value)
98
+ raise NoMethodError, "Not implemented for this raw driver"
99
+ end
100
+
101
+ def select_first(sql, *bindvars) # :nodoc:
102
+ cursor = cursor_from_query(sql, bindvars, prefetch_rows: 1)
103
+ cursor.fetch
104
+ ensure
105
+ cursor.close rescue nil
106
+ end
107
+
108
+ def select_hash_first(sql, *bindvars) # :nodoc:
109
+ cursor = cursor_from_query(sql, bindvars, prefetch_rows: 1)
110
+ cursor.fetch_hash
111
+ ensure
112
+ cursor.close rescue nil
113
+ end
114
+
115
+ def select_all(sql, *bindvars, &block) # :nodoc:
116
+ cursor = cursor_from_query(sql, bindvars)
117
+ results = []
118
+ row_count = 0
119
+ while row = cursor.fetch
120
+ if block_given?
121
+ yield(row)
122
+ row_count += 1
123
+ else
124
+ results << row
125
+ end
126
+ end
127
+ block_given? ? row_count : results
128
+ ensure
129
+ cursor.close rescue nil
130
+ end
131
+
132
+ def select_hash_all(sql, *bindvars, &block) # :nodoc:
133
+ cursor = cursor_from_query(sql, bindvars)
134
+ results = []
135
+ row_count = 0
136
+ while row = cursor.fetch_hash
137
+ if block_given?
138
+ yield(row)
139
+ row_count += 1
140
+ else
141
+ results << row
142
+ end
143
+ end
144
+ block_given? ? row_count : results
145
+ ensure
146
+ cursor.close rescue nil
147
+ end
148
+
149
+ def exec(sql, *bindvars) # :nodoc:
150
+ raise NoMethodError, "Not implemented for this raw driver"
151
+ end
152
+
153
+ def parse(sql) # :nodoc:
154
+ raise NoMethodError, "Not implemented for this raw driver"
155
+ end
156
+
157
+ module CursorCommon
158
+ # Fetch all rows from cursor, each row as array of values
159
+ def fetch_all
160
+ rows = []
161
+ while (row = fetch)
162
+ rows << row
163
+ end
164
+ rows
165
+ end
166
+
167
+ # Fetch all rows from cursor, each row as hash {:column => value, ...}
168
+ def fetch_hash_all
169
+ rows = []
170
+ while (row = fetch_hash)
171
+ rows << row
172
+ end
173
+ rows
174
+ end
175
+
176
+ # Fetch row from cursor as hash {:column => value, ...}
177
+ def fetch_hash
178
+ (row = fetch) && ArrayHelpers::to_hash(fields, row)
179
+ end
180
+ end
181
+
182
+ # all_synonyms view is quite slow therefore
183
+ # this implementation is overriden in OCI connection with faster native OCI method
184
+ def describe_synonym(schema_name, synonym_name) # :nodoc:
185
+ select_first(
186
+ "SELECT table_owner, table_name FROM all_synonyms WHERE owner = :owner AND synonym_name = :synonym_name",
187
+ schema_name.to_s.upcase, synonym_name.to_s.upcase)
188
+ end
189
+
190
+ # Returns array with major and minor version of database (e.g. [10, 2])
191
+ def database_version
192
+ raise NoMethodError, "Not implemented for this raw driver"
193
+ end
194
+
195
+ # Returns session ID
196
+ def session_id
197
+ @session_id ||= select_first("SELECT TO_NUMBER(USERENV('SESSIONID')) FROM dual")[0]
198
+ end
199
+
200
+ # Set time zone
201
+ def set_time_zone(time_zone = nil)
202
+ exec("alter session set time_zone = '#{time_zone}'") if time_zone
203
+ end
204
+
205
+ # Returns session time zone
206
+ def time_zone
207
+ select_first("SELECT SESSIONTIMEZONE FROM dual")[0]
208
+ end
209
+
210
+ RUBY_TEMP_TABLE_PREFIX = "ruby_"
211
+
212
+ # Drop all ruby temporary tables that are used for calling packages with table parameter types defined in packages
213
+ def drop_all_ruby_temporary_tables
214
+ select_all("SELECT table_name FROM user_tables WHERE temporary='Y' AND table_name LIKE :table_name",
215
+ RUBY_TEMP_TABLE_PREFIX.upcase + "%").each do |row|
216
+ exec "TRUNCATE TABLE #{row[0]}"
217
+ exec "DROP TABLE #{row[0]}"
218
+ end
219
+ end
220
+
221
+ # Drop ruby temporary tables created in current session that are used for calling packages with table parameter types defined in packages
222
+ def drop_session_ruby_temporary_tables
223
+ select_all("SELECT table_name FROM user_tables WHERE temporary='Y' AND table_name LIKE :table_name",
224
+ RUBY_TEMP_TABLE_PREFIX.upcase + "#{session_id}_%").each do |row|
225
+ exec "TRUNCATE TABLE #{row[0]}"
226
+ exec "DROP TABLE #{row[0]}"
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,7 @@
1
+ module PLSQL # :nodoc:
2
+ module ArrayHelpers # :nodoc:
3
+ def self.to_hash(keys, values) # :nodoc:
4
+ (0...keys.size).inject({}) { |hash, i| hash[keys[i]] = values[i]; hash }
5
+ end
6
+ end
7
+ end