activerecord-jdbc-adapter 1.2.2.1 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/.gitignore +1 -2
  2. data/.travis.yml +18 -3
  3. data/Appraisals +16 -0
  4. data/Gemfile +10 -10
  5. data/Gemfile.lock +27 -17
  6. data/LICENSE.txt +20 -17
  7. data/README.rdoc +29 -14
  8. data/Rakefile +4 -4
  9. data/activerecord-jdbc-adapter.gemspec +2 -1
  10. data/gemfiles/rails23.gemfile +12 -0
  11. data/gemfiles/rails23.gemfile.lock +44 -0
  12. data/gemfiles/rails30.gemfile +11 -0
  13. data/gemfiles/rails30.gemfile.lock +39 -0
  14. data/gemfiles/rails31.gemfile +11 -0
  15. data/gemfiles/rails31.gemfile.lock +41 -0
  16. data/gemfiles/rails32.gemfile +11 -0
  17. data/gemfiles/rails32.gemfile.lock +41 -0
  18. data/lib/arel/visitors/sql_server.rb +7 -0
  19. data/lib/arjdbc/db2/adapter.rb +82 -32
  20. data/lib/arjdbc/derby.rb +0 -4
  21. data/lib/arjdbc/derby/adapter.rb +1 -1
  22. data/lib/arjdbc/derby/connection_methods.rb +3 -2
  23. data/lib/arjdbc/discover.rb +16 -1
  24. data/lib/arjdbc/firebird/adapter.rb +5 -1
  25. data/lib/arjdbc/h2.rb +0 -1
  26. data/lib/arjdbc/h2/connection_methods.rb +3 -1
  27. data/lib/arjdbc/hsqldb.rb +0 -1
  28. data/lib/arjdbc/hsqldb/adapter.rb +4 -3
  29. data/lib/arjdbc/hsqldb/connection_methods.rb +3 -3
  30. data/lib/arjdbc/informix/adapter.rb +5 -1
  31. data/lib/arjdbc/jdbc/adapter.rb +22 -24
  32. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  33. data/lib/arjdbc/jdbc/base_ext.rb +1 -1
  34. data/lib/arjdbc/jdbc/connection.rb +23 -29
  35. data/lib/arjdbc/jdbc/core_ext.rb +1 -1
  36. data/lib/arjdbc/jdbc/discover.rb +1 -1
  37. data/lib/arjdbc/jdbc/driver.rb +1 -1
  38. data/lib/arjdbc/jdbc/extension.rb +3 -3
  39. data/lib/arjdbc/jdbc/jdbc.rake +15 -5
  40. data/lib/arjdbc/mssql.rb +0 -1
  41. data/lib/arjdbc/mssql/adapter.rb +10 -4
  42. data/lib/arjdbc/mssql/connection_methods.rb +15 -15
  43. data/lib/arjdbc/mssql/limit_helpers.rb +24 -2
  44. data/lib/arjdbc/mssql/tsql_helper.rb +0 -8
  45. data/lib/arjdbc/mysql.rb +0 -1
  46. data/lib/arjdbc/mysql/adapter.rb +82 -0
  47. data/lib/arjdbc/mysql/connection_methods.rb +3 -4
  48. data/lib/arjdbc/oracle/adapter.rb +12 -2
  49. data/lib/arjdbc/postgresql.rb +0 -1
  50. data/lib/arjdbc/postgresql/adapter.rb +127 -27
  51. data/lib/arjdbc/postgresql/connection_methods.rb +3 -4
  52. data/lib/arjdbc/sqlite3.rb +0 -1
  53. data/lib/arjdbc/sqlite3/adapter.rb +13 -14
  54. data/lib/arjdbc/sqlite3/connection_methods.rb +3 -4
  55. data/lib/arjdbc/version.rb +1 -1
  56. data/rakelib/01-tomcat.rake +52 -0
  57. data/rakelib/02-test.rake +111 -0
  58. data/rakelib/db.rake +4 -3
  59. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +7 -0
  60. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +8 -3
  61. data/test/abstract_db_create.rb +5 -1
  62. data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -1
  63. data/test/activerecord/jall.sh +0 -0
  64. data/test/activerecord/jtest.sh +0 -0
  65. data/test/db/db2.rb +2 -0
  66. data/test/db/derby.rb +3 -5
  67. data/test/db/h2.rb +3 -1
  68. data/test/db/hsqldb.rb +2 -0
  69. data/test/db/informix.rb +2 -0
  70. data/test/db/jdbc.rb +11 -10
  71. data/test/db/jdbc_derby.rb +14 -0
  72. data/test/db/jdbc_h2.rb +17 -0
  73. data/test/db/jdbc_mysql.rb +13 -0
  74. data/test/db/jdbc_postgres.rb +23 -0
  75. data/test/db/jndi_config.rb +28 -33
  76. data/test/db/jndi_pooled_config.rb +35 -0
  77. data/test/db/logger.rb +1 -1
  78. data/test/db/mssql.rb +2 -0
  79. data/test/db/mysql.rb +2 -7
  80. data/test/db/mysql_config.rb +7 -0
  81. data/test/db/oracle.rb +2 -0
  82. data/test/db/postgres.rb +9 -7
  83. data/test/db/postgres_config.rb +10 -0
  84. data/test/db/sqlite3.rb +2 -0
  85. data/test/db2_reset_column_information_test.rb +0 -2
  86. data/test/derby_migration_test.rb +0 -1
  87. data/test/derby_multibyte_test.rb +0 -1
  88. data/test/derby_reset_column_information_test.rb +0 -3
  89. data/test/derby_row_locking_test.rb +0 -3
  90. data/test/derby_simple_test.rb +0 -1
  91. data/test/generic_jdbc_connection_test.rb +72 -17
  92. data/test/h2_change_column_test.rb +0 -1
  93. data/test/h2_simple_test.rb +0 -1
  94. data/test/helper.rb +22 -91
  95. data/test/jdbc_common.rb +98 -3
  96. data/test/jndi_callbacks_test.rb +6 -5
  97. data/test/jndi_test.rb +40 -15
  98. data/test/models/custom_pk_name.rb +14 -0
  99. data/test/mssql_ignore_system_views_test.rb +7 -4
  100. data/test/mssql_limit_offset_test.rb +30 -0
  101. data/test/mssql_multibyte_test.rb +1 -2
  102. data/test/mssql_reset_column_information_test.rb +0 -2
  103. data/test/mssql_row_locking_sql_test.rb +0 -2
  104. data/test/mssql_row_locking_test.rb +0 -2
  105. data/test/mysql_reset_column_information_test.rb +0 -2
  106. data/test/mysql_simple_test.rb +3 -18
  107. data/test/oracle_limit_test.rb +23 -0
  108. data/test/oracle_reset_column_information_test.rb +0 -2
  109. data/test/postgres_db_create_test.rb +0 -1
  110. data/test/postgres_drop_db_test.rb +0 -1
  111. data/test/postgres_information_schema_leak_test.rb +0 -1
  112. data/test/postgres_native_type_mapping_test.rb +17 -14
  113. data/test/postgres_nonseq_pkey_test.rb +0 -1
  114. data/test/postgres_reserved_test.rb +1 -2
  115. data/test/postgres_reset_column_information_test.rb +0 -3
  116. data/test/postgres_schema_search_path_test.rb +0 -1
  117. data/test/postgres_simple_test.rb +40 -1
  118. data/test/postgres_table_alias_length_test.rb +0 -1
  119. data/test/postgres_type_conversion_test.rb +0 -1
  120. data/test/row_locking.rb +6 -2
  121. data/test/simple.rb +57 -20
  122. data/test/sqlite3_reset_column_information_test.rb +0 -2
  123. data/test/sqlite3_simple_test.rb +1 -16
  124. data/test/sybase_reset_column_information_test.rb +0 -2
  125. metadata +366 -343
  126. data/lib/arjdbc/jdbc/require_driver.rb +0 -16
@@ -2,13 +2,13 @@ module ActiveRecord
2
2
  class Base
3
3
  class << self
4
4
  def hsqldb_connection(config)
5
- require "arjdbc/hsqldb"
5
+ require 'active_record/connection_adapters/jdbchsqldb_adapter'
6
+
6
7
  config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
7
- config[:driver] ||= "org.hsqldb.jdbcDriver"
8
+ config[:driver] ||= defined?(::Jdbc::HSQLDB.driver_name) ? ::Jdbc::HSQLDB.driver_name : 'org.hsqldb.jdbcDriver'
8
9
  config[:adapter_spec] = ::ArJdbc::HSQLDB
9
10
  embedded_driver(config)
10
11
  end
11
-
12
12
  alias_method :jdbchsqldb_connection, :hsqldb_connection
13
13
  end
14
14
  end
@@ -8,7 +8,11 @@ module ::ActiveRecord
8
8
  self.class.columns.each do |c|
9
9
  if [:text, :binary].include? c.type
10
10
  value = self[c.name]
11
- value = value.to_yaml if unserializable_attribute?(c.name, c)
11
+ if respond_to?(:unserializable_attribute?)
12
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
13
+ else
14
+ value = value.to_yaml if value.is_a?(Hash)
15
+ end
12
16
 
13
17
  unless value.nil? || (value == '')
14
18
  connection.write_large_object(c.type == :binary,
@@ -1,19 +1,17 @@
1
1
  require 'active_record/version'
2
2
  require 'active_record/connection_adapters/abstract_adapter'
3
3
  require 'arjdbc/version'
4
- require 'arjdbc/jdbc/require_driver'
4
+ require 'arjdbc/jdbc/base_ext'
5
5
  require 'arjdbc/jdbc/connection_methods'
6
6
  require 'arjdbc/jdbc/compatibility'
7
7
  require 'arjdbc/jdbc/core_ext'
8
8
  require 'arjdbc/jdbc/java'
9
- require 'arjdbc/jdbc/type_converter'
10
9
  require 'arjdbc/jdbc/driver'
11
10
  require 'arjdbc/jdbc/column'
12
11
  require 'arjdbc/jdbc/connection'
13
12
  require 'arjdbc/jdbc/callbacks'
14
13
  require 'arjdbc/jdbc/extension'
15
- require 'arjdbc/jdbc/base_ext'
16
- require 'bigdecimal'
14
+ require 'arjdbc/jdbc/type_converter'
17
15
 
18
16
  module ActiveRecord
19
17
  module ConnectionAdapters
@@ -58,30 +56,30 @@ module ActiveRecord
58
56
 
59
57
  # Locate specialized adapter specification if one exists based on config data
60
58
  def adapter_spec(config)
61
- 2.times do
62
- dialect = (config[:dialect] || config[:driver]).to_s
63
- ::ArJdbc.constants.map { |name| ::ArJdbc.const_get name }.each do |constant|
64
- if constant.respond_to? :adapter_matcher
65
- spec = constant.adapter_matcher(dialect, config)
66
- return spec if spec
67
- end
59
+ dialect = (config[:dialect] || config[:driver]).to_s
60
+ ::ArJdbc.constants.sort.each do |constant|
61
+ constant = ::ArJdbc.const_get(constant) # e.g. ArJdbc::MySQL
62
+
63
+ if constant.respond_to?(:adapter_matcher)
64
+ spec = constant.adapter_matcher(dialect, config)
65
+ return spec if spec
68
66
  end
67
+ end
69
68
 
70
- # If nothing matches and we're using jndi, try to automatically detect the database.
71
- break unless config[:jndi] and !config[:dialect]
69
+ if config[:jndi] && ! config[:dialect]
72
70
  begin
73
- conn = Java::javax.naming.InitialContext.new.lookup(config[:jndi]).getConnection
74
- config[:dialect] = conn.getMetaData.getDatabaseProductName
75
-
76
- # Derby-specific hack
77
- if ::ArJdbc::Derby.adapter_matcher(config[:dialect], config)
78
- # Needed to set the correct database schema name
79
- config[:username] ||= conn.getMetaData.getUserName
80
- end
81
- rescue
82
- conn.close if conn
71
+ data_source = Java::JavaxNaming::InitialContext.new.lookup(config[:jndi])
72
+ connection = data_source.getConnection
73
+ config[:dialect] = connection.getMetaData.getDatabaseProductName
74
+ rescue Java::JavaSql::SQLException => e
75
+ warn "failed to set database :dialect from connection meda-data (#{e})"
76
+ else
77
+ return adapter_spec(config) # re-try matching a spec with set config[:dialect]
78
+ ensure
79
+ connection.close if connection # return to the pool
83
80
  end
84
81
  end
82
+
85
83
  nil
86
84
  end
87
85
 
@@ -112,7 +110,7 @@ module ActiveRecord
112
110
  if defined?(::Arel::Visitors::VISITORS)
113
111
  visitors = ::Arel::Visitors::VISITORS
114
112
  visitor = nil
115
- adapter_spec = config[:adapter_spec] || self.class
113
+ adapter_spec = [config[:adapter_spec], self.class].detect {|a| a && a.respond_to?(:arel2_visitors) }
116
114
  adapter_spec.arel2_visitors(config).each do |k,v|
117
115
  visitor = v
118
116
  visitors[k] = v
Binary file
@@ -1,6 +1,6 @@
1
1
  module ActiveRecord
2
2
  class Base # reopen
3
- class <<self
3
+ class << self
4
4
  # Allow adapters to provide their own reset_column_information methods
5
5
  #
6
6
  # NOTE: This only affects the current thread's connection.
@@ -26,25 +26,36 @@ module ActiveRecord
26
26
  end
27
27
 
28
28
  def configure_jndi
29
- jndi = config[:jndi].to_s
30
- ctx = javax.naming.InitialContext.new
31
- ds = ctx.lookup(jndi)
29
+ data_source = javax.naming.InitialContext.new.lookup config[:jndi].to_s
30
+ @jndi_connection = true
32
31
  @connection_factory = JdbcConnectionFactory.impl do
33
- ds.connection
32
+ data_source.connection
34
33
  end
35
- unless config[:driver]
36
- config[:driver] = connection.meta_data.connection.java_class.name
34
+ end
35
+
36
+ def configure_jdbc
37
+ if ! config[:url] || ( ! config[:driver] && ! config[:driver_instance] )
38
+ raise ::ActiveRecord::ConnectionNotEstablished, "jdbc adapter requires :driver class and :url"
39
+ end
40
+
41
+ url = configure_url
42
+ username = config[:username].to_s
43
+ password = config[:password].to_s
44
+ jdbc_driver = ( config[:driver_instance] ||= JdbcDriver.new(config[:driver].to_s) )
45
+
46
+ @connection_factory = JdbcConnectionFactory.impl do
47
+ jdbc_driver.connection(url, username, password)
37
48
  end
38
- @jndi_connection = true
39
49
  end
40
50
 
51
+ private
41
52
  def configure_url
42
53
  url = config[:url].to_s
43
54
  if Hash === config[:options]
44
55
  options = ''
45
- config[:options].each do |k,v|
56
+ config[:options].each do |key, val|
46
57
  options << '&' unless options.empty?
47
- options << "#{k}=#{v}"
58
+ options << "#{key}=#{val}"
48
59
  end
49
60
  url = url['?'] ? "#{url}&#{options}" : "#{url}?#{options}" unless options.empty?
50
61
  config[:url] = url
@@ -53,20 +64,6 @@ module ActiveRecord
53
64
  url
54
65
  end
55
66
 
56
- def configure_jdbc
57
- unless config[:driver] && config[:url]
58
- raise ::ActiveRecord::ConnectionNotEstablished, "jdbc adapter requires driver class and url"
59
- end
60
-
61
- driver = config[:driver].to_s
62
- user = config[:username].to_s
63
- pass = config[:password].to_s
64
- url = configure_url
65
- jdbc_driver = (config[:driver_instance] ||= JdbcDriver.new(driver))
66
- @connection_factory = JdbcConnectionFactory.impl do
67
- jdbc_driver.connection(url, user, pass)
68
- end
69
- end
70
67
  end
71
68
 
72
69
  attr_reader :adapter, :connection_factory
@@ -107,11 +104,8 @@ module ActiveRecord
107
104
  types = {}
108
105
  @native_types.each_pair do |k, v|
109
106
  types[k] = v.inject({}) do |memo, kv|
110
- memo[kv.first] = if kv.last.is_a? Numeric
111
- kv.last
112
- else
113
- begin kv.last.dup rescue kv.last end
114
- end
107
+ last = kv.last
108
+ memo[kv.first] = last.is_a?(Numeric) ? last : (last.dup rescue last)
115
109
  memo
116
110
  end
117
111
  end
@@ -120,7 +114,7 @@ module ActiveRecord
120
114
  private :dup_native_types
121
115
 
122
116
  def jndi_connection?
123
- @jndi_connection
117
+ @jndi_connection == true
124
118
  end
125
119
 
126
120
  def active?
@@ -8,7 +8,7 @@ module ActiveRecord # :nodoc:
8
8
  attr_accessor :sql_exception
9
9
  end
10
10
 
11
- module ConnectionAdapters # :nodoc:
11
+ module ConnectionAdapters # :nodoc:
12
12
  # Allows properly re-wrapping/re-defining methods that may already
13
13
  # be alias_method_chain'd.
14
14
  module ShadowCoreMethods
@@ -4,7 +4,7 @@ module ArJdbc
4
4
  files = ::Gem.find_files('arjdbc/discover')
5
5
  else
6
6
  files = $LOAD_PATH.map do |p|
7
- discover = File.join(p, 'arjdbc','discover.rb')
7
+ discover = File.join(p, 'arjdbc', 'discover.rb')
8
8
  File.exist?(discover) ? discover : nil
9
9
  end.compact
10
10
  end
@@ -16,7 +16,7 @@ module ActiveRecord
16
16
  java_import(driver_class_name) { driver_class_const }
17
17
  end
18
18
  end
19
- end
19
+ end unless Jdbc.const_defined?(driver_class_const)
20
20
  driver_class = Jdbc.const_get(driver_class_const)
21
21
  raise "You must specify a driver for your JDBC connection" unless driver_class
22
22
  driver_class
@@ -34,11 +34,11 @@ module ArJdbc
34
34
  end
35
35
  (class << mod; self; end).instance_eval do
36
36
  unless respond_to?(:adapter_matcher)
37
- define_method :adapter_matcher do |name, config|
37
+ define_method :adapter_matcher do |_name, config|
38
38
  if block.arity == 1
39
- block.call(name) ? mod : false
39
+ block.call(_name) ? mod : false
40
40
  else
41
- block.call(name, config) ? mod : false
41
+ block.call(_name, config) ? mod : false
42
42
  end
43
43
  end
44
44
  end
@@ -12,7 +12,7 @@ def redefine_task(*args, &block)
12
12
  existing_task.instance_variable_set "@actions", []
13
13
  end
14
14
  redefined_task = task(*args, &block)
15
- enhancements.each {|enhancement| redefined_task.actions << enhancement}
15
+ enhancements.each {|enhancement| redefined_task.actions << enhancement} unless enhancements.nil?
16
16
  end
17
17
 
18
18
  def rails_env
@@ -83,7 +83,7 @@ namespace :db do
83
83
  end
84
84
 
85
85
  ActiveRecord::Base.establish_connection(config.merge({'database' => nil, 'url' => url}))
86
- ActiveRecord::Base.connection.create_database(config['database'])
86
+ ActiveRecord::Base.connection.create_database(config['database'], config)
87
87
  ActiveRecord::Base.establish_connection(config)
88
88
  rescue => e
89
89
  raise e unless config['adapter'] =~ /mysql|postgresql|sqlite/
@@ -100,9 +100,19 @@ namespace :db do
100
100
  redefine_task :dump => :environment do
101
101
  abcs = ActiveRecord::Base.configurations
102
102
  ActiveRecord::Base.establish_connection(abcs[rails_env])
103
- File.open("db/#{rails_env}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
103
+ filename = ENV['DB_STRUCTURE'] || "db/#{rails_env}_structure.sql"
104
+ File.open(filename, "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
104
105
  if ActiveRecord::Base.connection.supports_migrations?
105
- File.open("db/#{rails_env}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
106
+ File.open(filename, "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
107
+ end
108
+ end
109
+
110
+ redefine_task :load => :environment do
111
+ abcs = ActiveRecord::Base.configurations
112
+ ActiveRecord::Base.establish_connection(abcs[rails_env])
113
+ filename = ENV['DB_STRUCTURE'] || "db/#{rails_env}_structure.sql"
114
+ IO.read(filename).split(/;\n*/m).each do |ddl|
115
+ ActiveRecord::Base.connection.execute(ddl)
106
116
  end
107
117
  end
108
118
  end
@@ -125,7 +135,7 @@ namespace :db do
125
135
  redefine_task :purge => :environment do
126
136
  abcs = ActiveRecord::Base.configurations
127
137
  db = find_database_name(abcs['test'])
128
- ActiveRecord::Base.connection.recreate_database(db)
138
+ ActiveRecord::Base.connection.recreate_database(db, abcs['test'])
129
139
  end
130
140
  end
131
141
  end
data/lib/arjdbc/mssql.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  require 'arjdbc/jdbc'
2
- jdbc_require_driver 'jdbc/jtds', 'jdbc-mssql'
3
2
  require 'arjdbc/mssql/connection_methods'
4
3
  require 'arjdbc/mssql/adapter'
@@ -1,7 +1,7 @@
1
+ require 'strscan'
1
2
  require 'arjdbc/mssql/tsql_helper'
2
3
  require 'arjdbc/mssql/limit_helpers'
3
4
  require 'arjdbc/mssql/lock_helpers'
4
- require 'strscan'
5
5
 
6
6
  module ::ArJdbc
7
7
  module MsSQL
@@ -64,11 +64,17 @@ module ::ArJdbc
64
64
  def modify_types(tp) #:nodoc:
65
65
  super(tp)
66
66
  tp[:string] = {:name => "NVARCHAR", :limit => 255}
67
+
67
68
  if sqlserver_version == "2000"
68
69
  tp[:text] = {:name => "NTEXT"}
69
70
  else
70
71
  tp[:text] = {:name => "NVARCHAR(MAX)"}
71
72
  end
73
+
74
+ tp[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
75
+ tp[:integer][:limit] = nil
76
+ tp[:boolean] = {:name => "bit"}
77
+ tp[:binary] = {:name => "image"}
72
78
  tp
73
79
  end
74
80
 
@@ -255,9 +261,9 @@ module ::ArJdbc
255
261
  true
256
262
  end
257
263
 
258
- def recreate_database(name)
264
+ def recreate_database(name, options = {})
259
265
  drop_database(name)
260
- create_database(name)
266
+ create_database(name, options)
261
267
  end
262
268
 
263
269
  def drop_database(name)
@@ -265,7 +271,7 @@ module ::ArJdbc
265
271
  execute "DROP DATABASE #{name}"
266
272
  end
267
273
 
268
- def create_database(name)
274
+ def create_database(name, options={})
269
275
  execute "CREATE DATABASE #{name}"
270
276
  execute "USE #{name}"
271
277
  end
@@ -1,26 +1,26 @@
1
1
  class ActiveRecord::Base
2
2
  class << self
3
3
  def mssql_connection(config)
4
- require "arjdbc/mssql"
4
+ require 'active_record/connection_adapters/jdbcmssql_adapter'
5
+
5
6
  config[:host] ||= "localhost"
6
7
  config[:port] ||= 1433
7
- config[:driver] ||= "net.sourceforge.jtds.jdbc.Driver"
8
+ config[:driver] ||= defined?(::Jdbc::JTDS.driver_name) ? ::Jdbc::JTDS.driver_name : 'net.sourceforge.jtds.jdbc.Driver'
8
9
  config[:adapter_spec] = ::ArJdbc::MsSQL
9
10
 
10
- url = "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
11
-
12
- # Instance is often a preferrable alternative to port when dynamic ports are used.
13
- # If instance is specified then port is essentially ignored.
14
- url << ";instance=#{config[:instance]}" if config[:instance]
15
-
16
- # This will enable windows domain-based authentication and will require the JTDS native libraries be available.
17
- url << ";domain=#{config[:domain]}" if config[:domain]
18
-
19
- # AppName is shown in sql server as additional information against the connection.
20
- url << ";appname=#{config[:appname]}" if config[:appname]
21
- config[:url] ||= url
11
+ config[:url] ||= begin
12
+ url = "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
13
+ # Instance is often a preferrable alternative to port when dynamic ports are used.
14
+ # If instance is specified then port is essentially ignored.
15
+ url << ";instance=#{config[:instance]}" if config[:instance]
16
+ # This will enable windows domain-based authentication and will require the JTDS native libraries be available.
17
+ url << ";domain=#{config[:domain]}" if config[:domain]
18
+ # AppName is shown in sql server as additional information against the connection.
19
+ url << ";appname=#{config[:appname]}" if config[:appname]
20
+ url
21
+ end
22
22
 
23
- if !config[:domain]
23
+ unless config[:domain]
24
24
  config[:username] ||= "sa"
25
25
  config[:password] ||= ""
26
26
  end
@@ -12,6 +12,28 @@ module ::ArJdbc
12
12
  end
13
13
  end
14
14
 
15
+ def get_primary_key(order, table_name)
16
+ if order =~ /(\w*id\w*)/i
17
+ $1
18
+ else
19
+ table_name[/\[+(.*)\]+/i]
20
+
21
+ # rails 2 vs rails 3
22
+ if ActiveRecord::VERSION::MAJOR >= 3
23
+ models = ActiveRecord::Base.descendants
24
+ else
25
+ models = ActiveRecord::Base.send(:subclasses)
26
+ end
27
+
28
+ model = models.select{|model| model.table_name == $1}.first
29
+ if model then
30
+ model.primary_key
31
+ else
32
+ 'id'
33
+ end
34
+ end
35
+ end
36
+
15
37
  module SqlServer2000ReplaceLimitOffset
16
38
  module_function
17
39
  def replace_limit_offset!(sql, limit, offset, order)
@@ -31,7 +53,7 @@ module ::ArJdbc
31
53
  rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
32
54
  #need the table name for avoiding amiguity
33
55
  table_name = LimitHelpers.get_table_name(sql)
34
- primary_key = order[/(\w*id\w*)/i] || "id"
56
+ primary_key = LimitHelpers.get_primary_key(order, table_name)
35
57
  #I am not sure this will cover all bases. but all the tests pass
36
58
  if order[/ORDER/].nil?
37
59
  new_order = "ORDER BY #{order}, #{table_name}.#{primary_key}" if order.index("#{table_name}.#{primary_key}").nil?
@@ -57,7 +79,7 @@ module ::ArJdbc
57
79
  if options[:limit]
58
80
  order = "ORDER BY #{options[:order] || determine_order_clause(sql)}"
59
81
  sql.sub!(/ ORDER BY.*$/i, '')
60
- SqlServerReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)
82
+ SqlServer2000ReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)
61
83
  end
62
84
  end
63
85
  end