activerecord-jdbc-adapter 1.0.2-java → 1.0.3-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.
- data/History.txt +9 -0
- data/Manifest.txt +6 -0
- data/lib/arel/visitors/db2.rb +15 -0
- data/lib/arel/visitors/derby.rb +19 -0
- data/lib/arel/visitors/hsqldb.rb +24 -0
- data/lib/arel/visitors/mssql.rb +44 -0
- data/lib/arjdbc/db2/adapter.rb +11 -3
- data/lib/arjdbc/derby/adapter.rb +5 -8
- data/lib/arjdbc/derby/connection_methods.rb +1 -1
- data/lib/arjdbc/h2/adapter.rb +8 -0
- data/lib/arjdbc/hsqldb/adapter.rb +5 -6
- data/lib/arjdbc/jdbc/adapter.rb +17 -3
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mssql/adapter.rb +11 -73
- data/lib/arjdbc/mssql/limit_helpers.rb +92 -0
- data/lib/arjdbc/mysql/adapter.rb +1 -1
- data/lib/arjdbc/oracle/adapter.rb +23 -2
- data/lib/arjdbc/postgresql/adapter.rb +4 -0
- data/lib/arjdbc/version.rb +1 -1
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +2 -0
- data/test/h2_simple_test.rb +35 -0
- data/test/jdbc_common.rb +1 -1
- data/test/mysql_db_create_test.rb +7 -10
- data/test/mysql_info_test.rb +8 -0
- data/test/mysql_simple_test.rb +13 -0
- data/test/oracle_simple_test.rb +8 -0
- data/test/simple.rb +30 -0
- metadata +9 -3
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 1.0.3 (11/29/10)
|
2
|
+
|
3
|
+
- ACTIVERECORD_JDBC-143: Implement table_exists? fixing association
|
4
|
+
table names with schema prefixes
|
5
|
+
- Cleanup of column code for hsqldb (Denis Odorcic)
|
6
|
+
- Rails 3.0.3 support - add Arel 2 visitors for all adapters
|
7
|
+
- Fix MySQL date types to not have limits (Chris Lowder)
|
8
|
+
- ACTIVERECORD_JDBC-141: Better schema support in H2
|
9
|
+
|
1
10
|
== 1.0.2
|
2
11
|
|
3
12
|
- ACTIVERECORD_JDBC-134: Fix conflicting adapter/column superclasses
|
data/Manifest.txt
CHANGED
@@ -25,6 +25,10 @@ lib/arel/engines/sql/compilers/h2_compiler.rb
|
|
25
25
|
lib/arel/engines/sql/compilers/hsqldb_compiler.rb
|
26
26
|
lib/arel/engines/sql/compilers/jdbc_compiler.rb
|
27
27
|
lib/arel/engines/sql/compilers/mssql_compiler.rb
|
28
|
+
lib/arel/visitors/db2.rb
|
29
|
+
lib/arel/visitors/derby.rb
|
30
|
+
lib/arel/visitors/hsqldb.rb
|
31
|
+
lib/arel/visitors/mssql.rb
|
28
32
|
lib/arjdbc/db2.rb
|
29
33
|
lib/arjdbc/derby.rb
|
30
34
|
lib/arjdbc/discover.rb
|
@@ -71,6 +75,7 @@ lib/arjdbc/jdbc/type_converter.rb
|
|
71
75
|
lib/arjdbc/mimer/adapter.rb
|
72
76
|
lib/arjdbc/mssql/adapter.rb
|
73
77
|
lib/arjdbc/mssql/connection_methods.rb
|
78
|
+
lib/arjdbc/mssql/limit_helpers.rb
|
74
79
|
lib/arjdbc/mssql/tsql_helper.rb
|
75
80
|
lib/arjdbc/mysql/adapter.rb
|
76
81
|
lib/arjdbc/mysql/connection_methods.rb
|
@@ -150,6 +155,7 @@ test/models/string_id.rb
|
|
150
155
|
test/models/validates_uniqueness_of_string.rb
|
151
156
|
lib/arjdbc/jdbc/jdbc.rake
|
152
157
|
src/java/arjdbc/derby/DerbyModule.java
|
158
|
+
src/java/arjdbc/h2/H2RubyJdbcConnection.java
|
153
159
|
src/java/arjdbc/informix/InformixRubyJdbcConnection.java
|
154
160
|
src/java/arjdbc/jdbc/AdapterJavaService.java
|
155
161
|
src/java/arjdbc/jdbc/JdbcConnectionFactory.java
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class DB2 < Arel::Visitors::ToSql
|
4
|
+
def visit_Arel_Nodes_SelectStatement o
|
5
|
+
add_limit_offset([o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
6
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
7
|
+
].compact.join(' '), o)
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_limit_offset(sql, o)
|
11
|
+
@connection.replace_limit_offset! sql, o.limit, o.offset
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class Derby < Arel::Visitors::ToSql
|
4
|
+
def visit_Arel_Nodes_SelectStatement o
|
5
|
+
[
|
6
|
+
o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
7
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
8
|
+
("FETCH FIRST #{o.limit} ROWS ONLY" if o.limit),
|
9
|
+
(visit(o.offset) if o.offset),
|
10
|
+
(visit(o.lock) if o.lock),
|
11
|
+
].compact.join ' '
|
12
|
+
end
|
13
|
+
|
14
|
+
def visit_Arel_Nodes_Offset o
|
15
|
+
"OFFSET #{visit o.value} ROWS"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class HSQLDB < Arel::Visitors::ToSql
|
4
|
+
def visit_Arel_Nodes_SelectStatement o
|
5
|
+
[
|
6
|
+
limit_offset(o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join, o),
|
7
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
8
|
+
].compact.join ' '
|
9
|
+
end
|
10
|
+
|
11
|
+
def limit_offset sql, o
|
12
|
+
offset = o.offset || 0
|
13
|
+
bef = sql[7..-1]
|
14
|
+
if limit = o.limit
|
15
|
+
"SELECT LIMIT #{offset} #{limit} #{bef}"
|
16
|
+
elsif offset > 0
|
17
|
+
"SELECT LIMIT #{offset} 0 #{bef}"
|
18
|
+
else
|
19
|
+
sql
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class SQLServer < Arel::Visitors::ToSql
|
4
|
+
include ArJdbc::MsSQL::LimitHelpers::SqlServerReplaceLimitOffset
|
5
|
+
|
6
|
+
def select_count? o
|
7
|
+
sel = o.cores.length == 1 && o.cores.first
|
8
|
+
projections = sel.projections.length == 1 && sel.projections
|
9
|
+
Arel::Nodes::Count === projections.first
|
10
|
+
end
|
11
|
+
|
12
|
+
# Need to mimic the subquery logic in ARel 1.x for select count with limit
|
13
|
+
# See arel/engines/sql/compilers/mssql_compiler.rb for details
|
14
|
+
def visit_Arel_Nodes_SelectStatement o
|
15
|
+
order = "ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?
|
16
|
+
if o.limit
|
17
|
+
if select_count?(o)
|
18
|
+
subquery = true
|
19
|
+
sql = o.cores.map do |x|
|
20
|
+
x = x.dup
|
21
|
+
x.projections = [Arel::Nodes::SqlLiteral.new("*")]
|
22
|
+
visit_Arel_Nodes_SelectCore x
|
23
|
+
end.join
|
24
|
+
else
|
25
|
+
sql = o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join
|
26
|
+
end
|
27
|
+
|
28
|
+
order ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
|
29
|
+
replace_limit_offset!(sql, o.limit.to_i, o.offset && o.offset.value.to_i, order)
|
30
|
+
sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if subquery
|
31
|
+
elsif order
|
32
|
+
sql << " #{order}"
|
33
|
+
else
|
34
|
+
sql = super
|
35
|
+
end
|
36
|
+
sql
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class SQLServer2000 < SQLServer
|
41
|
+
include ArJdbc::MsSQL::LimitHelpers::SqlServer2000ReplaceLimitOffset
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/arjdbc/db2/adapter.rb
CHANGED
@@ -143,8 +143,16 @@ module ArJdbc
|
|
143
143
|
'DB2'
|
144
144
|
end
|
145
145
|
|
146
|
+
def arel2_visitors
|
147
|
+
require 'arel/visitors/db2'
|
148
|
+
{'db2' => ::Arel::Visitors::DB2, 'as400' => ::Arel::Visitors::DB2}
|
149
|
+
end
|
150
|
+
|
146
151
|
def add_limit_offset!(sql, options)
|
147
|
-
|
152
|
+
replace_limit_offset!(sql, options[:limit], options[:offset])
|
153
|
+
end
|
154
|
+
|
155
|
+
def replace_limit_offset!(sql, limit, offset)
|
148
156
|
if limit && !offset
|
149
157
|
if limit == 1
|
150
158
|
sql << " FETCH FIRST ROW ONLY"
|
@@ -153,9 +161,9 @@ module ArJdbc
|
|
153
161
|
end
|
154
162
|
elsif limit && offset
|
155
163
|
sql.gsub!(/SELECT/i, 'SELECT B.* FROM (SELECT A.*, row_number() over () AS internal$rownum FROM (SELECT')
|
156
|
-
sql << ") A ) B WHERE B.internal$rownum > #{offset} AND B.internal$
|
157
|
-
um <= #{sanitize_limit(limit) + offset}"
|
164
|
+
sql << ") A ) B WHERE B.internal$rownum > #{offset} AND B.internal$rownum <= #{sanitize_limit(limit) + offset}"
|
158
165
|
end
|
166
|
+
sql
|
159
167
|
end
|
160
168
|
|
161
169
|
def pk_and_sequence_for(table)
|
data/lib/arjdbc/derby/adapter.rb
CHANGED
@@ -55,6 +55,11 @@ module ::ArJdbc
|
|
55
55
|
'Derby'
|
56
56
|
end
|
57
57
|
|
58
|
+
def arel2_visitors
|
59
|
+
require 'arel/visitors/derby'
|
60
|
+
{'derby' => ::Arel::Visitors::Derby, 'jdbcderby' => ::Arel::Visitors::Derby}
|
61
|
+
end
|
62
|
+
|
58
63
|
include ArJdbc::MissingFunctionalityHelper
|
59
64
|
|
60
65
|
def index_name_length
|
@@ -87,7 +92,6 @@ module ::ArJdbc
|
|
87
92
|
# Override default -- fix case where ActiveRecord passes :default => nil, :null => true
|
88
93
|
def add_column_options!(sql, options)
|
89
94
|
options.delete(:default) if options.has_key?(:default) && options[:default].nil?
|
90
|
-
options.delete(:null) if options.has_key?(:null) && (options[:null].nil? || options[:null] == true)
|
91
95
|
sql << " DEFAULT #{quote(options.delete(:default))}" if options.has_key?(:default)
|
92
96
|
super
|
93
97
|
end
|
@@ -158,16 +162,9 @@ module ::ArJdbc
|
|
158
162
|
|
159
163
|
|
160
164
|
def add_column(table_name, column_name, type, options = {})
|
161
|
-
if option_not_null = (options[:null] == false)
|
162
|
-
options.delete(:null)
|
163
|
-
end
|
164
165
|
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
165
166
|
add_column_options!(add_column_sql, options)
|
166
167
|
execute(add_column_sql)
|
167
|
-
if option_not_null
|
168
|
-
alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
|
169
|
-
execute(alter_column_sql)
|
170
|
-
end
|
171
168
|
end
|
172
169
|
|
173
170
|
def execute(sql, name = nil)
|
@@ -6,7 +6,7 @@ module ActiveRecord
|
|
6
6
|
config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
|
7
7
|
conn = embedded_driver(config)
|
8
8
|
md = conn.jdbc_connection.meta_data
|
9
|
-
if md.database_major_version < 10 || md.database_minor_version < 5
|
9
|
+
if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
|
10
10
|
raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
|
11
11
|
end
|
12
12
|
conn
|
data/lib/arjdbc/h2/adapter.rb
CHANGED
@@ -4,10 +4,18 @@ module ArJdbc
|
|
4
4
|
module H2
|
5
5
|
include HSQLDB
|
6
6
|
|
7
|
+
def self.jdbc_connection_class
|
8
|
+
::ActiveRecord::ConnectionAdapters::H2JdbcConnection
|
9
|
+
end
|
10
|
+
|
7
11
|
def adapter_name #:nodoc:
|
8
12
|
'H2'
|
9
13
|
end
|
10
14
|
|
15
|
+
def arel2_visitors
|
16
|
+
super.merge 'h2' => ::Arel::Visitors::HSQLDB, 'jdbch2' => ::Arel::Visitors::HSQLDB
|
17
|
+
end
|
18
|
+
|
11
19
|
def h2_adapter
|
12
20
|
true
|
13
21
|
end
|
@@ -40,6 +40,11 @@ module ::ArJdbc
|
|
40
40
|
'Hsqldb'
|
41
41
|
end
|
42
42
|
|
43
|
+
def arel2_visitors
|
44
|
+
require 'arel/visitors/hsqldb'
|
45
|
+
{'hsqldb' => ::Arel::Visitors::HSQLDB, 'jdbchsqldb' => ::Arel::Visitors::HSQLDB}
|
46
|
+
end
|
47
|
+
|
43
48
|
def modify_types(tp)
|
44
49
|
tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
|
45
50
|
tp[:integer][:limit] = nil
|
@@ -99,15 +104,9 @@ module ::ArJdbc
|
|
99
104
|
end
|
100
105
|
|
101
106
|
def add_column(table_name, column_name, type, options = {})
|
102
|
-
if option_not_null = options[:null] == false
|
103
|
-
option_not_null = options.delete(:null)
|
104
|
-
end
|
105
107
|
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
106
108
|
add_column_options!(add_column_sql, options)
|
107
109
|
execute(add_column_sql)
|
108
|
-
if option_not_null
|
109
|
-
alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
|
110
|
-
end
|
111
110
|
end
|
112
111
|
|
113
112
|
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
@@ -32,7 +32,7 @@ module ActiveRecord
|
|
32
32
|
end
|
33
33
|
super(connection, logger)
|
34
34
|
extend spec if spec
|
35
|
-
configure_arel2_visitors
|
35
|
+
configure_arel2_visitors(config)
|
36
36
|
connection.adapter = self
|
37
37
|
JndiConnectionPoolCallbacks.prepare(self, connection)
|
38
38
|
end
|
@@ -93,12 +93,17 @@ module ActiveRecord
|
|
93
93
|
{}
|
94
94
|
end
|
95
95
|
|
96
|
-
def configure_arel2_visitors
|
96
|
+
def configure_arel2_visitors(config)
|
97
97
|
if defined?(::Arel::Visitors::VISITORS)
|
98
98
|
visitors = ::Arel::Visitors::VISITORS
|
99
|
+
visitor = nil
|
99
100
|
arel2_visitors.each do |k,v|
|
101
|
+
visitor = v
|
100
102
|
visitors[k] = v unless visitors.has_key?(k)
|
101
103
|
end
|
104
|
+
if visitor && config[:dialect] && config[:adapter] =~ /^(jdbc|jndi)$/
|
105
|
+
visitors[config[:adapter]] = visitor
|
106
|
+
end
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
@@ -220,7 +225,6 @@ module ActiveRecord
|
|
220
225
|
id_value || id
|
221
226
|
end
|
222
227
|
|
223
|
-
|
224
228
|
def jdbc_columns(table_name, name = nil)
|
225
229
|
@connection.columns(table_name.to_s)
|
226
230
|
end
|
@@ -230,6 +234,10 @@ module ActiveRecord
|
|
230
234
|
@connection.tables
|
231
235
|
end
|
232
236
|
|
237
|
+
def table_exists?(name)
|
238
|
+
jdbc_columns(name) rescue nil
|
239
|
+
end
|
240
|
+
|
233
241
|
def indexes(table_name, name = nil, schema_name = nil)
|
234
242
|
@connection.indexes(table_name, name, schema_name)
|
235
243
|
end
|
@@ -266,6 +274,12 @@ module ActiveRecord
|
|
266
274
|
def select(*args)
|
267
275
|
execute(*args)
|
268
276
|
end
|
277
|
+
|
278
|
+
def translate_exception(e, message)
|
279
|
+
puts e.backtrace if $DEBUG || ENV['DEBUG']
|
280
|
+
super
|
281
|
+
end
|
282
|
+
protected :translate_exception
|
269
283
|
end
|
270
284
|
end
|
271
285
|
end
|
Binary file
|
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'arjdbc/mssql/tsql_helper'
|
2
|
+
require 'arjdbc/mssql/limit_helpers'
|
2
3
|
|
3
4
|
module ::ArJdbc
|
4
5
|
module MsSQL
|
5
6
|
include TSqlMethods
|
7
|
+
include LimitHelpers
|
6
8
|
|
7
9
|
def self.extended(mod)
|
8
10
|
unless @lob_callback_added
|
@@ -32,15 +34,21 @@ module ::ArJdbc
|
|
32
34
|
::ActiveRecord::ConnectionAdapters::MssqlJdbcConnection
|
33
35
|
end
|
34
36
|
|
37
|
+
def arel2_visitors
|
38
|
+
require 'arel/visitors/mssql'
|
39
|
+
visitor_class = sqlserver_version == "2000" ? ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
|
40
|
+
{ 'mssql' => visitor_class, 'jdbcmssql' => visitor_class}
|
41
|
+
end
|
42
|
+
|
35
43
|
def sqlserver_version
|
36
44
|
@sqlserver_version ||= select_value("select @@version")[/Microsoft SQL Server\s+(\d{4})/, 1]
|
37
45
|
end
|
38
46
|
|
39
47
|
def add_version_specific_add_limit_offset
|
40
48
|
if sqlserver_version == "2000"
|
41
|
-
extend
|
49
|
+
extend LimitHelpers::SqlServer2000AddLimitOffset
|
42
50
|
else
|
43
|
-
extend
|
51
|
+
extend LimitHelpers::SqlServerAddLimitOffset
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
@@ -228,64 +236,6 @@ module ::ArJdbc
|
|
228
236
|
'MsSQL'
|
229
237
|
end
|
230
238
|
|
231
|
-
module SqlServer2000LimitOffset
|
232
|
-
def add_limit_offset!(sql, options)
|
233
|
-
limit = options[:limit]
|
234
|
-
if limit
|
235
|
-
offset = (options[:offset] || 0).to_i
|
236
|
-
start_row = offset + 1
|
237
|
-
end_row = offset + limit.to_i
|
238
|
-
order = (options[:order] || determine_order_clause(sql))
|
239
|
-
sql.sub!(/ ORDER BY.*$/i, '')
|
240
|
-
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
241
|
-
whole, select, rest_of_query = find_select.match(sql).to_a
|
242
|
-
if (start_row == 1) && (end_row ==1)
|
243
|
-
new_sql = "#{select} TOP 1 #{rest_of_query}"
|
244
|
-
sql.replace(new_sql)
|
245
|
-
else
|
246
|
-
#UGLY
|
247
|
-
#KLUDGY?
|
248
|
-
#removing out stuff before the FROM...
|
249
|
-
rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
|
250
|
-
#need the table name for avoiding amiguity
|
251
|
-
table_name = get_table_name(sql)
|
252
|
-
#I am not sure this will cover all bases. but all the tests pass
|
253
|
-
new_order = "#{order}, #{table_name}.id" if order.index("#{table_name}.id").nil?
|
254
|
-
new_order ||= order
|
255
|
-
|
256
|
-
if (rest_of_query.match(/WHERE/).nil?)
|
257
|
-
new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} ORDER BY #{new_order}) ORDER BY #{order} "
|
258
|
-
else
|
259
|
-
new_sql = "#{select} TOP #{limit} #{rest_of_query} AND #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} ORDER BY #{new_order}) ORDER BY #{order} "
|
260
|
-
end
|
261
|
-
|
262
|
-
sql.replace(new_sql)
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
module SqlServerLimitOffset
|
269
|
-
def add_limit_offset!(sql, options)
|
270
|
-
limit = options[:limit]
|
271
|
-
if limit
|
272
|
-
offset = (options[:offset] || 0).to_i
|
273
|
-
start_row = offset + 1
|
274
|
-
end_row = offset + limit.to_i
|
275
|
-
order = (options[:order] || determine_order_clause(sql))
|
276
|
-
sql.sub!(/ ORDER BY.*$/i, '')
|
277
|
-
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
278
|
-
whole, select, rest_of_query = find_select.match(sql).to_a
|
279
|
-
if rest_of_query.strip!.first == '*'
|
280
|
-
from_table = /.*FROM\s*\b(\w*)\b/i.match(rest_of_query).to_a[1]
|
281
|
-
end
|
282
|
-
new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(ORDER BY #{order}) AS _row_num, #{from_table + '.' if from_table}#{rest_of_query}"
|
283
|
-
new_sql << ") AS t WHERE t._row_num BETWEEN #{start_row.to_s} AND #{end_row.to_s}"
|
284
|
-
sql.replace(new_sql)
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
239
|
def change_order_direction(order)
|
290
240
|
order.split(",").collect do |fragment|
|
291
241
|
case fragment
|
@@ -442,8 +392,6 @@ module ::ArJdbc
|
|
442
392
|
sql
|
443
393
|
end
|
444
394
|
|
445
|
-
private
|
446
|
-
|
447
395
|
# Turns IDENTITY_INSERT ON for table during execution of the block
|
448
396
|
# N.B. This sets the state of IDENTITY_INSERT to OFF after the
|
449
397
|
# block has been executed without regard to its previous state
|
@@ -460,16 +408,6 @@ module ::ArJdbc
|
|
460
408
|
raise ActiveRecord::ActiveRecordError, "IDENTITY_INSERT could not be turned #{enable ? 'ON' : 'OFF'} for table #{table_name}"
|
461
409
|
end
|
462
410
|
|
463
|
-
def get_table_name(sql)
|
464
|
-
if sql =~ /^\s*insert\s+into\s+([^\(\s,]+)\s*|^\s*update\s+([^\(\s,]+)\s*/i
|
465
|
-
$1
|
466
|
-
elsif sql =~ /from\s+([^\(\s,]+)\s*/i
|
467
|
-
$1
|
468
|
-
else
|
469
|
-
nil
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
411
|
def identity_column(table_name)
|
474
412
|
columns(table_name).each do |col|
|
475
413
|
return col.name if col.identity
|
@@ -527,7 +465,7 @@ module ::ArJdbc
|
|
527
465
|
end
|
528
466
|
|
529
467
|
def clear_cached_table(name)
|
530
|
-
(@table_columns ||= {}).delete(name)
|
468
|
+
(@table_columns ||= {}).delete(name.to_s)
|
531
469
|
end
|
532
470
|
end
|
533
471
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module ::ArJdbc
|
2
|
+
module MsSQL
|
3
|
+
module LimitHelpers
|
4
|
+
module_function
|
5
|
+
def get_table_name(sql)
|
6
|
+
if sql =~ /^\s*insert\s+into\s+([^\(\s,]+)\s*|^\s*update\s+([^\(\s,]+)\s*/i
|
7
|
+
$1
|
8
|
+
elsif sql =~ /from\s+([^\(\s,]+)\s*/i
|
9
|
+
$1
|
10
|
+
else
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module SqlServer2000ReplaceLimitOffset
|
16
|
+
module_function
|
17
|
+
def replace_limit_offset!(sql, limit, offset, order)
|
18
|
+
if limit
|
19
|
+
offset ||= 0
|
20
|
+
start_row = offset + 1
|
21
|
+
end_row = offset + limit.to_i
|
22
|
+
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
23
|
+
whole, select, rest_of_query = find_select.match(sql).to_a
|
24
|
+
if (start_row == 1) && (end_row ==1)
|
25
|
+
new_sql = "#{select} TOP 1 #{rest_of_query}"
|
26
|
+
sql.replace(new_sql)
|
27
|
+
else
|
28
|
+
#UGLY
|
29
|
+
#KLUDGY?
|
30
|
+
#removing out stuff before the FROM...
|
31
|
+
rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
|
32
|
+
#need the table name for avoiding amiguity
|
33
|
+
table_name = LimitHelpers.get_table_name(sql)
|
34
|
+
#I am not sure this will cover all bases. but all the tests pass
|
35
|
+
new_order = "ORDER BY #{order}, #{table_name}.id" if order.index("#{table_name}.id").nil?
|
36
|
+
new_order ||= order
|
37
|
+
|
38
|
+
if (rest_of_query.match(/WHERE/).nil?)
|
39
|
+
new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} #{new_order}) #{order} "
|
40
|
+
else
|
41
|
+
new_sql = "#{select} TOP #{limit} #{rest_of_query} AND #{table_name}.id NOT IN (#{select} TOP #{offset} #{table_name}.id #{rest} #{new_order}) #{order} "
|
42
|
+
end
|
43
|
+
|
44
|
+
sql.replace(new_sql)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
sql
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module SqlServer2000AddLimitOffset
|
52
|
+
def add_limit_offset!(sql, options)
|
53
|
+
if options[:limit]
|
54
|
+
order = "ORDER BY #{options[:order] || determine_order_clause(sql)}"
|
55
|
+
sql.sub!(/ ORDER BY.*$/i, '')
|
56
|
+
SqlServerReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module SqlServerReplaceLimitOffset
|
62
|
+
module_function
|
63
|
+
def replace_limit_offset!(sql, limit, offset, order)
|
64
|
+
if limit
|
65
|
+
offset ||= 0
|
66
|
+
start_row = offset + 1
|
67
|
+
end_row = offset + limit.to_i
|
68
|
+
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
69
|
+
whole, select, rest_of_query = find_select.match(sql).to_a
|
70
|
+
if rest_of_query.strip!.first == '*'
|
71
|
+
from_table = /.*FROM\s*\b(\w*)\b/i.match(rest_of_query).to_a[1]
|
72
|
+
end
|
73
|
+
new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(#{order}) AS _row_num, #{from_table + '.' if from_table}#{rest_of_query}"
|
74
|
+
new_sql << ") AS t WHERE t._row_num BETWEEN #{start_row.to_s} AND #{end_row.to_s}"
|
75
|
+
sql.replace(new_sql)
|
76
|
+
end
|
77
|
+
sql
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module SqlServerAddLimitOffset
|
82
|
+
def add_limit_offset!(sql, options)
|
83
|
+
if options[:limit]
|
84
|
+
order = "ORDER BY #{options[:order] || determine_order_clause(sql)}"
|
85
|
+
sql.sub!(/ ORDER BY.*$/i, '')
|
86
|
+
SqlServerReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -109,6 +109,15 @@ module ::ArJdbc
|
|
109
109
|
'Oracle'
|
110
110
|
end
|
111
111
|
|
112
|
+
def arel2_visitors
|
113
|
+
{ 'oracle' => Arel::Visitors::Oracle }
|
114
|
+
end
|
115
|
+
|
116
|
+
# TODO: use this instead of the QuotedPrimaryKey logic and execute_id_insert?
|
117
|
+
# def prefetch_primary_key?(table_name = nil)
|
118
|
+
# columns(table_name).detect {|c| c.primary } if table_name
|
119
|
+
# end
|
120
|
+
|
112
121
|
def table_alias_length
|
113
122
|
30
|
114
123
|
end
|
@@ -144,8 +153,17 @@ module ::ArJdbc
|
|
144
153
|
recreate_database(name)
|
145
154
|
end
|
146
155
|
|
156
|
+
def next_sequence_value(sequence_name)
|
157
|
+
# avoid #select or #select_one so that the sequence values aren't cached
|
158
|
+
execute("select #{sequence_name}.nextval id from dual").first['id'].to_i
|
159
|
+
end
|
160
|
+
|
161
|
+
def sql_literal?(value)
|
162
|
+
defined?(::Arel::SqlLiteral) && ::Arel::SqlLiteral === value
|
163
|
+
end
|
164
|
+
|
147
165
|
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
148
|
-
if (id_value && !
|
166
|
+
if (id_value && !sql_literal?(id_value)) || pk.nil?
|
149
167
|
# Pre-assigned id or table without a primary key
|
150
168
|
# Presence of #to_sql means an Arel literal bind variable
|
151
169
|
# that should use #execute_id_insert below
|
@@ -155,7 +173,7 @@ module ::ArJdbc
|
|
155
173
|
# Extract the table from the insert sql. Yuck.
|
156
174
|
table = sql.split(" ", 4)[2].gsub('"', '')
|
157
175
|
sequence_name ||= default_sequence_name(table)
|
158
|
-
id_value =
|
176
|
+
id_value = next_sequence_value(sequence_name)
|
159
177
|
log(sql, name) do
|
160
178
|
@connection.execute_id_insert(sql,id_value)
|
161
179
|
end
|
@@ -344,6 +362,9 @@ module ::ArJdbc
|
|
344
362
|
end
|
345
363
|
|
346
364
|
def quote(value, column = nil) #:nodoc:
|
365
|
+
# Arel 2 passes SqlLiterals through
|
366
|
+
return value if sql_literal?(value)
|
367
|
+
|
347
368
|
if column && [:text, :binary].include?(column.type)
|
348
369
|
if /(.*?)\([0-9]+\)/ =~ column.sql_type
|
349
370
|
%Q{empty_#{ $1.downcase }()}
|
data/lib/arjdbc/version.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
/*
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
3
|
+
* Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
|
4
|
+
* Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
|
5
|
+
* Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
* a copy of this software and associated documentation files (the
|
9
|
+
* "Software"), to deal in the Software without restriction, including
|
10
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
* the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be
|
16
|
+
* included in all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
***** END LICENSE BLOCK *****/
|
26
|
+
|
27
|
+
package arjdbc.h2;
|
28
|
+
|
29
|
+
import java.sql.ResultSet;
|
30
|
+
import java.sql.SQLException;
|
31
|
+
import java.sql.Types;
|
32
|
+
|
33
|
+
import arjdbc.jdbc.RubyJdbcConnection;
|
34
|
+
|
35
|
+
import org.jruby.Ruby;
|
36
|
+
import org.jruby.RubyClass;
|
37
|
+
import org.jruby.runtime.ObjectAllocator;
|
38
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
39
|
+
|
40
|
+
/**
|
41
|
+
*
|
42
|
+
* @author nicksieger
|
43
|
+
*/
|
44
|
+
public class H2RubyJdbcConnection extends RubyJdbcConnection {
|
45
|
+
protected H2RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
46
|
+
super(runtime, metaClass);
|
47
|
+
}
|
48
|
+
|
49
|
+
public static RubyClass createH2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
|
50
|
+
RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("H2JdbcConnection",
|
51
|
+
jdbcConnection, H2_JDBCCONNECTION_ALLOCATOR);
|
52
|
+
clazz.defineAnnotatedMethods(H2RubyJdbcConnection.class);
|
53
|
+
|
54
|
+
return clazz;
|
55
|
+
}
|
56
|
+
|
57
|
+
private static ObjectAllocator H2_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
|
58
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
59
|
+
return new H2RubyJdbcConnection(runtime, klass);
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
/**
|
64
|
+
* H2 supports schemas.
|
65
|
+
*/
|
66
|
+
@Override
|
67
|
+
protected boolean databaseSupportsSchemas() {
|
68
|
+
return true;
|
69
|
+
}
|
70
|
+
}
|
@@ -29,6 +29,7 @@ package arjdbc.jdbc;
|
|
29
29
|
import java.io.IOException;
|
30
30
|
|
31
31
|
import arjdbc.derby.DerbyModule;
|
32
|
+
import arjdbc.h2.H2RubyJdbcConnection;
|
32
33
|
import arjdbc.informix.InformixRubyJdbcConnection;
|
33
34
|
import arjdbc.mssql.MssqlRubyJdbcConnection;
|
34
35
|
import arjdbc.mysql.MySQLModule;
|
@@ -53,6 +54,7 @@ public class AdapterJavaService implements BasicLibraryService {
|
|
53
54
|
InformixRubyJdbcConnection.createInformixJdbcConnectionClass(runtime, jdbcConnection);
|
54
55
|
OracleRubyJdbcConnection.createOracleJdbcConnectionClass(runtime, jdbcConnection);
|
55
56
|
Sqlite3RubyJdbcConnection.createSqlite3JdbcConnectionClass(runtime, jdbcConnection);
|
57
|
+
H2RubyJdbcConnection.createH2JdbcConnectionClass(runtime, jdbcConnection);
|
56
58
|
RubyModule arJdbc = runtime.getOrCreateModule("ArJdbc");
|
57
59
|
|
58
60
|
rubyApi = JavaEmbedUtils.newObjectAdapter();
|
data/test/h2_simple_test.rb
CHANGED
@@ -4,3 +4,38 @@ require 'db/h2'
|
|
4
4
|
class H2SimpleTest < Test::Unit::TestCase
|
5
5
|
include SimpleTestMethods
|
6
6
|
end
|
7
|
+
|
8
|
+
class H2SchemaTest < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@connection = ActiveRecord::Base.connection
|
11
|
+
@connection.execute("create schema s1");
|
12
|
+
@connection.execute("set schema s1");
|
13
|
+
CreateEntries.up
|
14
|
+
@connection.execute("create schema s2");
|
15
|
+
@connection.execute("set schema s2");
|
16
|
+
CreateUsers.up
|
17
|
+
@connection.execute("set schema public");
|
18
|
+
Entry.set_table_name 's1.entries'
|
19
|
+
User.set_table_name 's2.users'
|
20
|
+
user = User.create! :login => "something"
|
21
|
+
Entry.create! :title => "title", :content => "content", :rating => 123.45, :user => user
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
@connection.execute("set schema s1");
|
26
|
+
CreateEntries.down
|
27
|
+
@connection.execute("set schema s2");
|
28
|
+
CreateUsers.down
|
29
|
+
@connection.execute("drop schema s1");
|
30
|
+
@connection.execute("drop schema s2");
|
31
|
+
@connection.execute("set schema public");
|
32
|
+
Entry.reset_table_name
|
33
|
+
Entry.reset_column_information
|
34
|
+
User.reset_table_name
|
35
|
+
User.reset_column_information
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_find_in_other_schema
|
39
|
+
assert !Entry.all(:include => :user).empty?
|
40
|
+
end
|
41
|
+
end
|
data/test/jdbc_common.rb
CHANGED
@@ -8,9 +8,9 @@ class MysqlDbCreateTest < Test::Unit::TestCase
|
|
8
8
|
MYSQL_CONFIG
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def test_rake_db_create
|
12
|
+
Rake::Task["db:create"].invoke
|
13
|
+
if find_executable?("mysql")
|
14
14
|
output = nil
|
15
15
|
IO.popen("mysql -u #{MYSQL_CONFIG[:username]} --password=#{MYSQL_CONFIG[:password]}", "r+") do |mysql|
|
16
16
|
mysql << "show databases where `Database` = '#{@db_name}';"
|
@@ -18,13 +18,10 @@ class MysqlDbCreateTest < Test::Unit::TestCase
|
|
18
18
|
assert mysql.read =~ /#{@db_name}/m
|
19
19
|
end
|
20
20
|
end
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
else
|
27
|
-
def test_skipped
|
28
|
-
end
|
23
|
+
def test_rake_db_test_purge
|
24
|
+
Rake::Task["db:create"].invoke
|
25
|
+
Rake::Task["db:test:purge"].invoke
|
29
26
|
end
|
30
27
|
end
|
data/test/mysql_info_test.rb
CHANGED
@@ -12,6 +12,7 @@ class DBSetup < ActiveRecord::Migration
|
|
12
12
|
|
13
13
|
create_table :cars, :primary_key => 'legacy_id' do |t|
|
14
14
|
t.string :name
|
15
|
+
t.date :production_started_on
|
15
16
|
end
|
16
17
|
|
17
18
|
create_table :cats, :id => false do |t|
|
@@ -80,6 +81,13 @@ class MysqlInfoTest < Test::Unit::TestCase
|
|
80
81
|
dump = strio.string
|
81
82
|
dump.grep(/datetime/).each {|line| assert line !~ /limit/ }
|
82
83
|
end
|
84
|
+
|
85
|
+
def test_schema_dump_should_not_have_limits_on_date
|
86
|
+
strio = StringIO.new
|
87
|
+
ActiveRecord::SchemaDumper::dump(@connection, strio)
|
88
|
+
dump = strio.string
|
89
|
+
dump.grep(/date/).each {|line| assert line !~ /limit/ }
|
90
|
+
end
|
83
91
|
|
84
92
|
def test_should_include_limit
|
85
93
|
text_column = @connection.columns('memos').find { |c| c.name == 'text' }
|
data/test/mysql_simple_test.rb
CHANGED
@@ -29,6 +29,19 @@ class MysqlSimpleTest < Test::Unit::TestCase
|
|
29
29
|
def test_update_all_with_limit
|
30
30
|
assert_nothing_raised { Entry.update_all({:title => "test"}, {}, {:limit => 1}) }
|
31
31
|
end
|
32
|
+
|
33
|
+
def test_find_in_other_schema_with_include
|
34
|
+
old_entries_table_name = Entry.table_name
|
35
|
+
old_users_table_name = User.table_name
|
36
|
+
begin
|
37
|
+
User.set_table_name 'weblog_development.users'
|
38
|
+
Entry.set_table_name 'weblog_development.entries'
|
39
|
+
assert !Entry.all(:include => :user).empty?
|
40
|
+
ensure
|
41
|
+
Entry.set_table_name old_entries_table_name
|
42
|
+
User.set_table_name old_users_table_name
|
43
|
+
end
|
44
|
+
end
|
32
45
|
end
|
33
46
|
|
34
47
|
class MysqlHasManyThroughTest < Test::Unit::TestCase
|
data/test/oracle_simple_test.rb
CHANGED
@@ -7,4 +7,12 @@ class OracleSimpleTest < Test::Unit::TestCase
|
|
7
7
|
def test_default_id_type_is_integer
|
8
8
|
assert Integer === Entry.first.id
|
9
9
|
end
|
10
|
+
|
11
|
+
def test_sequences_are_not_cached
|
12
|
+
ActiveRecord::Base.transaction do
|
13
|
+
e1 = Entry.create :title => "hello1"
|
14
|
+
e2 = Entry.create :title => "hello2"
|
15
|
+
assert e1.id != e2.id
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
data/test/simple.rb
CHANGED
@@ -348,6 +348,36 @@ module SimpleTestMethods
|
|
348
348
|
AddNotNullColumnToTable.down
|
349
349
|
end
|
350
350
|
|
351
|
+
def test_add_null_column_with_default
|
352
|
+
Entry.connection.add_column :entries, :color, :string, :null => false, :default => "blue"
|
353
|
+
created_columns = Entry.connection.columns('entries')
|
354
|
+
|
355
|
+
color = created_columns.detect { |c| c.name == 'color' }
|
356
|
+
assert !color.null
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_add_null_column_with_no_default
|
360
|
+
# You must specify a default value with most databases
|
361
|
+
if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
|
362
|
+
Entry.connection.add_column :entries, :color, :string, :null => false
|
363
|
+
created_columns = Entry.connection.columns('entries')
|
364
|
+
|
365
|
+
color = created_columns.detect { |c| c.name == 'color' }
|
366
|
+
assert !color.null
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_add_null_column_with_nil_default
|
371
|
+
# You must specify a default value with most databases
|
372
|
+
if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
|
373
|
+
Entry.connection.add_column :entries, :color, :string, :null => false, :default => nil
|
374
|
+
created_columns = Entry.connection.columns('entries')
|
375
|
+
|
376
|
+
color = created_columns.detect { |c| c.name == 'color' }
|
377
|
+
assert !color.null
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
351
381
|
def test_validates_uniqueness_of_strings_case_sensitive
|
352
382
|
name_lower = ValidatesUniquenessOfString.new(:cs_string => "name", :ci_string => '1')
|
353
383
|
name_lower.save!
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 3
|
9
|
+
version: 1.0.3
|
10
10
|
platform: java
|
11
11
|
authors:
|
12
12
|
- Nick Sieger, Ola Bini and JRuby contributors
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-29 00:00:00 -06:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -89,6 +89,10 @@ files:
|
|
89
89
|
- lib/arel/engines/sql/compilers/hsqldb_compiler.rb
|
90
90
|
- lib/arel/engines/sql/compilers/jdbc_compiler.rb
|
91
91
|
- lib/arel/engines/sql/compilers/mssql_compiler.rb
|
92
|
+
- lib/arel/visitors/db2.rb
|
93
|
+
- lib/arel/visitors/derby.rb
|
94
|
+
- lib/arel/visitors/hsqldb.rb
|
95
|
+
- lib/arel/visitors/mssql.rb
|
92
96
|
- lib/arjdbc/db2.rb
|
93
97
|
- lib/arjdbc/derby.rb
|
94
98
|
- lib/arjdbc/discover.rb
|
@@ -135,6 +139,7 @@ files:
|
|
135
139
|
- lib/arjdbc/mimer/adapter.rb
|
136
140
|
- lib/arjdbc/mssql/adapter.rb
|
137
141
|
- lib/arjdbc/mssql/connection_methods.rb
|
142
|
+
- lib/arjdbc/mssql/limit_helpers.rb
|
138
143
|
- lib/arjdbc/mssql/tsql_helper.rb
|
139
144
|
- lib/arjdbc/mysql/adapter.rb
|
140
145
|
- lib/arjdbc/mysql/connection_methods.rb
|
@@ -214,6 +219,7 @@ files:
|
|
214
219
|
- test/models/validates_uniqueness_of_string.rb
|
215
220
|
- lib/arjdbc/jdbc/jdbc.rake
|
216
221
|
- src/java/arjdbc/derby/DerbyModule.java
|
222
|
+
- src/java/arjdbc/h2/H2RubyJdbcConnection.java
|
217
223
|
- src/java/arjdbc/informix/InformixRubyJdbcConnection.java
|
218
224
|
- src/java/arjdbc/jdbc/AdapterJavaService.java
|
219
225
|
- src/java/arjdbc/jdbc/JdbcConnectionFactory.java
|