Class: Arel::Visitors::SQLServer
- Inherits:
-
Object
- Object
- Arel::Visitors::SQLServer
- 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
Instance Method Summary collapse
- #visit_Arel_Nodes_Bin(o, a = nil) ⇒ Object
- #visit_Arel_Nodes_Limit(o, a = nil) ⇒ Object
- #visit_Arel_Nodes_Lock(o, a = nil) ⇒ Object
- #visit_Arel_Nodes_Ordering(o, a = nil) ⇒ Object
-
#visit_Arel_Nodes_SelectStatement(*args) ⇒ Object
[o] AR <= 4.0 [o, a] on 4.1.
- #visit_Arel_Nodes_Top(o, a = nil) ⇒ Object
-
#visit_Arel_Nodes_UpdateStatement(*args) ⇒ Object
[o] AR <= 4.0 [o, a] on 4.1.
Methods included from ArJdbc::MSSQL::LimitHelpers::SqlServerReplaceLimitOffset
Methods included from ArJdbc::MSSQL::LockMethods
Instance Method Details
#visit_Arel_Nodes_Bin(o, a = nil) ⇒ Object
86 87 88 |
# File 'lib/arel/visitors/sql_server.rb', line 86 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
73 74 75 |
# File 'lib/arel/visitors/sql_server.rb', line 73 def visit_Arel_Nodes_Limit o, a = nil "TOP (#{do_visit o.expr, a})" end |
#visit_Arel_Nodes_Lock(o, a = nil) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/arel/visitors/sql_server.rb', line 57 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
77 78 79 80 81 82 83 84 |
# File 'lib/arel/visitors/sql_server.rb', line 77 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 44 45 46 47 |
# 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 if ! o.limit && ! o.offset return super elsif ! o.limit && o.offset raise ActiveRecord::ActiveRecordError, "must specify :limit with :offset" end unless o.orders.empty? select_order_by = "ORDER BY #{o.orders.map { |x| do_visit x, 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
65 66 67 68 69 70 71 |
# File 'lib/arel/visitors/sql_server.rb', line 65 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
49 50 51 52 53 54 55 |
# File 'lib/arel/visitors/sql_server.rb', line 49 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(9223372036854775807) end super end |