Class: Arel::Visitors::SQLServer

Inherits:
Object
  • Object
show all
Includes:
ArJdbc::MSSQL::LimitHelpers::SqlServerReplaceLimitOffset, ArJdbc::MSSQL::LockMethods
Defined in:
lib/arel/visitors/sql_server.rb

Overview

Note:

AREL set's up Arel::Visitors::MSSQL but we should not use that one !

Direct Known Subclasses

SQLServer2000

Instance Method Summary collapse

Methods included from ArJdbc::MSSQL::LimitHelpers::SqlServerReplaceLimitOffset

append_limit_row_num_clause, replace_limit_offset!

Methods included from ArJdbc::MSSQL::LockMethods

#add_lock!

Instance Method Details

#do_visit_columns(colls, a) ⇒ Object



104
105
106
# File 'lib/arel/visitors/sql_server.rb', line 104

def do_visit_columns(colls, a)
  colls.map { |x| do_visit x, a }
end

#visit_Arel_Nodes_Bin(o, a = nil) ⇒ Object



85
86
87
# File 'lib/arel/visitors/sql_server.rb', line 85

def visit_Arel_Nodes_Bin o, a = nil
  "#{do_visit o.expr, a} COLLATE Latin1_General_CS_AS_WS"
end

#visit_Arel_Nodes_Limit(o, a = nil) ⇒ Object



72
73
74
# File 'lib/arel/visitors/sql_server.rb', line 72

def visit_Arel_Nodes_Limit o, a = nil
  "TOP (#{do_visit o.expr, a})"
end

#visit_Arel_Nodes_Lock(o, a = nil) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/arel/visitors/sql_server.rb', line 56

def visit_Arel_Nodes_Lock o, a = nil
  # MS-SQL doesn't support "SELECT...FOR UPDATE".  Instead, it needs
  # WITH(ROWLOCK,UPDLOCK) specified after each table in the FROM clause.
  #
  # we return nothing here and add the appropriate stuff with #add_lock!
  #do_visit o.expr, a
end

#visit_Arel_Nodes_Ordering(o, a = nil) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/arel/visitors/sql_server.rb', line 76

def visit_Arel_Nodes_Ordering o, a = nil
  expr = do_visit o.expr, a
  if o.respond_to?(:direction)
    "#{expr} #{o.ascending? ? 'ASC' : 'DESC'}"
  else
    expr
  end
end

#visit_Arel_Nodes_SelectStatement(*args) ⇒ Object

[o] AR <= 4.0 [o, a] on 4.1



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/arel/visitors/sql_server.rb', line 8

def visit_Arel_Nodes_SelectStatement(*args) # [o] AR <= 4.0 [o, a] on 4.1
  o, a = args.first, args.last

  return super if ! o.limit && ! o.offset # NOTE: really?

  unless o.orders.empty?
    select_order_by = "ORDER BY #{do_visit_columns(o.orders, a).join(', ')}"
  end

  select_count = false
  sql = o.cores.map do |x|
    x = x.dup
    order_by = select_order_by || determine_order_by(x, a)
    if select_count? x
      p = order_by ? row_num_literal(order_by) : Arel::Nodes::SqlLiteral.new("*")
      x.projections = [p]
      select_count = true
    else
      # NOTE: this should really be added here and we should built the
      # wrapping SQL but than #replace_limit_offset! assumes it does that
      # ... MS-SQL adapter code seems to be 'hacked' by a lot of people
      #x.projections << row_num_literal(order_by)
    end
    do_visit_select_core x, a
  end.join

  #sql = "SELECT _t.* FROM (#{sql}) as _t WHERE #{get_offset_limit_clause(o)}"
  select_order_by ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
  replace_limit_offset!(sql, limit_for(o.limit), o.offset && o.offset.value.to_i, select_order_by)

  sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if select_count

  add_lock!(sql, :lock => o.lock && true)

  sql
end

#visit_Arel_Nodes_Top(o, a = nil) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/arel/visitors/sql_server.rb', line 64

def visit_Arel_Nodes_Top o, a = nil
  # `top` wouldn't really work here:
  #   User.select("distinct first_name").limit(10)
  # would generate "select top 10 distinct first_name from users",
  # which is invalid should be "select distinct top 10 first_name ..."
  ''
end

#visit_Arel_Nodes_UpdateStatement(*args) ⇒ Object

[o] AR <= 4.0 [o, a] on 4.1



48
49
50
51
52
53
54
# File 'lib/arel/visitors/sql_server.rb', line 48

def visit_Arel_Nodes_UpdateStatement(*args) # [o] AR <= 4.0 [o, a] on 4.1
  o = args.first
  if o.orders.any? && o.limit.nil?
    o.limit = Nodes::Limit.new(MAX_LIMIT_VALUE)
  end
  super
end