kb-activerecord-jdbc-adapter 0.9.7.1-java → 1.0.0.beta1-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 +11 -0
- data/Manifest.txt +71 -38
- data/lib/active_record/connection_adapters/cachedb_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -661
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -13
- data/lib/activerecord-jdbc-adapter.rb +2 -2
- data/lib/arjdbc/cachedb/adapter.rb +20 -0
- data/lib/arjdbc/cachedb/connection_methods.rb +10 -0
- data/lib/arjdbc/cachedb.rb +3 -0
- data/lib/{jdbc_adapter/jdbc_db2.rb → arjdbc/db2/adapter.rb} +2 -17
- data/lib/arjdbc/db2.rb +2 -0
- data/lib/{jdbc_adapter/jdbc_derby.rb → arjdbc/derby/adapter.rb} +8 -26
- data/lib/arjdbc/derby/connection_methods.rb +18 -0
- data/lib/arjdbc/derby.rb +7 -0
- data/lib/arjdbc/discover.rb +99 -0
- data/lib/{jdbc_adapter/jdbc_firebird.rb → arjdbc/firebird/adapter.rb} +12 -16
- data/lib/arjdbc/firebird.rb +2 -0
- data/lib/arjdbc/h2/adapter.rb +15 -0
- data/lib/arjdbc/h2/connection_methods.rb +12 -0
- data/lib/arjdbc/h2.rb +4 -0
- data/lib/{jdbc_adapter/jdbc_hsqldb.rb → arjdbc/hsqldb/adapter.rb} +6 -58
- data/lib/arjdbc/hsqldb/connection_methods.rb +14 -0
- data/lib/arjdbc/hsqldb.rb +4 -0
- data/lib/{jdbc_adapter/jdbc_informix.rb → arjdbc/informix/adapter.rb} +6 -19
- data/lib/arjdbc/informix/connection_methods.rb +10 -0
- data/lib/arjdbc/informix.rb +3 -0
- data/lib/arjdbc/jdbc/adapter.rb +235 -0
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/callbacks.rb +44 -0
- data/lib/arjdbc/jdbc/column.rb +38 -0
- data/lib/arjdbc/jdbc/compatibility.rb +51 -0
- data/lib/arjdbc/jdbc/connection.rb +97 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
- data/lib/arjdbc/jdbc/core_ext.rb +24 -0
- data/lib/arjdbc/jdbc/discover.rb +18 -0
- data/lib/arjdbc/jdbc/driver.rb +44 -0
- data/lib/arjdbc/jdbc/extension.rb +47 -0
- data/lib/arjdbc/jdbc/java.rb +14 -0
- data/lib/{jdbc_adapter → arjdbc/jdbc}/missing_functionality_helper.rb +5 -5
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
- data/lib/{jdbc_adapter → arjdbc/jdbc}/railtie.rb +1 -1
- data/lib/arjdbc/jdbc/require_driver.rb +16 -0
- data/lib/arjdbc/jdbc/type_converter.rb +119 -0
- data/lib/arjdbc/jdbc.rb +2 -0
- data/lib/{jdbc_adapter/jdbc_mimer.rb → arjdbc/mimer/adapter.rb} +16 -19
- data/lib/arjdbc/mimer.rb +2 -0
- data/lib/{jdbc_adapter/jdbc_mssql.rb → arjdbc/mssql/adapter.rb} +19 -31
- data/lib/arjdbc/mssql/connection_methods.rb +13 -0
- data/lib/arjdbc/mssql.rb +4 -0
- data/lib/arjdbc/mysql/adapter.rb +388 -0
- data/lib/arjdbc/mysql/connection_methods.rb +26 -0
- data/lib/arjdbc/mysql.rb +4 -0
- data/lib/{jdbc_adapter/jdbc_oracle.rb → arjdbc/oracle/adapter.rb} +9 -17
- data/lib/arjdbc/oracle/connection_methods.rb +11 -0
- data/lib/arjdbc/oracle.rb +3 -0
- data/lib/{jdbc_adapter/jdbc_postgre.rb → arjdbc/postgresql/adapter.rb} +7 -36
- data/lib/arjdbc/postgresql/connection_methods.rb +21 -0
- data/lib/arjdbc/postgresql.rb +4 -0
- data/lib/{jdbc_adapter/jdbc_sqlite3.rb → arjdbc/sqlite3/adapter.rb} +106 -104
- data/lib/arjdbc/sqlite3/connection_methods.rb +33 -0
- data/lib/arjdbc/sqlite3.rb +4 -0
- data/lib/arjdbc/sybase/adapter.rb +46 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/arjdbc.rb +29 -0
- data/lib/jdbc_adapter/version.rb +3 -5
- data/lib/jdbc_adapter.rb +2 -27
- data/rails_generators/templates/config/initializers/jdbc.rb +1 -1
- data/rakelib/compile.rake +3 -2
- data/rakelib/package.rake +3 -3
- data/src/java/{jdbc_adapter/JdbcDerbySpec.java → arjdbc/derby/DerbyModule.java} +32 -32
- data/src/java/{jdbc_adapter/JdbcAdapterInternalService.java → arjdbc/jdbc/AdapterJavaService.java} +13 -7
- data/src/java/{jdbc_adapter → arjdbc/jdbc}/JdbcConnectionFactory.java +6 -6
- data/src/java/{jdbc_adapter → arjdbc/jdbc}/RubyJdbcConnection.java +91 -16
- data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
- data/src/java/{jdbc_adapter → arjdbc/mssql}/MssqlRubyJdbcConnection.java +5 -2
- data/src/java/{jdbc_adapter/JdbcMySQLSpec.java → arjdbc/mysql/MySQLModule.java} +12 -12
- data/src/java/{jdbc_adapter/PostgresRubyJdbcConnection.java → arjdbc/postgresql/PostgresqlRubyJdbcConnection.java} +11 -9
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +64 -0
- data/test/abstract_db_create.rb +4 -1
- data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -1
- data/test/db/cachedb.rb +0 -0
- data/test/db/derby.rb +12 -14
- data/test/db/hsqldb.rb +3 -2
- data/test/db/jndi_config.rb +4 -4
- data/test/db/sqlite3.rb +2 -6
- data/test/db2_simple_test.rb +23 -0
- data/test/derby_migration_test.rb +50 -3
- data/test/jdbc_common.rb +1 -1
- data/test/jndi_callbacks_test.rb +1 -0
- data/test/postgres_nonseq_pkey_test.rb +0 -2
- data/test/postgres_schema_search_path_test.rb +0 -2
- data/test/simple.rb +3 -3
- data/test/sybase_jtds_simple_test.rb +22 -0
- metadata +81 -46
- data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +0 -26
- data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
- data/lib/jdbc_adapter/jdbc_cachedb.rb +0 -33
- data/lib/jdbc_adapter/jdbc_mysql.rb +0 -260
- data/lib/jdbc_adapter/jdbc_sybase.rb +0 -50
- data/src/java/jdbc_adapter/SQLBlock.java +0 -27
- data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +0 -41
- data/test/jdbc_adapter/jdbc_db2_test.rb +0 -26
- data/test/jdbc_adapter/jdbc_sybase_test.rb +0 -33
- data/test/minirunit/testConnect.rb +0 -14
- data/test/minirunit/testH2.rb +0 -73
- data/test/minirunit/testHsqldb.rb +0 -73
- data/test/minirunit/testLoadActiveRecord.rb +0 -3
- data/test/minirunit/testMysql.rb +0 -83
- data/test/minirunit/testRawSelect.rb +0 -24
- data/test/minirunit.rb +0 -109
- /data/lib/{jdbc_adapter → arjdbc/jdbc}/jdbc.rake +0 -0
- /data/lib/{jdbc_adapter → arjdbc/jdbc}/rake_tasks.rb +0 -0
- /data/lib/{jdbc_adapter → arjdbc/mssql}/tsql_helper.rb +0 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module QuotedPrimaryKeyExtension
|
3
|
+
def self.extended(base)
|
4
|
+
# Rails 3 method Rails 2 method
|
5
|
+
meth = [:arel_attributes_values, :attributes_with_quotes].detect do |m|
|
6
|
+
base.private_instance_methods.include?(m.to_s)
|
7
|
+
end
|
8
|
+
pk_hash_key = "self.class.primary_key"
|
9
|
+
pk_hash_value = '"?"'
|
10
|
+
if meth == :arel_attributes_values
|
11
|
+
pk_hash_key = "self.class.arel_table[#{pk_hash_key}]"
|
12
|
+
pk_hash_value = "Arel::SqlLiteral.new(#{pk_hash_value})"
|
13
|
+
end
|
14
|
+
if meth
|
15
|
+
base.module_eval <<-PK, __FILE__, __LINE__
|
16
|
+
alias :#{meth}_pre_pk :#{meth}
|
17
|
+
def #{meth}(include_primary_key = true, *args) #:nodoc:
|
18
|
+
aq = #{meth}_pre_pk(include_primary_key, *args)
|
19
|
+
if connection.is_a?(ArJdbc::Oracle) || connection.is_a?(ArJdbc::Mimer)
|
20
|
+
aq[#{pk_hash_key}] = #{pk_hash_value} if include_primary_key && aq[#{pk_hash_key}].nil?
|
21
|
+
end
|
22
|
+
aq
|
23
|
+
end
|
24
|
+
PK
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Kernel
|
2
|
+
# load a JDBC driver library/gem, failing silently. If failed, trust
|
3
|
+
# that the driver jar is already present through some other means
|
4
|
+
def jdbc_require_driver(path, gem_name = nil)
|
5
|
+
gem_name ||= path.sub('/', '-')
|
6
|
+
2.times do
|
7
|
+
begin
|
8
|
+
require path
|
9
|
+
break
|
10
|
+
rescue LoadError
|
11
|
+
require 'rubygems'
|
12
|
+
begin; gem gem_name; rescue LoadError; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
# I want to use JDBC's DatabaseMetaData#getTypeInfo to choose the best native types to
|
4
|
+
# use for ActiveRecord's Adapter#native_database_types in a database-independent way,
|
5
|
+
# but apparently a database driver can return multiple types for a given
|
6
|
+
# java.sql.Types constant. So this type converter uses some heuristics to try to pick
|
7
|
+
# the best (most common) type to use. It's not great, it would be better to just
|
8
|
+
# delegate to each database's existin AR adapter's native_database_types method, but I
|
9
|
+
# wanted to try to do this in a way that didn't pull in all the other adapters as
|
10
|
+
# dependencies. Suggestions appreciated.
|
11
|
+
class JdbcTypeConverter
|
12
|
+
# The basic ActiveRecord types, mapped to an array of procs that are used to #select
|
13
|
+
# the best type. The procs are used as selectors in order until there is only one
|
14
|
+
# type left. If all the selectors are applied and there is still more than one
|
15
|
+
# type, an exception will be raised.
|
16
|
+
AR_TO_JDBC_TYPES = {
|
17
|
+
:string => [ lambda {|r| Jdbc::Types::VARCHAR == r['data_type'].to_i},
|
18
|
+
lambda {|r| r['type_name'] =~ /^varchar/i},
|
19
|
+
lambda {|r| r['type_name'] =~ /^varchar$/i},
|
20
|
+
lambda {|r| r['type_name'] =~ /varying/i}],
|
21
|
+
:text => [ lambda {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'].to_i)},
|
22
|
+
lambda {|r| r['type_name'] =~ /^text$/i}, # For Informix
|
23
|
+
lambda {|r| r['type_name'] =~ /^(text|clob)$/i},
|
24
|
+
lambda {|r| r['type_name'] =~ /^character large object$/i},
|
25
|
+
lambda {|r| r['sql_data_type'] == 2005}],
|
26
|
+
:integer => [ lambda {|r| Jdbc::Types::INTEGER == r['data_type'].to_i},
|
27
|
+
lambda {|r| r['type_name'] =~ /^integer$/i},
|
28
|
+
lambda {|r| r['type_name'] =~ /^int4$/i},
|
29
|
+
lambda {|r| r['type_name'] =~ /^int$/i}],
|
30
|
+
:decimal => [ lambda {|r| Jdbc::Types::DECIMAL == r['data_type'].to_i},
|
31
|
+
lambda {|r| r['type_name'] =~ /^decimal$/i},
|
32
|
+
lambda {|r| r['type_name'] =~ /^numeric$/i},
|
33
|
+
lambda {|r| r['type_name'] =~ /^number$/i},
|
34
|
+
lambda {|r| r['type_name'] =~ /^real$/i},
|
35
|
+
lambda {|r| r['precision'] == '38'},
|
36
|
+
lambda {|r| r['data_type'] == '2'}],
|
37
|
+
:float => [ lambda {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE, Jdbc::Types::REAL].include?(r['data_type'].to_i)},
|
38
|
+
lambda {|r| r['data_type'].to_i == Jdbc::Types::REAL}, #Prefer REAL to DOUBLE for Postgresql
|
39
|
+
lambda {|r| r['type_name'] =~ /^float/i},
|
40
|
+
lambda {|r| r['type_name'] =~ /^double$/i},
|
41
|
+
lambda {|r| r['type_name'] =~ /^real$/i},
|
42
|
+
lambda {|r| r['precision'] == '15'}],
|
43
|
+
:datetime => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
|
44
|
+
lambda {|r| r['type_name'] =~ /^datetime$/i},
|
45
|
+
lambda {|r| r['type_name'] =~ /^timestamp$/i},
|
46
|
+
lambda {|r| r['type_name'] =~ /^date/i},
|
47
|
+
lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
|
48
|
+
:timestamp => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
|
49
|
+
lambda {|r| r['type_name'] =~ /^timestamp$/i},
|
50
|
+
lambda {|r| r['type_name'] =~ /^datetime/i},
|
51
|
+
lambda {|r| r['type_name'] =~ /^date/i},
|
52
|
+
lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
|
53
|
+
:time => [ lambda {|r| Jdbc::Types::TIME == r['data_type'].to_i},
|
54
|
+
lambda {|r| r['type_name'] =~ /^time$/i},
|
55
|
+
lambda {|r| r['type_name'] =~ /^datetime/i}, # For Informix
|
56
|
+
lambda {|r| r['type_name'] =~ /^date/i},
|
57
|
+
lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
|
58
|
+
:date => [ lambda {|r| Jdbc::Types::DATE == r['data_type'].to_i},
|
59
|
+
lambda {|r| r['type_name'] =~ /^date$/i},
|
60
|
+
lambda {|r| r['type_name'] =~ /^date/i},
|
61
|
+
lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver3
|
62
|
+
:binary => [ lambda {|r| [Jdbc::Types::LONGVARBINARY,Jdbc::Types::BINARY,Jdbc::Types::BLOB].include?(r['data_type'].to_i)},
|
63
|
+
lambda {|r| r['type_name'] =~ /^blob/i},
|
64
|
+
lambda {|r| r['type_name'] =~ /sub_type 0$/i}, # For FireBird
|
65
|
+
lambda {|r| r['type_name'] =~ /^varbinary$/i}, # We want this sucker for Mimer
|
66
|
+
lambda {|r| r['type_name'] =~ /^binary$/i}, ],
|
67
|
+
:boolean => [ lambda {|r| [Jdbc::Types::TINYINT].include?(r['data_type'].to_i)},
|
68
|
+
lambda {|r| r['type_name'] =~ /^bool/i},
|
69
|
+
lambda {|r| r['data_type'] == '-7'},
|
70
|
+
lambda {|r| r['type_name'] =~ /^tinyint$/i},
|
71
|
+
lambda {|r| r['type_name'] =~ /^decimal$/i},
|
72
|
+
lambda {|r| r['type_name'] =~ /^integer$/i}]
|
73
|
+
}
|
74
|
+
|
75
|
+
def initialize(types)
|
76
|
+
@types = types
|
77
|
+
@types.each {|t| t['type_name'] ||= t['local_type_name']} # Sybase driver seems to want 'local_type_name'
|
78
|
+
end
|
79
|
+
|
80
|
+
def choose_best_types
|
81
|
+
type_map = {}
|
82
|
+
@types.each do |row|
|
83
|
+
name = row['type_name'].downcase
|
84
|
+
k = name.to_sym
|
85
|
+
type_map[k] = { :name => name }
|
86
|
+
type_map[k][:limit] = row['precision'].to_i if row['precision']
|
87
|
+
end
|
88
|
+
|
89
|
+
AR_TO_JDBC_TYPES.keys.each do |k|
|
90
|
+
typerow = choose_type(k)
|
91
|
+
type_map[k] = { :name => typerow['type_name'].downcase }
|
92
|
+
case k
|
93
|
+
when :integer, :string, :decimal
|
94
|
+
type_map[k][:limit] = typerow['precision'] && typerow['precision'].to_i
|
95
|
+
when :boolean
|
96
|
+
type_map[k][:limit] = 1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
type_map
|
100
|
+
end
|
101
|
+
|
102
|
+
def choose_type(ar_type)
|
103
|
+
procs = AR_TO_JDBC_TYPES[ar_type]
|
104
|
+
types = @types
|
105
|
+
procs.each do |p|
|
106
|
+
new_types = types.reject {|r| r["data_type"].to_i == Jdbc::Types::OTHER}
|
107
|
+
new_types = new_types.select(&p)
|
108
|
+
new_types = new_types.inject([]) do |typs,t|
|
109
|
+
typs << t unless typs.detect {|el| el['type_name'] == t['type_name']}
|
110
|
+
typs
|
111
|
+
end
|
112
|
+
return new_types.first if new_types.length == 1
|
113
|
+
types = new_types if new_types.length > 0
|
114
|
+
end
|
115
|
+
raise "unable to choose type for #{ar_type} from:\n#{types.collect{|t| t['type_name']}.inspect}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/arjdbc/jdbc.rb
ADDED
@@ -1,11 +1,8 @@
|
|
1
|
-
module
|
1
|
+
module ArJdbc
|
2
2
|
module Mimer
|
3
3
|
def self.extended(mod)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def self.adapter_matcher(name, *)
|
8
|
-
name =~ /mimer/i ? self : false
|
4
|
+
require 'arjdbc/jdbc/quoted_primary_key'
|
5
|
+
ActiveRecord::Base.extend ArJdbc::QuotedPrimaryKeyExtension
|
9
6
|
end
|
10
7
|
|
11
8
|
def modify_types(tp)
|
@@ -20,7 +17,7 @@ module JdbcSpec
|
|
20
17
|
tp[:date] = { :name => "TIMESTAMP" }
|
21
18
|
tp
|
22
19
|
end
|
23
|
-
|
20
|
+
|
24
21
|
def default_sequence_name(table, column) #:nodoc:
|
25
22
|
"#{table}_seq"
|
26
23
|
end
|
@@ -54,13 +51,13 @@ module JdbcSpec
|
|
54
51
|
log(sql, name) { @connection.execute_insert sql,pk }
|
55
52
|
else # Assume the sql contains a bind-variable for the id
|
56
53
|
id_value = select_one("SELECT NEXT_VALUE OF #{sequence_name} AS val FROM MIMER.ONEROW")['val']
|
57
|
-
log(sql, name) {
|
54
|
+
log(sql, name) {
|
58
55
|
execute_prepared_insert(sql,id_value)
|
59
56
|
}
|
60
57
|
end
|
61
58
|
id_value
|
62
59
|
end
|
63
|
-
|
60
|
+
|
64
61
|
def execute_prepared_insert(sql, id)
|
65
62
|
@stmts ||= {}
|
66
63
|
@stmts[sql] ||= @connection.ps(sql)
|
@@ -72,24 +69,24 @@ module JdbcSpec
|
|
72
69
|
|
73
70
|
def quote(value, column = nil) #:nodoc:
|
74
71
|
return value.quoted_id if value.respond_to?(:quoted_id)
|
75
|
-
|
72
|
+
|
76
73
|
if String === value && column && column.type == :binary
|
77
74
|
return "X'#{quote_string(value.unpack("C*").collect {|v| v.to_s(16)}.join)}'"
|
78
75
|
end
|
79
76
|
case value
|
80
|
-
when String
|
77
|
+
when String
|
81
78
|
%Q{'#{quote_string(value)}'}
|
82
|
-
when NilClass
|
79
|
+
when NilClass
|
83
80
|
'NULL'
|
84
|
-
when TrueClass
|
81
|
+
when TrueClass
|
85
82
|
'1'
|
86
|
-
when FalseClass
|
83
|
+
when FalseClass
|
87
84
|
'0'
|
88
|
-
when Numeric
|
85
|
+
when Numeric
|
89
86
|
value.to_s
|
90
|
-
when Date, Time
|
87
|
+
when Date, Time
|
91
88
|
%Q{TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
|
92
|
-
else
|
89
|
+
else
|
93
90
|
%Q{'#{quote_string(value.to_yaml)}'}
|
94
91
|
end
|
95
92
|
end
|
@@ -106,7 +103,7 @@ module JdbcSpec
|
|
106
103
|
@limit = options[:limit]
|
107
104
|
@offset = options[:offset]
|
108
105
|
end
|
109
|
-
|
106
|
+
|
110
107
|
def select_all(sql, name = nil)
|
111
108
|
@offset ||= 0
|
112
109
|
if !@limit || @limit == -1
|
@@ -118,7 +115,7 @@ module JdbcSpec
|
|
118
115
|
ensure
|
119
116
|
@limit = @offset = nil
|
120
117
|
end
|
121
|
-
|
118
|
+
|
122
119
|
def select_one(sql, name = nil)
|
123
120
|
@offset ||= 0
|
124
121
|
select(sql, name)[@offset]
|
data/lib/arjdbc/mimer.rb
ADDED
@@ -1,22 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
module ::JdbcSpec
|
4
|
-
|
5
|
-
module ActiveRecordExtensions
|
6
|
-
|
7
|
-
def mssql_connection(config)
|
8
|
-
require "active_record/connection_adapters/mssql_adapter"
|
9
|
-
config[:host] ||= "localhost"
|
10
|
-
config[:port] ||= 1433
|
11
|
-
config[:url] ||= "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
12
|
-
config[:driver] ||= "net.sourceforge.jtds.jdbc.Driver"
|
13
|
-
embedded_driver(config)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
1
|
+
require 'arjdbc/mssql/tsql_helper'
|
17
2
|
|
3
|
+
module ::ArJdbc
|
18
4
|
module MsSQL
|
19
|
-
|
20
5
|
include TSqlMethods
|
21
6
|
|
22
7
|
def self.extended(mod)
|
@@ -39,12 +24,8 @@ module ::JdbcSpec
|
|
39
24
|
mod.add_version_specific_add_limit_offset
|
40
25
|
end
|
41
26
|
|
42
|
-
def self.adapter_matcher(name, *)
|
43
|
-
name =~ /sqlserver|tds/i ? self : false
|
44
|
-
end
|
45
|
-
|
46
27
|
def self.column_selector
|
47
|
-
[/sqlserver|tds/i, lambda {|cfg,col| col.extend(::
|
28
|
+
[/sqlserver|tds/i, lambda {|cfg,col| col.extend(::ArJdbc::MsSQL::Column)}]
|
48
29
|
end
|
49
30
|
|
50
31
|
def self.jdbc_connection_class
|
@@ -102,7 +83,7 @@ module ::JdbcSpec
|
|
102
83
|
def type_cast(value)
|
103
84
|
return nil if value.nil? || value == "(null)" || value == "(NULL)"
|
104
85
|
case type
|
105
|
-
when :integer then unquote(value).to_i rescue value ? 1 : 0
|
86
|
+
when :integer then value.to_i rescue unquote(value).to_i rescue value ? 1 : 0
|
106
87
|
when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
|
107
88
|
when :decimal then self.class.value_to_decimal(unquote(value))
|
108
89
|
when :datetime then cast_to_datetime(value)
|
@@ -165,7 +146,7 @@ module ::JdbcSpec
|
|
165
146
|
when String, ActiveSupport::Multibyte::Chars
|
166
147
|
value = value.to_s
|
167
148
|
if column && column.type == :binary
|
168
|
-
"'#{quote_string(
|
149
|
+
"'#{quote_string(ArJdbc::MsSQL::Column.string_to_binary(value))}'" # ' (for ruby-mode)
|
169
150
|
elsif column && [:integer, :float].include?(column.type)
|
170
151
|
value = column.type == :integer ? value.to_i : value.to_f
|
171
152
|
value.to_s
|
@@ -209,7 +190,7 @@ module ::JdbcSpec
|
|
209
190
|
end_row = offset + limit.to_i
|
210
191
|
order = (options[:order] || determine_order_clause(sql))
|
211
192
|
sql.sub!(/ ORDER BY.*$/i, '')
|
212
|
-
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/
|
193
|
+
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
213
194
|
whole, select, rest_of_query = find_select.match(sql).to_a
|
214
195
|
if (start_row == 1) && (end_row ==1)
|
215
196
|
new_sql = "#{select} TOP 1 #{rest_of_query}"
|
@@ -240,7 +221,7 @@ module ::JdbcSpec
|
|
240
221
|
end_row = offset + limit.to_i
|
241
222
|
order = (options[:order] || determine_order_clause(sql))
|
242
223
|
sql.sub!(/ ORDER BY.*$/i, '')
|
243
|
-
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/
|
224
|
+
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
244
225
|
whole, select, rest_of_query = find_select.match(sql).to_a
|
245
226
|
new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(ORDER BY #{order}) AS row_num, #{rest_of_query}"
|
246
227
|
new_sql << ") AS t WHERE t.row_num BETWEEN #{start_row.to_s} AND #{end_row.to_s}"
|
@@ -371,6 +352,12 @@ module ::JdbcSpec
|
|
371
352
|
end
|
372
353
|
end
|
373
354
|
|
355
|
+
def select(sql, name = nil)
|
356
|
+
log(sql, name) do
|
357
|
+
@connection.execute_query(sql)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
374
361
|
#SELECT .. FOR UPDATE is not supported on Microsoft SQL Server
|
375
362
|
def add_lock!(sql, options)
|
376
363
|
sql
|
@@ -452,17 +439,18 @@ module ::JdbcSpec
|
|
452
439
|
|
453
440
|
def determine_order_clause(sql)
|
454
441
|
return $1 if sql =~ /ORDER BY (.*)$/
|
455
|
-
|
456
|
-
table_name = $1
|
442
|
+
table_name = get_table_name(sql)
|
457
443
|
"#{table_name}.#{determine_primary_key(table_name)}"
|
458
444
|
end
|
459
445
|
|
460
446
|
def determine_primary_key(table_name)
|
461
447
|
primary_key = columns(table_name).detect { |column| column.primary || column.identity }
|
462
|
-
|
448
|
+
return primary_key.name if primary_key
|
449
|
+
# Look for an id column. Return it, without changing case, to cover dbs with a case-sensitive collation.
|
450
|
+
columns(table_name).each { |column| return column.name if column.name =~ /^id$/i }
|
451
|
+
# Give up and provide something which is going to crash almost certainly
|
452
|
+
"id"
|
463
453
|
end
|
464
|
-
|
465
454
|
end
|
466
|
-
|
467
455
|
end
|
468
456
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
def mssql_connection(config)
|
4
|
+
require "arjdbc/mssql"
|
5
|
+
config[:host] ||= "localhost"
|
6
|
+
config[:port] ||= 1433
|
7
|
+
config[:url] ||= "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
8
|
+
config[:driver] ||= "net.sourceforge.jtds.jdbc.Driver"
|
9
|
+
embedded_driver(config)
|
10
|
+
end
|
11
|
+
alias_method :jdbcmssql_connection, :mssql_connection
|
12
|
+
end
|
13
|
+
end
|
data/lib/arjdbc/mssql.rb
ADDED