activerecord-sqlserver-adapter_new 4.2.15

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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/CHANGELOG.md +212 -0
  4. data/CODE_OF_CONDUCT.md +31 -0
  5. data/Gemfile +61 -0
  6. data/Guardfile +29 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +201 -0
  9. data/RUNNING_UNIT_TESTS.md +121 -0
  10. data/Rakefile +48 -0
  11. data/VERSION +1 -0
  12. data/activerecord-sqlserver-adapter_new.gemspec +20 -0
  13. data/appveyor.yml +39 -0
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +27 -0
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +25 -0
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +40 -0
  17. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +4 -0
  18. data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +34 -0
  19. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +49 -0
  20. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +386 -0
  21. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +68 -0
  22. data/lib/active_record/connection_adapters/sqlserver/errors.rb +7 -0
  23. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +69 -0
  24. data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +114 -0
  25. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +52 -0
  26. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +473 -0
  27. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +66 -0
  28. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +66 -0
  29. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +22 -0
  30. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +76 -0
  31. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +57 -0
  32. data/lib/active_record/connection_adapters/sqlserver/type.rb +46 -0
  33. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +15 -0
  34. data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +15 -0
  35. data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +12 -0
  36. data/lib/active_record/connection_adapters/sqlserver/type/char.rb +38 -0
  37. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +21 -0
  38. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +41 -0
  39. data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +17 -0
  40. data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +31 -0
  41. data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +12 -0
  42. data/lib/active_record/connection_adapters/sqlserver/type/float.rb +15 -0
  43. data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +12 -0
  44. data/lib/active_record/connection_adapters/sqlserver/type/money.rb +21 -0
  45. data/lib/active_record/connection_adapters/sqlserver/type/real.rb +15 -0
  46. data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +13 -0
  47. data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +21 -0
  48. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +22 -0
  49. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +12 -0
  50. data/lib/active_record/connection_adapters/sqlserver/type/text.rb +15 -0
  51. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +40 -0
  52. data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +76 -0
  53. data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +15 -0
  54. data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +22 -0
  55. data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +15 -0
  56. data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +12 -0
  57. data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +15 -0
  58. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +20 -0
  59. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +20 -0
  60. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +23 -0
  61. data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +20 -0
  62. data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +20 -0
  63. data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +20 -0
  64. data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +20 -0
  65. data/lib/active_record/connection_adapters/sqlserver/utils.rb +136 -0
  66. data/lib/active_record/connection_adapters/sqlserver/version.rb +11 -0
  67. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +405 -0
  68. data/lib/active_record/connection_adapters/sqlserver_column.rb +53 -0
  69. data/lib/active_record/sqlserver_base.rb +20 -0
  70. data/lib/active_record/tasks/sqlserver_database_tasks.rb +131 -0
  71. data/lib/activerecord-sqlserver-adapter.rb +1 -0
  72. data/lib/arel/visitors/sqlserver.rb +214 -0
  73. data/lib/arel_sqlserver.rb +3 -0
  74. data/test/appveyor/dbsetup.ps1 +27 -0
  75. data/test/appveyor/dbsetup.sql +11 -0
  76. data/test/cases/adapter_test_sqlserver.rb +444 -0
  77. data/test/cases/coerced_tests.rb +713 -0
  78. data/test/cases/column_test_sqlserver.rb +780 -0
  79. data/test/cases/connection_test_sqlserver.rb +142 -0
  80. data/test/cases/execute_procedure_test_sqlserver.rb +44 -0
  81. data/test/cases/fetch_test_sqlserver.rb +57 -0
  82. data/test/cases/fully_qualified_identifier_test_sqlserver.rb +76 -0
  83. data/test/cases/helper_sqlserver.rb +54 -0
  84. data/test/cases/migration_test_sqlserver.rb +61 -0
  85. data/test/cases/order_test_sqlserver.rb +147 -0
  86. data/test/cases/pessimistic_locking_test_sqlserver.rb +90 -0
  87. data/test/cases/rake_test_sqlserver.rb +163 -0
  88. data/test/cases/schema_dumper_test_sqlserver.rb +198 -0
  89. data/test/cases/schema_test_sqlserver.rb +54 -0
  90. data/test/cases/scratchpad_test_sqlserver.rb +9 -0
  91. data/test/cases/showplan_test_sqlserver.rb +65 -0
  92. data/test/cases/specific_schema_test_sqlserver.rb +167 -0
  93. data/test/cases/transaction_test_sqlserver.rb +66 -0
  94. data/test/cases/utils_test_sqlserver.rb +129 -0
  95. data/test/cases/uuid_test_sqlserver.rb +48 -0
  96. data/test/config.yml +41 -0
  97. data/test/debug.rb +14 -0
  98. data/test/fixtures/1px.gif +0 -0
  99. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +11 -0
  100. data/test/models/sqlserver/booking.rb +3 -0
  101. data/test/models/sqlserver/customers_view.rb +3 -0
  102. data/test/models/sqlserver/datatype.rb +3 -0
  103. data/test/models/sqlserver/datatype_migration.rb +3 -0
  104. data/test/models/sqlserver/dollar_table_name.rb +3 -0
  105. data/test/models/sqlserver/dot_table_name.rb +3 -0
  106. data/test/models/sqlserver/edge_schema.rb +13 -0
  107. data/test/models/sqlserver/fk_has_fk.rb +3 -0
  108. data/test/models/sqlserver/fk_has_pk.rb +3 -0
  109. data/test/models/sqlserver/natural_pk_data.rb +4 -0
  110. data/test/models/sqlserver/natural_pk_int_data.rb +3 -0
  111. data/test/models/sqlserver/no_pk_data.rb +3 -0
  112. data/test/models/sqlserver/object_default.rb +3 -0
  113. data/test/models/sqlserver/quoted_table.rb +7 -0
  114. data/test/models/sqlserver/quoted_view_1.rb +3 -0
  115. data/test/models/sqlserver/quoted_view_2.rb +3 -0
  116. data/test/models/sqlserver/string_default.rb +3 -0
  117. data/test/models/sqlserver/string_defaults_big_view.rb +3 -0
  118. data/test/models/sqlserver/string_defaults_view.rb +3 -0
  119. data/test/models/sqlserver/tinyint_pk.rb +3 -0
  120. data/test/models/sqlserver/upper.rb +3 -0
  121. data/test/models/sqlserver/uppered.rb +3 -0
  122. data/test/models/sqlserver/uuid.rb +3 -0
  123. data/test/schema/datatypes/2012.sql +55 -0
  124. data/test/schema/sqlserver_specific_schema.rb +207 -0
  125. data/test/support/coerceable_test_sqlserver.rb +45 -0
  126. data/test/support/connection_reflection.rb +37 -0
  127. data/test/support/load_schema_sqlserver.rb +29 -0
  128. data/test/support/minitest_sqlserver.rb +1 -0
  129. data/test/support/paths_sqlserver.rb +50 -0
  130. data/test/support/rake_helpers.rb +41 -0
  131. data/test/support/sql_counter_sqlserver.rb +32 -0
  132. metadata +253 -0
@@ -0,0 +1,53 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class SQLServerColumn < Column
4
+
5
+ def initialize(name, default, cast_type, sql_type = nil, null = true, sqlserver_options = {})
6
+ super(name, default, cast_type, sql_type, null)
7
+ @sqlserver_options = sqlserver_options.symbolize_keys
8
+ @default_function = @sqlserver_options[:default_function]
9
+ end
10
+
11
+ def sql_type_for_statement
12
+ if is_integer? || is_real?
13
+ sql_type.sub(/\((\d+)?\)/, '')
14
+ else
15
+ sql_type
16
+ end
17
+ end
18
+
19
+ def table_name
20
+ @sqlserver_options[:table_name]
21
+ end
22
+
23
+ def is_identity?
24
+ @sqlserver_options[:is_identity]
25
+ end
26
+
27
+ def is_primary?
28
+ @sqlserver_options[:is_primary]
29
+ end
30
+
31
+ def is_utf8?
32
+ @sql_type =~ /nvarchar|ntext|nchar/i
33
+ end
34
+
35
+ def is_integer?
36
+ @sql_type =~ /int/i
37
+ end
38
+
39
+ def is_real?
40
+ @sql_type =~ /real/i
41
+ end
42
+
43
+ def collation
44
+ @sqlserver_options[:collation]
45
+ end
46
+
47
+ def case_sensitive?
48
+ collation && !collation.match(/_CI/)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveRecord
2
+ module ConnectionHandling
3
+ def sqlserver_connection(config) #:nodoc:
4
+ config = config.symbolize_keys
5
+ config.reverse_merge! mode: :dblib
6
+ mode = config[:mode].to_s.downcase.underscore.to_sym
7
+ case mode
8
+ when :dblib
9
+ require 'tiny_tds'
10
+ when :odbc
11
+ raise ArgumentError, 'Missing :dsn configuration.' unless config.key?(:dsn)
12
+ require 'odbc'
13
+ require 'active_record/connection_adapters/sqlserver/core_ext/odbc'
14
+ else
15
+ raise ArgumentError, "Unknown connection mode in #{config.inspect}."
16
+ end
17
+ ConnectionAdapters::SQLServerAdapter.new(nil, logger, nil, config.merge(mode: mode))
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,131 @@
1
+ require 'active_record/tasks/database_tasks'
2
+ require 'shellwords'
3
+ require 'ipaddr'
4
+ require 'socket'
5
+
6
+ module ActiveRecord
7
+ module Tasks
8
+
9
+ class SQLServerDatabaseTasks
10
+
11
+ DEFAULT_COLLATION = 'SQL_Latin1_General_CP1_CI_AS'
12
+
13
+ delegate :connection, :establish_connection, :clear_active_connections!,
14
+ to: ActiveRecord::Base
15
+
16
+ def initialize(configuration)
17
+ @configuration = configuration
18
+ end
19
+
20
+ def create(master_established = false)
21
+ establish_master_connection unless master_established
22
+ connection.create_database configuration['database'], configuration.merge('collation' => default_collation)
23
+ establish_connection configuration
24
+ rescue ActiveRecord::StatementInvalid => error
25
+ if /database .* already exists/i === error.message
26
+ raise DatabaseAlreadyExists
27
+ else
28
+ raise
29
+ end
30
+ end
31
+
32
+ def drop
33
+ establish_master_connection
34
+ connection.drop_database configuration['database']
35
+ end
36
+
37
+ def charset
38
+ connection.charset
39
+ end
40
+
41
+ def collation
42
+ connection.collation
43
+ end
44
+
45
+ def purge
46
+ clear_active_connections!
47
+ drop
48
+ create true
49
+ end
50
+
51
+ def structure_dump(filename)
52
+ command = [
53
+ "defncopy",
54
+ "-S #{Shellwords.escape(configuration['host'])}",
55
+ "-D #{Shellwords.escape(configuration['database'])}",
56
+ "-U #{Shellwords.escape(configuration['username'])}",
57
+ "-P #{Shellwords.escape(configuration['password'])}",
58
+ "-o #{Shellwords.escape(filename)}",
59
+ ]
60
+ table_args = connection.tables.map { |t| Shellwords.escape(t) }
61
+ command.concat(table_args)
62
+ view_args = connection.views.map { |v| Shellwords.escape(v) }
63
+ command.concat(view_args)
64
+ raise 'Error dumping database' unless Kernel.system(command.join(' '))
65
+ dump = File.read(filename)
66
+ dump.gsub!(/^USE .*$\nGO\n/, '') # Strip db USE statements
67
+ dump.gsub!(/^GO\n/, '') # Strip db GO statements
68
+ dump.gsub!(/nvarchar\(8000\)/, 'nvarchar(4000)') # Fix nvarchar(8000) column defs
69
+ dump.gsub!(/nvarchar\(-1\)/, 'nvarchar(max)') # Fix nvarchar(-1) column defs
70
+ dump.gsub!(/text\(\d+\)/, 'text') # Fix text(16) column defs
71
+ File.open(filename, "w") { |file| file.puts dump }
72
+ end
73
+
74
+ def structure_load(filename)
75
+ connection.execute File.read(filename)
76
+ end
77
+
78
+
79
+ private
80
+
81
+ def configuration
82
+ @configuration
83
+ end
84
+
85
+ def default_collation
86
+ configuration['collation'] || DEFAULT_COLLATION
87
+ end
88
+
89
+ def establish_master_connection
90
+ establish_connection configuration.merge('database' => 'master')
91
+ end
92
+
93
+ end
94
+
95
+ module DatabaseTasksSQLServer
96
+
97
+ extend ActiveSupport::Concern
98
+
99
+ module ClassMethods
100
+
101
+ LOCAL_IPADDR = [
102
+ IPAddr.new('192.168.0.0/16'),
103
+ IPAddr.new('10.0.0.0/8'),
104
+ IPAddr.new('172.16.0.0/12')
105
+ ]
106
+
107
+ private
108
+
109
+ def local_database?(configuration)
110
+ super || local_ipaddr?(configuration_host_ip(configuration))
111
+ end
112
+
113
+ def configuration_host_ip(configuration)
114
+ return nil unless configuration['host']
115
+ Socket::getaddrinfo(configuration['host'], 'echo', Socket::AF_INET)[0][3]
116
+ end
117
+
118
+ def local_ipaddr?(host_ip)
119
+ return false unless host_ip
120
+ LOCAL_IPADDR.any? { |ip| ip.include?(host_ip) }
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
127
+ DatabaseTasks.register_task %r{sqlserver}, SQLServerDatabaseTasks
128
+ DatabaseTasks.send :include, DatabaseTasksSQLServer
129
+
130
+ end
131
+ end
@@ -0,0 +1 @@
1
+ require 'active_record/connection_adapters/sqlserver_adapter'
@@ -0,0 +1,214 @@
1
+ module Arel
2
+ module Visitors
3
+ class SQLServer < Arel::Visitors::ToSql
4
+
5
+ OFFSET = " OFFSET "
6
+ ROWS = " ROWS"
7
+ FETCH = " FETCH NEXT "
8
+ FETCH0 = " FETCH FIRST (SELECT 0) "
9
+ ROWS_ONLY = " ROWS ONLY"
10
+
11
+
12
+ private
13
+
14
+ # SQLServer ToSql/Visitor (Overides)
15
+
16
+ def visit_Arel_Nodes_BindParam o, collector
17
+ collector.add_bind(o) { |i| "@#{i-1}" }
18
+ end
19
+
20
+ def visit_Arel_Nodes_Bin o, collector
21
+ visit o.expr, collector
22
+ if o.expr.val.is_a? Numeric
23
+ collector
24
+ else
25
+ collector << " #{ActiveRecord::ConnectionAdapters::SQLServerAdapter.cs_equality_operator} "
26
+ end
27
+ end
28
+
29
+ def visit_Arel_Nodes_UpdateStatement(o, a)
30
+ if o.orders.any? && o.limit.nil?
31
+ o.limit = Nodes::Limit.new(9_223_372_036_854_775_807)
32
+ end
33
+ super
34
+ end
35
+
36
+ def visit_Arel_Nodes_Lock o, collector
37
+ o.expr = Arel.sql('WITH(UPDLOCK)') if o.expr.to_s =~ /FOR UPDATE/
38
+ collector << SPACE
39
+ visit o.expr, collector
40
+ end
41
+
42
+ def visit_Arel_Nodes_Offset o, collector
43
+ collector << OFFSET
44
+ visit o.expr, collector
45
+ collector << ROWS
46
+ end
47
+
48
+ def visit_Arel_Nodes_Limit o, collector
49
+ if node_value(o) == 0
50
+ collector << FETCH0
51
+ collector << ROWS_ONLY
52
+ else
53
+ collector << FETCH
54
+ visit o.expr, collector
55
+ collector << ROWS_ONLY
56
+ end
57
+ end
58
+
59
+ def visit_Arel_Nodes_SelectStatement o, collector
60
+ @select_statement = o
61
+ distinct_One_As_One_Is_So_Not_Fetch o
62
+ if o.with
63
+ collector = visit o.with, collector
64
+ collector << SPACE
65
+ end
66
+ collector = o.cores.inject(collector) { |c,x|
67
+ visit_Arel_Nodes_SelectCore(x, c)
68
+ }
69
+ collector = visit_Orders_And_Let_Fetch_Happen o, collector
70
+ collector = visit_Make_Fetch_Happen o, collector
71
+ collector
72
+ ensure
73
+ @select_statement = nil
74
+ end
75
+
76
+ def visit_Arel_Table o, collector
77
+ # Apparently, o.engine.connection can actually be a different adapter
78
+ # than sqlserver. Can be removed if fixed in ActiveRecord. See:
79
+ # github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450
80
+ table_name = if o.engine.connection.respond_to?(:sqlserver?) && o.engine.connection.database_prefix_remote_server?
81
+ remote_server_table_name(o)
82
+ else
83
+ quote_table_name(o.name)
84
+ end
85
+ if o.table_alias
86
+ collector << "#{table_name} #{quote_table_name o.table_alias}"
87
+ else
88
+ collector << table_name
89
+ end
90
+ end
91
+
92
+ def visit_Arel_Nodes_JoinSource o, collector
93
+ if o.left
94
+ collector = visit o.left, collector
95
+ collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
96
+ end
97
+ if o.right.any?
98
+ collector << " " if o.left
99
+ collector = inject_join o.right, collector, ' '
100
+ end
101
+ collector
102
+ end
103
+
104
+ def visit_Arel_Nodes_OuterJoin o, collector
105
+ collector << "LEFT OUTER JOIN "
106
+ collector = visit o.left, collector
107
+ collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
108
+ collector << " "
109
+ visit o.right, collector
110
+ end
111
+
112
+ # SQLServer ToSql/Visitor (Additions)
113
+
114
+ def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
115
+ if select_statement_lock?
116
+ collector = visit @select_statement.lock, collector
117
+ collector << SPACE if options[:space]
118
+ end
119
+ collector
120
+ end
121
+
122
+ def visit_Orders_And_Let_Fetch_Happen o, collector
123
+ make_Fetch_Possible_And_Deterministic o
124
+ unless o.orders.empty?
125
+ collector << SPACE
126
+ collector << ORDER_BY
127
+ len = o.orders.length - 1
128
+ o.orders.each_with_index { |x, i|
129
+ collector = visit(x, collector)
130
+ collector << COMMA unless len == i
131
+ }
132
+ end
133
+ collector
134
+ end
135
+
136
+ def visit_Make_Fetch_Happen o, collector
137
+ o.offset = Nodes::Offset.new(0) if o.limit && !o.offset
138
+ collector = visit o.offset, collector if o.offset
139
+ collector = visit o.limit, collector if o.limit
140
+ collector
141
+ end
142
+
143
+ # SQLServer Helpers
144
+
145
+ def node_value(node)
146
+ return nil unless node
147
+ case node.expr
148
+ when NilClass then nil
149
+ when Numeric then node.expr
150
+ when Arel::Nodes::Unary then node.expr.expr
151
+ end
152
+ end
153
+
154
+ def select_statement_lock?
155
+ @select_statement && @select_statement.lock
156
+ end
157
+
158
+ def make_Fetch_Possible_And_Deterministic o
159
+ return if o.limit.nil? && o.offset.nil?
160
+ t = table_From_Statement o
161
+ pk = primary_Key_From_Table t
162
+ return unless pk
163
+ if o.orders.empty?
164
+ # Prefer deterministic vs a simple `(SELECT NULL)` expr.
165
+ o.orders = [pk.asc]
166
+ end
167
+ end
168
+
169
+ def distinct_One_As_One_Is_So_Not_Fetch o
170
+ core = o.cores.first
171
+ distinct = Nodes::Distinct === core.set_quantifier
172
+ oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE }
173
+ limitone = node_value(o.limit) == 1
174
+ if distinct && oneasone && limitone && !o.offset
175
+ core.projections = [Arel.sql("TOP(1) 1 AS [one]")]
176
+ o.limit = nil
177
+ end
178
+ end
179
+
180
+ def table_From_Statement o
181
+ core = o.cores.first
182
+ if Arel::Table === core.from
183
+ core.from
184
+ elsif Arel::Nodes::SqlLiteral === core.from
185
+ Arel::Table.new(core.from)
186
+ elsif Arel::Nodes::JoinSource === core.source
187
+ Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left
188
+ end
189
+ end
190
+
191
+ def primary_Key_From_Table t
192
+ return unless t
193
+ return t.primary_key if t.primary_key
194
+ if engine_pk = t.engine.primary_key
195
+ pk = t.engine.arel_table[engine_pk]
196
+ return pk if pk
197
+ end
198
+ pk = t.engine.connection.schema_cache.primary_keys(t.engine.table_name)
199
+ return pk if pk
200
+ column_name = t.engine.columns.first.try(:name)
201
+ column_name ? t[column_name] : nil
202
+ end
203
+
204
+ def remote_server_table_name o
205
+ ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
206
+ "#{o.engine.connection.database_prefix}#{o.name}"
207
+ ).quoted
208
+ end
209
+
210
+ end
211
+ end
212
+ end
213
+
214
+ Arel::Visitors::VISITORS['sqlserver'] = Arel::Visitors::SQLServer
@@ -0,0 +1,3 @@
1
+ require 'arel'
2
+ require 'arel/visitors/bind_visitor'
3
+ require 'arel/visitors/sqlserver'
@@ -0,0 +1,27 @@
1
+
2
+ Write-Output "Setting up..."
3
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
4
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null
5
+
6
+ Write-Output "Setting variables..."
7
+ $serverName = $env:COMPUTERNAME
8
+ $instances = @('SQL2012SP1', 'SQL2014')
9
+ $smo = 'Microsoft.SqlServer.Management.Smo.'
10
+ $wmi = new-object ($smo + 'Wmi.ManagedComputer')
11
+
12
+ Write-Output "Configure Instances..."
13
+ foreach ($instance in $instances) {
14
+ Write-Output "Instance $instance ..."
15
+ Write-Output "Enable TCP/IP and port 1433..."
16
+ $uri = "ManagedComputer[@Name='$serverName']/ServerInstance[@Name='$instance']/ServerProtocol[@Name='Tcp']"
17
+ $tcp = $wmi.GetSmoObject($uri)
18
+ $tcp.IsEnabled = $true
19
+ foreach ($ipAddress in $Tcp.IPAddresses) {
20
+ $ipAddress.IPAddressProperties["TcpDynamicPorts"].Value = ""
21
+ $ipAddress.IPAddressProperties["TcpPort"].Value = "1433"
22
+ }
23
+ $tcp.Alter()
24
+ }
25
+
26
+ Set-Service SQLBrowser -StartupType Manual
27
+ Start-Service SQLBrowser