# File lib/arel/visitors/sqlserver.rb, line 203 def primary_Key_From_Table t return unless t column_name = @connection.schema_cache.primary_keys(t.name) || @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name) column_name ? t[column_name] : nil end
class Arel::Visitors::SQLServer
Constants
- FETCH
- FETCH0
- OFFSET
- ROWS
- ROWS_ONLY
Private Instance Methods
distinct_One_As_One_Is_So_Not_Fetch(o)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 181 def distinct_One_As_One_Is_So_Not_Fetch o core = o.cores.first distinct = Nodes::Distinct === core.set_quantifier oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE } limitone = [nil, 0, 1].include? node_value(o.limit) if distinct && oneasone && limitone && !o.offset core.projections = [Arel.sql("TOP(1) 1 AS [one]")] o.limit = nil end end
make_Fetch_Possible_And_Deterministic(o)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 170 def make_Fetch_Possible_And_Deterministic o return if o.limit.nil? && o.offset.nil? t = table_From_Statement o pk = primary_Key_From_Table t return unless pk if o.orders.empty? # Prefer deterministic vs a simple `(SELECT NULL)` expr. o.orders = [pk.asc] end end
node_value(node)
click to toggle source
SQLServer
Helpers
# File lib/arel/visitors/sqlserver.rb, line 157 def node_value(node) return nil unless node case node.expr when NilClass then nil when Numeric then node.expr when Arel::Nodes::Unary then node.expr.expr end end
primary_Key_From_Table(t)
click to toggle source
remote_server_table_name(o)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 210 def remote_server_table_name o ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers( "#{o.class.engine.connection.database_prefix}#{o.name}" ).quoted end
select_statement_lock?()
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 166 def select_statement_lock? @select_statement && @select_statement.lock end
table_From_Statement(o)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 192 def table_From_Statement o core = o.cores.first if Arel::Table === core.from core.from elsif Arel::Nodes::SqlLiteral === core.from Arel::Table.new(core.from) elsif Arel::Nodes::JoinSource === core.source Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left end end
visit_Arel_Nodes_Bin(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 20 def visit_Arel_Nodes_Bin o, collector visit o.expr, collector collector << " #{ActiveRecord::ConnectionAdapters::SQLServerAdapter.cs_equality_operator} " end
visit_Arel_Nodes_BindParam(o, collector)
click to toggle source
SQLServer
ToSql/Visitor (Overides)
# File lib/arel/visitors/sqlserver.rb, line 16 def visit_Arel_Nodes_BindParam o, collector collector.add_bind(o.value) { |i| "@#{i-1}" } end
visit_Arel_Nodes_InnerJoin(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 104 def visit_Arel_Nodes_InnerJoin o, collector collector << "INNER JOIN " collector = visit o.left, collector collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true if o.right collector << SPACE visit(o.right, collector) else collector end end
visit_Arel_Nodes_JoinSource(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 92 def visit_Arel_Nodes_JoinSource o, collector if o.left collector = visit o.left, collector collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector end if o.right.any? collector << SPACE if o.left collector = inject_join o.right, collector, ' ' end collector end
visit_Arel_Nodes_Limit(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 44 def visit_Arel_Nodes_Limit o, collector if node_value(o) == 0 collector << FETCH0 collector << ROWS_ONLY else collector << FETCH visit o.expr, collector collector << ROWS_ONLY end end
visit_Arel_Nodes_Lock(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 32 def visit_Arel_Nodes_Lock o, collector o.expr = Arel.sql('WITH(UPDLOCK)') if o.expr.to_s =~ /FOR UPDATE/ collector << SPACE visit o.expr, collector end
visit_Arel_Nodes_Offset(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 38 def visit_Arel_Nodes_Offset o, collector collector << OFFSET visit o.expr, collector collector << ROWS end
visit_Arel_Nodes_OuterJoin(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 116 def visit_Arel_Nodes_OuterJoin o, collector collector << "LEFT OUTER JOIN " collector = visit o.left, collector collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true collector << SPACE visit o.right, collector end
visit_Arel_Nodes_SelectStatement(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 55 def visit_Arel_Nodes_SelectStatement o, collector @select_statement = o distinct_One_As_One_Is_So_Not_Fetch o if o.with collector = visit o.with, collector collector << SPACE end collector = o.cores.inject(collector) { |c,x| visit_Arel_Nodes_SelectCore(x, c) } collector = visit_Orders_And_Let_Fetch_Happen o, collector collector = visit_Make_Fetch_Happen o, collector collector ensure @select_statement = nil end
visit_Arel_Nodes_SelectStatement_SQLServer_Lock(collector, options = {})
click to toggle source
SQLServer
ToSql/Visitor (Additions)
# File lib/arel/visitors/sqlserver.rb, line 126 def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {} if select_statement_lock? collector = visit @select_statement.lock, collector collector << SPACE if options[:space] end collector end
visit_Arel_Nodes_UpdateStatement(o, a)
click to toggle source
Calls superclass method
# File lib/arel/visitors/sqlserver.rb, line 25 def visit_Arel_Nodes_UpdateStatement(o, a) if o.orders.any? && o.limit.nil? o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) end super end
visit_Arel_Table(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 72 def visit_Arel_Table o, collector # Apparently, o.engine.connection can actually be a different adapter # than sqlserver. Can be removed if fixed in ActiveRecord. See: # github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450 table_name = begin if o.class.engine.connection.respond_to?(:sqlserver?) && o.class.engine.connection.database_prefix_remote_server? remote_server_table_name(o) else quote_table_name(o.name) end rescue Exception => e quote_table_name(o.name) end if o.table_alias collector << "#{table_name} #{quote_table_name o.table_alias}" else collector << table_name end end
visit_Make_Fetch_Happen(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 148 def visit_Make_Fetch_Happen o, collector o.offset = Nodes::Offset.new(0) if o.limit && !o.offset collector = visit o.offset, collector if o.offset collector = visit o.limit, collector if o.limit collector end
visit_Orders_And_Let_Fetch_Happen(o, collector)
click to toggle source
# File lib/arel/visitors/sqlserver.rb, line 134 def visit_Orders_And_Let_Fetch_Happen o, collector make_Fetch_Possible_And_Deterministic o unless o.orders.empty? collector << SPACE collector << ORDER_BY len = o.orders.length - 1 o.orders.each_with_index { |x, i| collector = visit(x, collector) collector << COMMA unless len == i } end collector end