11module Arel
22 class Lock < Compound
3- def initialize ( relation , locked , & block )
4- @ relation = relation
5- @locked = locked . blank? ? "WITH(HOLDLOCK, ROWLOCK)" : locked
3+ def initialize ( relation , locked )
4+ super ( relation )
5+ @locked = true == locked ? "WITH(HOLDLOCK, ROWLOCK)" : locked
66 end
77 end
88end
@@ -12,88 +12,94 @@ module SqlCompiler
1212 class SQLServerCompiler < GenericCompiler
1313
1414 def select_sql
15- skipped ? select_sql_with_skipped : select_sql_without_skipped
15+ relation . skipped ? select_sql_with_skipped : select_sql_without_skipped
1616 end
1717
1818 def delete_sql
1919 build_query \
20- "DELETE #{ taken_clause if taken . present? } " . strip ,
21- "FROM #{ table_sql } " ,
22- ( "WHERE #{ wheres . collect ( &:to_sql ) . join ( ' AND ' ) } " unless wheres . blank? )
20+ "DELETE #{ taken_clause if relation . taken . present? } " . strip ,
21+ "FROM #{ relation . table_sql } " ,
22+ ( "WHERE #{ relation . wheres . collect ( &:to_sql ) . join ( ' AND ' ) } " unless relation . wheres . blank? )
2323 end
2424
2525
2626 protected
2727
2828 def taken_only?
29- taken . present? && skipped . blank?
29+ relation . taken . present? && relation . skipped . blank?
3030 end
3131
3232 def taken_clause
33- "TOP (#{ taken . to_i } ) "
33+ "TOP (#{ relation . taken . to_i } ) "
3434 end
3535
3636 def single_distinct_select?
37- select_clauses . size == 1 && select_clauses . first . include? ( 'DISTINCT' )
37+ relation . select_clauses . size == 1 && relation . select_clauses . first . include? ( 'DISTINCT' )
3838 end
3939
4040 def select_sql_without_skipped ( windowed = false )
41- select_clause = windowed ? select_clauses . map { |sc | bare_select_clause ( sc ) } . join ( ', ' ) :
42- "SELECT #{ taken_clause if taken_only? } #{ select_clauses . join ( ', ' ) } "
41+ joins = relation . joins ( self )
42+ wheres = relation . where_clauses
43+ groups = relation . group_clauses
44+ havings = relation . having_clauses
45+ orders = relation . order_clauses
46+ select_clause = windowed ? relation . select_clauses . map { |sc | bare_select_clause ( sc ) } . join ( ', ' ) :
47+ "SELECT #{ taken_clause if taken_only? } #{ relation . select_clauses . join ( ', ' ) } "
4348 build_query (
4449 select_clause ,
45- "FROM #{ from_clauses } " ,
50+ "FROM #{ relation . from_clauses } " ,
4651 ( locked unless locked . blank? ) ,
47- ( joins ( self ) unless joins ( self ) . blank? ) ,
48- ( "WHERE #{ where_clauses . join ( ' AND ' ) } " unless wheres . blank? ) ,
49- ( "GROUP BY #{ group_clauses . join ( ', ' ) } " unless groupings . blank? ) ,
50- ( "HAVING #{ having_clauses . join ( ' AND ' ) } " unless havings . blank? ) ,
51- ( "ORDER BY #{ order_clauses . join ( ', ' ) } " if orders . present? && !windowed ) )
52+ ( joins unless joins . blank? ) ,
53+ ( "WHERE #{ wheres . join ( ' AND ' ) } " unless wheres . blank? ) ,
54+ ( "GROUP BY #{ groups . join ( ', ' ) } " unless groups . blank? ) ,
55+ ( "HAVING #{ havings . join ( ' AND ' ) } " unless havings . blank? ) ,
56+ ( "ORDER BY #{ orders . join ( ', ' ) } " if orders . present? && !windowed ) )
5257 end
5358
5459 def select_sql_with_skipped
55- tc = taken_clause if taken . present? && !single_distinct_select?
60+ tc = taken_clause if relation . taken . present? && !single_distinct_select?
5661 build_query \
5762 "SELECT #{ tc } #{ rowtable_select_clauses . join ( ', ' ) } " ,
5863 "FROM (" ,
5964 "SELECT ROW_NUMBER() OVER (ORDER BY #{ rowtable_order_clauses . join ( ', ' ) } ) AS [rn]," ,
6065 select_sql_without_skipped ( true ) ,
6166 ") AS [_rnt]" ,
62- "WHERE [_rnt].[rn] > #{ skipped . to_i } "
67+ "WHERE [_rnt].[rn] > #{ relation . skipped . to_i } "
6368 end
6469
6570 def rowtable_select_clauses
6671 if single_distinct_select?
67- ::Array . wrap ( select_clauses . first . dup . tap do |sc |
68- sc . sub! 'DISTINCT' , "DISTINCT #{ taken_clause if taken . present? } " . strip
72+ ::Array . wrap ( relation . select_clauses . first . dup . tap do |sc |
73+ sc . sub! 'DISTINCT' , "DISTINCT #{ taken_clause if relation . taken . present? } " . strip
6974 sc . sub! table_name_from_select_clause ( sc ) , '_rnt'
7075 sc . strip!
7176 end )
72- elsif join?
77+ elsif relation . join?
7378
7479 else
75- select_clauses . map do |sc |
76- sc . gsub /\[ #{ table . name } \] \. / , '[_rnt].'
80+ relation . select_clauses . map do |sc |
81+ sc . gsub /\[ #{ relation . table . name } \] \. / , '[_rnt].'
7782 end
7883 end
7984 end
8085
8186 def rowtable_order_clauses
82- if order_clauses . present?
83- order_clauses
84- elsif join?
87+ orders = relation . order_clauses
88+ if orders . present?
89+ orders
90+ elsif relation . join?
8591 table_names_from_select_clauses . map { |tn | quote ( "#{ tn } .#{ pk_for_table ( tn ) } " ) }
8692 else
87- [ quote ( "#{ table . name } .#{ primary_key } " ) ]
93+ [ quote ( "#{ relation . table . name } .#{ relation . primary_key } " ) ]
8894 end
8995 end
9096
9197 def limited_update_conditions ( conditions , taken )
92- quoted_primary_key = engine . quote_column_name ( primary_key )
98+ quoted_primary_key = engine . quote_column_name ( relation . primary_key )
9399 conditions = " #{ conditions } " . strip
94100 build_query \
95101 "WHERE #{ quoted_primary_key } IN" ,
96- "(SELECT #{ taken_clause if taken . present? } #{ quoted_primary_key } FROM #{ engine . connection . quote_table_name ( table . name ) } #{ conditions } )"
102+ "(SELECT #{ taken_clause if relation . taken . present? } #{ quoted_primary_key } FROM #{ engine . connection . quote_table_name ( relation . table . name ) } #{ conditions } )"
97103 end
98104
99105 def quote ( value )
@@ -116,7 +122,7 @@ def table_name_from_select_clause(sc)
116122 end
117123
118124 def table_names_from_select_clauses
119- select_clauses . map { |sc | table_name_from_select_clause ( sc ) } . compact . uniq
125+ relation . select_clauses . map { |sc | table_name_from_select_clause ( sc ) } . compact . uniq
120126 end
121127
122128 end
0 commit comments