activerecord-jdbc-alt-adapter 52.2.3-java → 60.1.0-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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +80 -52
  4. data/Gemfile +10 -3
  5. data/README.md +55 -37
  6. data/Rakefile +31 -5
  7. data/Rakefile.jdbc +8 -1
  8. data/activerecord-jdbc-adapter.gemspec +6 -9
  9. data/activerecord-jdbc-alt-adapter.gemspec +6 -9
  10. data/lib/arel/visitors/sqlserver.rb +33 -23
  11. data/lib/arjdbc/abstract/connection_management.rb +7 -0
  12. data/lib/arjdbc/abstract/core.rb +17 -24
  13. data/lib/arjdbc/abstract/database_statements.rb +31 -20
  14. data/lib/arjdbc/abstract/statement_cache.rb +2 -5
  15. data/lib/arjdbc/abstract/transaction_support.rb +5 -3
  16. data/lib/arjdbc/db2/column.rb +0 -39
  17. data/lib/arjdbc/derby/adapter.rb +1 -20
  18. data/lib/arjdbc/firebird/adapter.rb +0 -21
  19. data/lib/arjdbc/h2/adapter.rb +0 -15
  20. data/lib/arjdbc/hsqldb/adapter.rb +0 -14
  21. data/lib/arjdbc/informix/adapter.rb +0 -23
  22. data/lib/arjdbc/jdbc.rb +0 -4
  23. data/lib/arjdbc/jdbc/adapter.rb +3 -1
  24. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  25. data/lib/arjdbc/jdbc/base_ext.rb +3 -1
  26. data/lib/arjdbc/jdbc/callbacks.rb +2 -0
  27. data/lib/arjdbc/jdbc/column.rb +3 -5
  28. data/lib/arjdbc/jdbc/connection.rb +2 -0
  29. data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
  30. data/lib/arjdbc/jdbc/error.rb +2 -0
  31. data/lib/arjdbc/jdbc/extension.rb +2 -0
  32. data/lib/arjdbc/jdbc/java.rb +3 -1
  33. data/lib/arjdbc/jdbc/railtie.rb +3 -1
  34. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
  35. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
  36. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  37. data/lib/arjdbc/jdbc/type_converter.rb +2 -0
  38. data/lib/arjdbc/mssql.rb +3 -1
  39. data/lib/arjdbc/mssql/adapter.rb +112 -46
  40. data/lib/arjdbc/mssql/column.rb +5 -1
  41. data/lib/arjdbc/mssql/connection_methods.rb +13 -2
  42. data/lib/arjdbc/mssql/database_limits.rb +2 -0
  43. data/lib/arjdbc/mssql/database_statements.rb +44 -6
  44. data/lib/arjdbc/mssql/errors.rb +2 -0
  45. data/lib/arjdbc/mssql/explain_support.rb +3 -1
  46. data/lib/arjdbc/mssql/extensions/attribute_methods.rb +5 -1
  47. data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
  48. data/lib/arjdbc/mssql/quoting.rb +38 -0
  49. data/lib/arjdbc/mssql/schema_creation.rb +24 -2
  50. data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
  51. data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
  52. data/lib/arjdbc/mssql/schema_statements.rb +63 -21
  53. data/lib/arjdbc/mssql/transaction.rb +2 -0
  54. data/lib/arjdbc/mssql/types.rb +2 -0
  55. data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
  56. data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
  57. data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
  58. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
  59. data/lib/arjdbc/mssql/types/string_types.rb +2 -0
  60. data/lib/arjdbc/mssql/utils.rb +2 -0
  61. data/lib/arjdbc/mysql/adapter.rb +47 -18
  62. data/lib/arjdbc/mysql/connection_methods.rb +13 -7
  63. data/lib/arjdbc/postgresql/adapter.rb +240 -214
  64. data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
  65. data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
  66. data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
  67. data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
  68. data/lib/arjdbc/postgresql/column.rb +11 -6
  69. data/lib/arjdbc/postgresql/connection_methods.rb +3 -1
  70. data/lib/arjdbc/postgresql/name.rb +2 -0
  71. data/lib/arjdbc/postgresql/oid_types.rb +3 -1
  72. data/lib/arjdbc/sqlite3/adapter.rb +188 -180
  73. data/lib/arjdbc/sqlite3/connection_methods.rb +16 -4
  74. data/lib/arjdbc/tasks/databases.rake +13 -10
  75. data/lib/arjdbc/tasks/mssql_database_tasks.rb +49 -5
  76. data/lib/arjdbc/util/quoted_cache.rb +3 -1
  77. data/lib/arjdbc/util/serialized_attributes.rb +3 -1
  78. data/lib/arjdbc/util/table_copier.rb +3 -1
  79. data/lib/arjdbc/version.rb +1 -1
  80. data/pom.xml +4 -4
  81. data/rakelib/01-tomcat.rake +2 -2
  82. data/rakelib/02-test.rake +0 -2
  83. data/rakelib/rails.rake +1 -1
  84. data/src/java/arjdbc/ArJdbcModule.java +5 -5
  85. data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
  86. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +468 -637
  87. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +319 -38
  88. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
  89. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +44 -31
  90. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
  91. data/src/java/arjdbc/util/DateTimeUtils.java +34 -12
  92. metadata +7 -17
@@ -1,11 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  # MSSQL specific extensions to column definitions in a table.
4
6
  class MSSQLColumn < Column
7
+ attr_reader :table_name
5
8
  def initialize(name, raw_default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
9
+ @table_name = table_name
6
10
  default = extract_default(raw_default)
7
11
 
8
- super(name, default, sql_type_metadata, null, table_name, default_function, collation, comment: comment)
12
+ super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
9
13
  end
10
14
 
11
15
  def extract_default(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ArJdbc::ConnectionMethods.module_eval do
2
4
 
3
5
  # Default connection method for MS-SQL adapter (`adapter: mssql`),
@@ -11,6 +13,8 @@ ArJdbc::ConnectionMethods.module_eval do
11
13
  return sqlserver_connection(config)
12
14
  end
13
15
 
16
+ config = config.deep_dup
17
+
14
18
  config[:adapter_spec] ||= ::ArJdbc::MSSQL
15
19
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::MSSQLAdapter unless config.key?(:adapter_class)
16
20
 
@@ -31,7 +35,8 @@ ArJdbc::ConnectionMethods.module_eval do
31
35
  config[:connection_alive_sql] ||= 'SELECT 1'
32
36
 
33
37
  config[:url] ||= begin
34
- url = "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
38
+ url = ''.dup
39
+ url << "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
35
40
  # Instance is often a preferrable alternative to port when dynamic ports are used.
36
41
  # If instance is specified then port is essentially ignored.
37
42
  url << ";instance=#{config[:instance]}" if config[:instance]
@@ -52,6 +57,8 @@ ArJdbc::ConnectionMethods.module_eval do
52
57
 
53
58
  # @note Assumes SQLServer SQL-JDBC driver on the class-path.
54
59
  def sqlserver_connection(config)
60
+ config = config.deep_dup
61
+
55
62
  config[:adapter_spec] ||= ::ArJdbc::MSSQL
56
63
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::MSSQLAdapter unless config.key?(:adapter_class)
57
64
 
@@ -60,13 +67,17 @@ ArJdbc::ConnectionMethods.module_eval do
60
67
  config[:host] ||= 'localhost'
61
68
  config[:driver] ||= 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
62
69
  config[:connection_alive_sql] ||= 'SELECT 1'
70
+ config[:lock_timeout] ||= 5000
63
71
 
64
72
  config[:url] ||= begin
65
- url = "jdbc:sqlserver://#{config[:host]}"
73
+ url = ''.dup
74
+ url << "jdbc:sqlserver://#{config[:host]}"
66
75
  url << ( config[:port] ? ":#{config[:port]};" : ';' )
67
76
  url << "databaseName=#{config[:database]};" if config[:database]
68
77
  url << "instanceName=#{config[:instance]};" if config[:instance]
69
78
  url << "sendTimeAsDatetime=#{config[:send_time_as_datetime] || false};"
79
+ url << "loginTimeout=#{config[:login_timeout].to_i};" if config[:login_timeout]
80
+ url << "lockTimeout=#{config[:lock_timeout].to_i};"
70
81
  app = config[:appname] || config[:application]
71
82
  url << "applicationName=#{app};" if app
72
83
  isc = config[:integrated_security] # Win only - needs sqljdbc_auth.dll
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -23,6 +25,15 @@ module ActiveRecord
23
25
  end
24
26
  alias_method :execute_procedure, :exec_proc # AR-SQLServer-Adapter naming
25
27
 
28
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
29
+ :begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :with
30
+ ) # :nodoc:
31
+ private_constant :READ_QUERY
32
+
33
+ def write_query?(sql) # :nodoc:
34
+ !READ_QUERY.match?(sql)
35
+ end
36
+
26
37
  def execute(sql, name = nil)
27
38
  # with identity insert on block
28
39
  if insert_sql?(sql)
@@ -52,11 +63,6 @@ module ActiveRecord
52
63
  end
53
64
  end
54
65
 
55
- # Implements the truncate method.
56
- def truncate(table_name, name = nil)
57
- execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
58
- end
59
-
60
66
  # Not a rails method, own method to test different isolation
61
67
  # levels supported by the mssql adapter.
62
68
  def supports_transaction_isolation_level?(level)
@@ -95,8 +101,40 @@ module ActiveRecord
95
101
  end
96
102
  end
97
103
 
104
+ # Implements the truncate method.
105
+ def truncate(table_name, name = nil)
106
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
107
+ end
108
+
109
+ def truncate_tables(*table_names) # :nodoc:
110
+ return if table_names.empty?
111
+
112
+ disable_referential_integrity do
113
+ table_names.each do |table_name|
114
+ mssql_truncate(table_name)
115
+ end
116
+ end
117
+ end
118
+
98
119
  private
99
120
 
121
+ # It seems the truncate_tables is mostly used for testing
122
+ # this a workaround to the fact that SQL Server truncate tables
123
+ # referenced by a foreign key, it may not be required to reset
124
+ # the identity column too, more at:
125
+ # https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver15
126
+ # TODO: improve is with pure T-SQL, use statements
127
+ # such as TRY CATCH and reset identity with DBCC CHECKIDENT
128
+ def mssql_truncate(table_name)
129
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", 'Truncate Tables'
130
+ rescue => e
131
+ if e.message =~ /Cannot truncate table .* because it is being referenced by a FOREIGN KEY constraint/
132
+ execute "DELETE FROM #{quote_table_name(table_name)}", 'Truncate Tables with Delete'
133
+ else
134
+ raise
135
+ end
136
+ end
137
+
100
138
  # Overrides method in abstract class, combining the sqls with semicolon
101
139
  # affects disable_referential_integrity in mssql specially when multiple
102
140
  # tables are involved.
@@ -127,7 +165,7 @@ module ActiveRecord
127
165
  end
128
166
 
129
167
  def identity_column_name(table_name)
130
- for column in columns(table_name)
168
+ for column in schema_cache.columns(table_name)
131
169
  return column.name if column.identity?
132
170
  end
133
171
  nil
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # Error raised when adapter determines the database could not acquire
3
5
  # a necessary lock before timing out
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/string'
2
4
 
3
5
  module ActiveRecord
@@ -108,7 +110,7 @@ module ActiveRecord
108
110
  end
109
111
 
110
112
  def build_separator
111
- '+' << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
113
+ '+'.dup << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
112
114
  end
113
115
 
114
116
  def build_cells(items)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file contains extensions, overrides, and monkey patches to core parts
2
4
  # of active record to allow SQL Server work properly.
3
5
  #
@@ -15,7 +17,9 @@ module ActiveRecord
15
17
  # this behaviour, even the current comments for that method says that
16
18
  # it rejects primary key but it doesn't (maybe a rails bug?)
17
19
  def attributes_for_update(attribute_names)
18
- attribute_names.reject do |name|
20
+ attribute_names &= self.class.column_names
21
+
22
+ attribute_names.delete_if do |name|
19
23
  # It seems is only required to check if column in identity or not.
20
24
  # This allows to update rails custom primary keys
21
25
  next true if readonly_attribute?(name)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/relation'
2
4
  require 'active_record/version'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -64,6 +66,42 @@ module ActiveRecord
64
66
  # @see #quote in old adapter
65
67
  BLOB_VALUE_MARKER = "''"
66
68
 
69
+ def column_name_matcher
70
+ COLUMN_NAME
71
+ end
72
+
73
+ def column_name_with_order_matcher
74
+ COLUMN_NAME_WITH_ORDER
75
+ end
76
+
77
+ COLUMN_NAME = /
78
+ \A
79
+ (
80
+ (?:
81
+ # \[table_name\].\[column_name\] | function(one or no argument)
82
+ ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
83
+ )
84
+ (?:\s+AS\s+(?:\w+|\[\w+\]))?
85
+ )
86
+ (?:\s*,\s*\g<1>)*
87
+ \z
88
+ /ix
89
+
90
+ COLUMN_NAME_WITH_ORDER = /
91
+ \A
92
+ (
93
+ (?:
94
+ # \[table_name\].\[column_name\] | function(one or no argument)
95
+ ((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
96
+ )
97
+ (?:\s+ASC|\s+DESC)?
98
+ )
99
+ (?:\s*,\s*\g<1>)*
100
+ \z
101
+ /ix
102
+
103
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
104
+
67
105
  private
68
106
 
69
107
  def time_with_db_timezone(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -11,8 +13,28 @@ module ActiveRecord
11
13
  projections, source = query.match(%r{SELECT\s+(.*)?\s+FROM\s+(.*)?}).captures
12
14
  select_into = "SELECT #{projections} INTO #{table_name} FROM #{source}"
13
15
  else
14
- o.instance_variable_set :@as, nil
15
- super
16
+ # o.instance_variable_set :@as, nil
17
+ # super
18
+ create_sql = +''
19
+
20
+ create_sql << "IF NOT EXISTS (SELECT 1 FROM sysobjects WHERE name='#{o.name}' and xtype='U') " if o.if_not_exists
21
+ create_sql << "CREATE#{table_modifier_in_create(o)} TABLE "
22
+ create_sql << "#{quote_table_name(o.name)} "
23
+
24
+ statements = o.columns.map { |c| accept c }
25
+ statements << accept(o.primary_keys) if o.primary_keys
26
+
27
+ if supports_indexes_in_create?
28
+ statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
29
+ end
30
+
31
+ if supports_foreign_keys?
32
+ statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
33
+ end
34
+
35
+ create_sql << "(#{statements.join(', ')})" if statements.present?
36
+ add_table_options!(create_sql, table_options(o))
37
+ create_sql
16
38
  end
17
39
  end
18
40
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -81,6 +83,14 @@ module ActiveRecord
81
83
 
82
84
  super
83
85
  end
86
+
87
+ def timestamps(**options)
88
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
89
+ options[:precision] = 7
90
+ end
91
+
92
+ super
93
+ end
84
94
  end
85
95
 
86
96
  class Table < ActiveRecord::ConnectionAdapters::Table
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MSSQL
4
- module SchemaStatements
6
+ module SchemaStatements # :nodoc:
5
7
 
6
8
  NATIVE_DATABASE_TYPES = {
7
9
  # Logical Rails types to SQL Server types
@@ -41,23 +43,36 @@ module ActiveRecord
41
43
  NATIVE_DATABASE_TYPES
42
44
  end
43
45
 
44
- # Returns an array of Column objects for the table specified by +table_name+.
45
- # See the concrete implementation for details on the expected parameter values.
46
- # NOTE: This is ready, all implemented in the java part of adapter,
47
- # it uses MSSQLColumn, SqlTypeMetadata, etc.
48
- def columns(table_name)
49
- @connection.columns(table_name)
50
- rescue => e
51
- # raise translate_exception_class(e, nil)
52
- # FIXME: this breaks one arjdbc test but fixes activerecord tests
53
- # (table name alias). Also it behaves similarly to the CRuby adapter
54
- # which returns an empty array too. (postgres throws a exception)
55
- []
56
- end
57
-
58
46
  # Returns an array of indexes for the given table.
59
- def indexes(table_name, name = nil)
60
- @connection.indexes(table_name, name)
47
+ def indexes(table_name)
48
+ data = select("EXEC sp_helpindex #{quote(table_name)}", "SCHEMA") rescue []
49
+
50
+ data.reduce([]) do |indexes, index|
51
+ index = index.with_indifferent_access
52
+
53
+ if index[:index_description] =~ /primary key/
54
+ indexes
55
+ else
56
+ name = index[:index_name]
57
+ unique = index[:index_description].to_s.match?(/unique/)
58
+ where = select_value("SELECT [filter_definition] FROM sys.indexes WHERE name = #{quote(name)}")
59
+ orders = {}
60
+ columns = []
61
+
62
+ index[:index_keys].split(',').each do |column|
63
+ column.strip!
64
+
65
+ if column.ends_with?('(-)')
66
+ column.gsub! '(-)', ''
67
+ orders[column] = :desc
68
+ end
69
+
70
+ columns << column
71
+ end
72
+
73
+ indexes << IndexDefinition.new(table_name, name, unique, columns, where: where, orders: orders)
74
+ end
75
+ end
61
76
  end
62
77
 
63
78
  def primary_keys(table_name)
@@ -124,7 +139,7 @@ module ActiveRecord
124
139
  end
125
140
  end
126
141
 
127
- if options[:if_exists] && @mssql_major_version < 13
142
+ if options[:if_exists] && mssql_major_version < 13
128
143
  # this is for sql server 2012 and 2014
129
144
  execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = #{quote(table_name)}) DROP TABLE #{quote_table_name(table_name)}"
130
145
  else
@@ -193,7 +208,7 @@ module ActiveRecord
193
208
  column_type_sql << "(#{precision})"
194
209
  else
195
210
  raise(
196
- ActiveRecordError,
211
+ ArgumentError,
197
212
  "No #{native[:name]} type has precision of #{precision}. The " \
198
213
  'allowed range of precision is from 0 to 7, even though the ' \
199
214
  'sql type precision is 7 this adapter will persist up to 6 ' \
@@ -220,6 +235,14 @@ module ActiveRecord
220
235
  (order_columns << super).join(', ')
221
236
  end
222
237
 
238
+ def add_timestamps(table_name, options = {})
239
+ if !options.key?(:precision) && supports_datetime_with_precision?
240
+ options[:precision] = 7
241
+ end
242
+
243
+ super
244
+ end
245
+
223
246
  def create_schema_dumper(options)
224
247
  MSSQL::SchemaDumper.create(self, options)
225
248
  end
@@ -299,13 +322,30 @@ module ActiveRecord
299
322
  execute(sql_alter.join(' '))
300
323
  end
301
324
 
325
+ def update_table_definition(table_name, base) #:nodoc:
326
+ MSSQL::Table.new(table_name, base)
327
+ end
328
+
302
329
  private
303
330
 
331
+ def schema_creation
332
+ MSSQL::SchemaCreation.new(self)
333
+ end
334
+
335
+ def create_table_definition(*args)
336
+ MSSQL::TableDefinition.new(self, *args)
337
+ end
338
+
339
+ def new_column_from_field(table_name, field)
340
+ field
341
+ end
342
+
304
343
  def data_source_sql(name = nil, type: nil)
305
344
  scope = quoted_scope(name, type: type)
306
345
  table_name = 'TABLE_NAME'
307
346
 
308
- sql = "SELECT #{table_name}"
347
+ sql = ''.dup
348
+ sql << "SELECT #{table_name}"
309
349
  sql << ' FROM INFORMATION_SCHEMA.TABLES'
310
350
  sql << ' WHERE TABLE_CATALOG = DB_NAME()'
311
351
  sql << " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
@@ -327,7 +367,9 @@ module ActiveRecord
327
367
  end
328
368
 
329
369
  def change_column_type(table_name, column_name, type, options = {})
330
- sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
370
+ sql = ''.dup
371
+
372
+ sql << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
331
373
  sql << (options[:null] ? " NULL" : " NOT NULL") if options.has_key?(:null)
332
374
  result = execute(sql)
333
375
  result