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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +80 -52
- data/Gemfile +10 -3
- data/README.md +55 -37
- data/Rakefile +31 -5
- data/Rakefile.jdbc +8 -1
- data/activerecord-jdbc-adapter.gemspec +6 -9
- data/activerecord-jdbc-alt-adapter.gemspec +6 -9
- data/lib/arel/visitors/sqlserver.rb +33 -23
- data/lib/arjdbc/abstract/connection_management.rb +7 -0
- data/lib/arjdbc/abstract/core.rb +17 -24
- data/lib/arjdbc/abstract/database_statements.rb +31 -20
- data/lib/arjdbc/abstract/statement_cache.rb +2 -5
- data/lib/arjdbc/abstract/transaction_support.rb +5 -3
- data/lib/arjdbc/db2/column.rb +0 -39
- data/lib/arjdbc/derby/adapter.rb +1 -20
- data/lib/arjdbc/firebird/adapter.rb +0 -21
- data/lib/arjdbc/h2/adapter.rb +0 -15
- data/lib/arjdbc/hsqldb/adapter.rb +0 -14
- data/lib/arjdbc/informix/adapter.rb +0 -23
- data/lib/arjdbc/jdbc.rb +0 -4
- data/lib/arjdbc/jdbc/adapter.rb +3 -1
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/base_ext.rb +3 -1
- data/lib/arjdbc/jdbc/callbacks.rb +2 -0
- data/lib/arjdbc/jdbc/column.rb +3 -5
- data/lib/arjdbc/jdbc/connection.rb +2 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
- data/lib/arjdbc/jdbc/error.rb +2 -0
- data/lib/arjdbc/jdbc/extension.rb +2 -0
- data/lib/arjdbc/jdbc/java.rb +3 -1
- data/lib/arjdbc/jdbc/railtie.rb +3 -1
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
- data/lib/arjdbc/jdbc/type_cast.rb +2 -0
- data/lib/arjdbc/jdbc/type_converter.rb +2 -0
- data/lib/arjdbc/mssql.rb +3 -1
- data/lib/arjdbc/mssql/adapter.rb +112 -46
- data/lib/arjdbc/mssql/column.rb +5 -1
- data/lib/arjdbc/mssql/connection_methods.rb +13 -2
- data/lib/arjdbc/mssql/database_limits.rb +2 -0
- data/lib/arjdbc/mssql/database_statements.rb +44 -6
- data/lib/arjdbc/mssql/errors.rb +2 -0
- data/lib/arjdbc/mssql/explain_support.rb +3 -1
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +5 -1
- data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
- data/lib/arjdbc/mssql/quoting.rb +38 -0
- data/lib/arjdbc/mssql/schema_creation.rb +24 -2
- data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
- data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
- data/lib/arjdbc/mssql/schema_statements.rb +63 -21
- data/lib/arjdbc/mssql/transaction.rb +2 -0
- data/lib/arjdbc/mssql/types.rb +2 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
- data/lib/arjdbc/mssql/types/string_types.rb +2 -0
- data/lib/arjdbc/mssql/utils.rb +2 -0
- data/lib/arjdbc/mysql/adapter.rb +47 -18
- data/lib/arjdbc/mysql/connection_methods.rb +13 -7
- data/lib/arjdbc/postgresql/adapter.rb +240 -214
- data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
- data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
- data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
- data/lib/arjdbc/postgresql/column.rb +11 -6
- data/lib/arjdbc/postgresql/connection_methods.rb +3 -1
- data/lib/arjdbc/postgresql/name.rb +2 -0
- data/lib/arjdbc/postgresql/oid_types.rb +3 -1
- data/lib/arjdbc/sqlite3/adapter.rb +188 -180
- data/lib/arjdbc/sqlite3/connection_methods.rb +16 -4
- data/lib/arjdbc/tasks/databases.rake +13 -10
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +49 -5
- data/lib/arjdbc/util/quoted_cache.rb +3 -1
- data/lib/arjdbc/util/serialized_attributes.rb +3 -1
- data/lib/arjdbc/util/table_copier.rb +3 -1
- data/lib/arjdbc/version.rb +1 -1
- data/pom.xml +4 -4
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/02-test.rake +0 -2
- data/rakelib/rails.rake +1 -1
- data/src/java/arjdbc/ArJdbcModule.java +5 -5
- data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +468 -637
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +319 -38
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +44 -31
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
- data/src/java/arjdbc/util/DateTimeUtils.java +34 -12
- metadata +7 -17
data/lib/arjdbc/mssql/column.rb
CHANGED
@@ -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,
|
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 =
|
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 =
|
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
|
@@ -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
|
data/lib/arjdbc/mssql/errors.rb
CHANGED
@@ -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
|
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)
|
data/lib/arjdbc/mssql/quoting.rb
CHANGED
@@ -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,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
|
60
|
-
|
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] &&
|
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
|
-
|
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 =
|
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 =
|
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
|