ActiveRecord-JDBC 0.4 → 0.5

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 (35) hide show
  1. data/History.txt +12 -0
  2. data/Manifest.txt +13 -0
  3. data/Rakefile +18 -10
  4. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  5. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  6. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  7. data/lib/active_record/connection_adapters/jdbc_adapter.rb +124 -56
  8. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  9. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  10. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  11. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  12. data/lib/jdbc_adapter/jdbc_db2.rb +21 -0
  13. data/lib/jdbc_adapter/jdbc_derby.rb +22 -101
  14. data/lib/jdbc_adapter/jdbc_firebird.rb +5 -1
  15. data/lib/jdbc_adapter/jdbc_hsqldb.rb +23 -1
  16. data/lib/jdbc_adapter/jdbc_mimer.rb +4 -2
  17. data/lib/jdbc_adapter/jdbc_mssql.rb +149 -67
  18. data/lib/jdbc_adapter/jdbc_mysql.rb +22 -2
  19. data/lib/jdbc_adapter/jdbc_oracle.rb +80 -15
  20. data/lib/jdbc_adapter/jdbc_postgre.rb +132 -4
  21. data/lib/jdbc_adapter_internal.jar +0 -0
  22. data/src/java/JDBCDerbySpec.java +323 -0
  23. data/src/java/JDBCMySQLSpec.java +83 -0
  24. data/src/java/JdbcAdapterInternalService.java +802 -0
  25. data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -0
  26. data/test/db/derby.rb +2 -5
  27. data/test/db/h2.rb +2 -5
  28. data/test/db/hsqldb.rb +2 -6
  29. data/test/db/jdbc.rb +9 -0
  30. data/test/db/mysql.rb +4 -15
  31. data/test/db/postgres.rb +2 -3
  32. data/test/generic_jdbc_connection_test.rb +9 -0
  33. data/test/jdbc_adapter/jdbc_db2_test.rb +21 -0
  34. data/test/simple.rb +6 -8
  35. metadata +15 -2
@@ -1,5 +1,9 @@
1
- module JdbcSpec
1
+ module ::JdbcSpec
2
2
  module FireBird
3
+ def self.adapter_selector
4
+ [/firebird/i, lambda{|cfg,adapt| adapt.extend(::JdbcSpec::FireBird)}]
5
+ end
6
+
3
7
  def modify_types(tp)
4
8
  tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
5
9
  tp[:string][:limit] = 252
@@ -1,5 +1,27 @@
1
- module JdbcSpec
1
+ module ::JdbcSpec
2
+ module ActiveRecordExtensions
3
+ def hsqldb_connection(config)
4
+ config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
5
+ config[:driver] ||= "org.hsqldb.jdbcDriver"
6
+ embedded_driver(config)
7
+ end
8
+
9
+ def h2_connection(config)
10
+ config[:url] ||= "jdbc:h2:#{config[:database]}"
11
+ config[:driver] ||= "org.h2.Driver"
12
+ embedded_driver(config)
13
+ end
14
+ end
15
+
2
16
  module HSQLDB
17
+ def self.column_selector
18
+ [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::JdbcSpec::HSQLDB::Column)}]
19
+ end
20
+
21
+ def self.adapter_selector
22
+ [/hsqldb|\.h2\./i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::HSQLDB)}]
23
+ end
24
+
3
25
  module Column
4
26
  def type_cast(value)
5
27
  return nil if value.nil? || value =~ /^\s*null\s*$/i
@@ -1,5 +1,9 @@
1
1
  module JdbcSpec
2
2
  module Mimer
3
+ def self.adapter_selector
4
+ [/mimer/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::Mimer)}]
5
+ end
6
+
3
7
  def modify_types(tp)
4
8
  tp[:primary_key] = "INTEGER NOT NULL PRIMARY KEY"
5
9
  tp[:boolean][:limit] = nil
@@ -110,7 +114,6 @@ module JdbcSpec
110
114
  end
111
115
 
112
116
  def _execute(sql, name = nil)
113
- log_no_bench(sql, name) do
114
117
  if sql =~ /^select/i
115
118
  @offset ||= 0
116
119
  if !@limit || @limit == -1
@@ -122,7 +125,6 @@ module JdbcSpec
122
125
  else
123
126
  @connection.execute_update(sql)
124
127
  end
125
- end
126
128
  ensure
127
129
  @limit = @offset = nil
128
130
  end
@@ -1,10 +1,20 @@
1
1
  module JdbcSpec
2
2
  module MsSQL
3
+ def self.column_selector
4
+ [/sqlserver|tds/i, lambda {|cfg,col| col.extend(::JdbcSpec::MsSQL::Column)}]
5
+ end
6
+
7
+ def self.adapter_selector
8
+ [/sqlserver|tds/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::MsSQL)}]
9
+ end
10
+
3
11
  module Column
12
+ attr_accessor :identity, :is_special
13
+
4
14
  def simplified_type(field_type)
5
15
  case field_type
6
16
  when /int|bigint|smallint|tinyint/i then :integer
7
- when /float|double|decimal|money|numeric|real|smallmoney/i then @scale == 0 ? :integer : :float
17
+ when /float|double|decimal|money|numeric|real|smallmoney/i then @scale == 0 ? :integer : :decimal
8
18
  when /datetime|smalldatetime/i then :datetime
9
19
  when /timestamp/i then :timestamp
10
20
  when /time/i then :time
@@ -17,21 +27,26 @@ module JdbcSpec
17
27
  end
18
28
 
19
29
  def type_cast(value)
20
- return nil if value.nil? || value =~ /^\s*null\s*$/i
30
+ return nil if value.nil? || value == "(NULL)"
21
31
  case type
22
- when :string then value
23
- when :integer then value == true || value == false ? value == true ? 1 : 0 : value.to_i
32
+ when :string then unquote value
33
+ when :integer then unquote(value).to_i rescue value ? 1 : 0
24
34
  when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
25
- when :float then value.to_f
35
+ when :decimal then self.class.value_to_decimal(value)
26
36
  when :datetime then cast_to_datetime(value)
27
37
  when :timestamp then cast_to_time(value)
28
38
  when :time then cast_to_time(value)
29
39
  when :date then cast_to_datetime(value)
30
- when :boolean then value == true or (value =~ /^t(rue)?$/i) == 0 or value.to_s == '1'
40
+ when :boolean then value == true or (value =~ /^t(rue)?$/i) == 0 or unquote(value)=="1"
41
+ when :binary then unquote value
31
42
  else value
32
43
  end
33
44
  end
34
-
45
+
46
+ def unquote(value)
47
+ value.to_s.sub(/^\([\(\']?/, "").sub(/[\'\)]?\)$/, "")
48
+ end
49
+
35
50
  def cast_to_time(value)
36
51
  return value if value.is_a?(Time)
37
52
  time_array = ParseDate.parsedate(value)
@@ -85,77 +100,70 @@ module JdbcSpec
85
100
  tp[:binary] = { :name => "image"}
86
101
  tp
87
102
  end
88
-
103
+
89
104
  def quote(value, column = nil)
90
- if column && column.type == :primary_key
91
- return value.to_s
92
- end
93
- case value
94
- when String
95
- if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
96
- val = quote_string(column.class.string_to_binary(value))
97
- "'#{val}'"
98
- else
99
- "'#{quote_string(value)}'"
100
- end
101
- when NilClass then "NULL"
102
- when TrueClass then '1'
103
- when FalseClass then '0'
104
- when Float, Fixnum, Bignum then value.to_s
105
- when Date then "'#{value.to_s}'"
106
- when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
107
- else "'#{quote_string(value.to_yaml)}'"
108
- end
105
+ return value.quoted_id if value.respond_to?(:quoted_id)
106
+
107
+ case value
108
+ when TrueClass then '1'
109
+ when FalseClass then '0'
110
+ when Time, DateTime then "'#{value.strftime("%Y%m%d %H:%M:%S")}'"
111
+ when Date then "'#{value.strftime("%Y%m%d")}'"
112
+ else super
109
113
  end
114
+ end
110
115
 
111
116
  def quote_string(string)
112
117
  string.gsub(/\'/, "''")
113
118
  end
114
119
 
115
- def quoted_true
116
- "1"
117
- end
118
-
119
- def quoted_false
120
- "0"
121
- end
122
-
123
120
  def quote_column_name(name)
124
121
  "[#{name}]"
125
122
  end
123
+
124
+ def add_limit_offset!(sql, options)
125
+ if options[:limit] and options[:offset]
126
+ total_rows = select_all("SELECT count(*) as TotalRows from (#{sql.gsub(/\bSELECT(\s+DISTINCT)?\b/i, "SELECT#{$1} TOP 1000000000")}) tally")[0][:TotalRows].to_i
126
127
 
127
- def add_limit_offset!(sql, options)
128
- if options[:limit] and options[:offset]
129
- total_rows = @connection.select_all("SELECT count(*) as TotalRows from (#{sql.gsub(/\bSELECT\b/i, "SELECT TOP 1000000000")}) tally")[0][:TotalRows].to_i
130
- if (options[:limit] + options[:offset]) >= total_rows
131
- options[:limit] = (total_rows - options[:offset] >= 0) ? (total_rows - options[:offset]) : 0
132
- end
133
- sql.sub!(/^\s*SELECT/i, "SELECT * FROM (SELECT TOP #{options[:limit]} * FROM (SELECT TOP #{options[:limit] + options[:offset]} ")
134
- sql << ") AS tmp1"
135
- if options[:order]
136
- options[:order] = options[:order].split(',').map do |field|
137
- parts = field.split(" ")
138
- tc = parts[0]
139
- if sql =~ /\.\[/ and tc =~ /\./ # if column quoting used in query
140
- tc.gsub!(/\./, '\\.\\[')
141
- tc << '\\]'
142
- end
143
- if sql =~ /#{tc} AS (t\d_r\d\d?)/
144
- parts[0] = $1
128
+ sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i, "SELECT * FROM (SELECT TOP #{options[:limit]} * FROM (SELECT#{$1} TOP #{options[:limit] + options[:offset]} ")
129
+ sql << ") AS tmp1"
130
+ if options[:order]
131
+ options[:order] = options[:order].split(',').map do |field|
132
+ parts = field.split(" ")
133
+ tc = parts[0]
134
+ if sql =~ /\.\[/ and tc =~ /\./ # if column quoting used in query
135
+ tc.gsub!(/\./, '\\.\\[')
136
+ tc << '\\]'
137
+ end
138
+ if sql =~ /#{tc} AS (t\d_r\d\d?)/
139
+ parts[0] = $1
140
+ elsif parts[0] =~ /\w+\.(\w+)/
141
+ parts[0] = $1
142
+ end
143
+ parts.join(' ')
144
+ end.join(', ')
145
+ sql << " ORDER BY #{change_order_direction(options[:order])}) AS tmp2 ORDER BY #{options[:order]}"
146
+ else
147
+ sql << " ) AS tmp2"
145
148
  end
146
- parts.join(' ')
147
- end.join(', ')
148
- sql << " ORDER BY #{change_order_direction(options[:order])}) AS tmp2 ORDER BY #{options[:order]}"
149
- else
150
- sql << " ) AS tmp2"
149
+ elsif sql !~ /^\s*SELECT (@@|COUNT\()/i
150
+ sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i) do
151
+ "SELECT#{$1} TOP #{options[:limit]}"
152
+ end unless options[:limit].nil?
153
+ end
151
154
  end
152
- elsif sql !~ /^\s*SELECT (@@|COUNT\()/i
153
- sql.sub!(/^\s*SELECT([\s]*distinct)?/i) do
154
- "SELECT#{$1} TOP #{options[:limit]}"
155
- end unless options[:limit].nil?
156
- end
157
- end
158
155
 
156
+
157
+ def change_order_direction(order)
158
+ order.split(",").collect {|fragment|
159
+ case fragment
160
+ when /\bDESC\b/i then fragment.gsub(/\bDESC\b/i, "ASC")
161
+ when /\bASC\b/i then fragment.gsub(/\bASC\b/i, "DESC")
162
+ else String.new(fragment).split(',').join(' DESC,') + ' DESC'
163
+ end
164
+ }.join(",")
165
+ end
166
+
159
167
  def recreate_database(name)
160
168
  drop_database(name)
161
169
  create_database(name)
@@ -179,15 +187,17 @@ module JdbcSpec
179
187
 
180
188
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
181
189
  sql_commands = ["ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"]
182
- if options[:default]
190
+ if options_include_default?(options)
183
191
  remove_default_constraint(table_name, column_name)
184
- sql_commands << "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{options[:default]} FOR #{column_name}"
192
+ sql_commands << "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{quote(options[:default], options[:column])} FOR #{column_name}"
185
193
  end
186
194
  sql_commands.each {|c|
187
195
  execute(c)
188
196
  }
189
197
  end
190
-
198
+ def change_column_default(table_name, column_name, default) #:nodoc:
199
+ execute "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{quote(default, column_name)} FOR #{column_name}"
200
+ end
191
201
  def remove_column(table_name, column_name)
192
202
  remove_default_constraint(table_name, column_name)
193
203
  execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}"
@@ -203,6 +213,78 @@ module JdbcSpec
203
213
  def remove_index(table_name, options = {})
204
214
  execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
205
215
  end
216
+
217
+
218
+ def columns(table_name, name = nil)
219
+ cc = super
220
+ cc.each do |col|
221
+ col.identity = true if col.sql_type =~ /identity/i
222
+ col.is_special = true if col.sql_type =~ /text|ntext|image/i
223
+ end
224
+ cc
225
+ end
226
+
227
+ def _execute(sql, name = nil)
228
+ if sql.lstrip =~ /^insert/i
229
+ if query_requires_identity_insert?(sql)
230
+ table_name = get_table_name(sql)
231
+ with_identity_insert_enabled(table_name) do
232
+ id = @connection.execute_insert(sql)
233
+ end
234
+ else
235
+ @connection.execute_insert(sql)
236
+ end
237
+ elsif sql.lstrip =~ /^\(?\s*(select|show)/i
238
+ @connection.execute_query(sql)
239
+ else
240
+ @connection.execute_update(sql)
241
+ end
242
+ end
243
+
244
+
245
+ private
246
+ # Turns IDENTITY_INSERT ON for table during execution of the block
247
+ # N.B. This sets the state of IDENTITY_INSERT to OFF after the
248
+ # block has been executed without regard to its previous state
249
+
250
+ def with_identity_insert_enabled(table_name, &block)
251
+ set_identity_insert(table_name, true)
252
+ yield
253
+ ensure
254
+ set_identity_insert(table_name, false)
255
+ end
256
+
257
+ def set_identity_insert(table_name, enable = true)
258
+ execute "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}"
259
+ rescue Exception => e
260
+ raise ActiveRecordError, "IDENTITY_INSERT could not be turned #{enable ? 'ON' : 'OFF'} for table #{table_name}"
261
+ end
262
+
263
+ def get_table_name(sql)
264
+ if sql =~ /^\s*insert\s+into\s+([^\(\s]+)\s*|^\s*update\s+([^\(\s]+)\s*/i
265
+ $1
266
+ elsif sql =~ /from\s+([^\(\s]+)\s*/i
267
+ $1
268
+ else
269
+ nil
270
+ end
271
+ end
272
+
273
+ def identity_column(table_name)
274
+ @table_columns = {} unless @table_columns
275
+ @table_columns[table_name] = columns(table_name) if @table_columns[table_name] == nil
276
+ @table_columns[table_name].each do |col|
277
+ return col.name if col.identity
278
+ end
279
+
280
+ return nil
281
+ end
282
+
283
+ def query_requires_identity_insert?(sql)
284
+ table_name = get_table_name(sql)
285
+ id_column = identity_column(table_name)
286
+ sql =~ /\[#{id_column}\]/ ? table_name : nil
287
+ end
206
288
  end
207
289
  end
208
290
 
@@ -1,7 +1,27 @@
1
1
  require 'active_record/connection_adapters/abstract/schema_definitions'
2
2
 
3
- module JdbcSpec
3
+ module ::JdbcSpec
4
+ module ActiveRecordExtensions
5
+ def mysql_connection(config)
6
+ if config[:socket]
7
+ warn "AR-JDBC MySQL on JRuby does not support sockets"
8
+ end
9
+ config[:port] ||= 3306
10
+ config[:url] ||= "jdbc:mysql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
11
+ config[:driver] = "com.mysql.jdbc.Driver"
12
+ jdbc_connection(config)
13
+ end
14
+ end
15
+
4
16
  module MySQL
17
+ def self.column_selector
18
+ [/mysql/i, lambda {|cfg,col| col.extend(::JdbcSpec::MySQL::Column)}]
19
+ end
20
+
21
+ def self.adapter_selector
22
+ [/mysql/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::MySQL)}]
23
+ end
24
+
5
25
  def self.extended(adapter)
6
26
  adapter.execute("SET SQL_AUTO_IS_NULL=0")
7
27
  end
@@ -10,7 +30,7 @@ module JdbcSpec
10
30
  TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:binary, :string, :text])
11
31
 
12
32
  def simplified_type(field_type)
13
- return :boolean if field_type =~ /tinyint\(1\)|bit\(1\)/i
33
+ return :boolean if field_type =~ /tinyint\(1\)|bit/i
14
34
  return :string if field_type =~ /enum/i
15
35
  super
16
36
  end
@@ -1,5 +1,42 @@
1
- module JdbcSpec
1
+ module ::ActiveRecord
2
+ class Base
3
+ # After setting large objects to empty, write data back with a helper method
4
+ after_save :write_lobs
5
+ def write_lobs() #:nodoc:
6
+ if connection.is_a?(JdbcSpec::Oracle)
7
+ self.class.columns.select { |c| c.sql_type =~ /LOB\(|LOB$/i }.each { |c|
8
+ value = self[c.name]
9
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
10
+ next if value.nil? || (value == '')
11
+
12
+ connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
13
+ }
14
+ end
15
+ end
16
+
17
+ private :write_lobs
18
+ end
19
+ end
20
+
21
+ module ::JdbcSpec
22
+ module ActiveRecordExtensions
23
+ def oracle_connection(config)
24
+ config[:port] ||= 1521
25
+ config[:url] ||= "jdbc:oracle:thin:@#{config[:host]}:#{config[:port]}:#{config[:database]}"
26
+ config[:driver] ||= "oracle.jdbc.driver.OracleDriver"
27
+ jdbc_connection(config)
28
+ end
29
+ end
30
+
2
31
  module Oracle
32
+ def self.column_selector
33
+ [/oracle/i, lambda {|cfg,col| col.extend(::JdbcSpec::Oracle::Column)}]
34
+ end
35
+
36
+ def self.adapter_selector
37
+ [/oracle/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::Oracle)}]
38
+ end
39
+
3
40
  module Column
4
41
  def type_cast(value)
5
42
  return nil if value.nil? || value =~ /^\s*null\s*$/i
@@ -8,39 +45,46 @@ module JdbcSpec
8
45
  when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
9
46
  when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
10
47
  when :float then value.to_f
11
- when :datetime then cast_to_date_or_time(value)
12
- when :time then cast_to_time(value)
48
+ when :datetime then JdbcSpec::Oracle::Column.cast_to_date_or_time(value)
49
+ when :time then JdbcSpec::Oracle::Column.cast_to_time(value)
13
50
  when :decimal then self.class.value_to_decimal(value)
14
51
  when :boolean then self.class.value_to_boolean(value)
15
52
  else value
16
53
  end
17
54
  end
18
55
 
56
+ def type_cast_code(var_name)
57
+ return "JdbcSpec::Oracle::Column.cast_to_date_or_time(#{var_name})" if type == :datetime
58
+ super
59
+ end
60
+
19
61
  private
20
- def simplified_type(field_type)
62
+ def simplified_type(field_type)
21
63
  case field_type
22
- when /char/i : :string
23
- when /num|float|double|dec|real|int/i : @scale == 0 ? :integer : :float
24
- when /date|time/i : @name =~ /_at$/ ? :time : :datetime
64
+ when /char/i : :string
65
+ when /float|double/i : :float
66
+ when /int/i : :integer
67
+ when /num|dec|real/i : @scale == 0 ? :integer : :decimal
68
+ when /date|time/i : :datetime
25
69
  when /clob/i : :text
26
70
  when /blob/i : :binary
27
71
  end
28
72
  end
29
73
 
30
- def cast_to_date_or_time(value)
74
+ def self.cast_to_date_or_time(value)
31
75
  return value if value.is_a? Date
32
76
  return nil if value.blank?
33
- guess_date_or_time (value.is_a? Time) ? value : cast_to_time(value)
77
+ guess_date_or_time((value.is_a? Time) ? value : cast_to_time(value))
34
78
  end
35
79
 
36
- def cast_to_time(value)
80
+ def self.cast_to_time(value)
37
81
  return value if value.is_a? Time
38
82
  time_array = ParseDate.parsedate value
39
83
  time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
40
84
  Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue nil
41
85
  end
42
86
 
43
- def guess_date_or_time(value)
87
+ def self.guess_date_or_time(value)
44
88
  (value.hour == 0 and value.min == 0 and value.sec == 0) ?
45
89
  Date.new(value.year, value.month, value.day) : value
46
90
  end
@@ -65,6 +109,10 @@ module JdbcSpec
65
109
  execute "DROP SEQUENCE #{name}_seq" rescue nil
66
110
  end
67
111
 
112
+ def recreate_database(name)
113
+ tables.each{ |table| drop_table(table) }
114
+ end
115
+
68
116
  def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
69
117
  if pk.nil? # Who called us? What does the sql look like? No idea!
70
118
  execute sql, name
@@ -79,15 +127,17 @@ module JdbcSpec
79
127
  id_value
80
128
  end
81
129
 
130
+ def indexes(table, name = nil)
131
+ @connection.indexes(table, name, @connection.connection.meta_data.user_name)
132
+ end
133
+
82
134
  def _execute(sql, name = nil)
83
- log_no_bench(sql, name) do
84
135
  case sql.strip
85
136
  when /^(select|show)/i:
86
137
  @connection.execute_query(sql)
87
138
  else
88
139
  @connection.execute_update(sql)
89
140
  end
90
- end
91
141
  end
92
142
 
93
143
  def modify_types(tp)
@@ -147,7 +197,11 @@ module JdbcSpec
147
197
  from user_tab_columns
148
198
  where table_name = '#{table.to_a.first.last}'
149
199
  order by column_id
150
- }).map do |row|
200
+ }).map do |row|
201
+ row = row.inject({}) do |h,args|
202
+ h[args[0].downcase] = args[1]
203
+ h
204
+ end
151
205
  col = "#{row['column_name'].downcase} #{row['data_type'].downcase}"
152
206
  if row['data_type'] =='NUMBER' and !row['data_precision'].nil?
153
207
  col << "(#{row['data_precision'].to_i}"
@@ -202,7 +256,7 @@ module JdbcSpec
202
256
  return value.to_s
203
257
  end
204
258
  case value
205
- when String : %Q{'#{quote_string(value)}'}
259
+ when String, ActiveSupport::Multibyte::Chars : %Q{'#{quote_string(value)}'}
206
260
  when NilClass : 'null'
207
261
  when TrueClass : '1'
208
262
  when FalseClass : '0'
@@ -212,5 +266,16 @@ module JdbcSpec
212
266
  end
213
267
  end
214
268
  end
269
+
270
+ private
271
+
272
+ def select(sql, name = nil)
273
+ records = execute(sql, name)
274
+ records.map do |col|
275
+ col.delete('raw_rnum_')
276
+ col
277
+ end
278
+ records
279
+ end
215
280
  end
216
281
  end