wagn 1.12.11 → 1.12.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +8 -8
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/wagn.js.coffee +1 -1
  4. data/app/controllers/admin_controller.rb +1 -1
  5. data/app/controllers/wagn_controller.rb +6 -6
  6. data/app/models/user.rb +1 -1
  7. data/lib/card.rb +1 -3
  8. data/lib/card/exceptions.rb +18 -6
  9. data/lib/card/format.rb +1 -1
  10. data/lib/card/query/card_spec.rb +393 -388
  11. data/lib/wagn/exceptions.rb +7 -6
  12. data/lib/wagn/loader.rb +2 -2
  13. data/mods/core/formats/html_format.rb +1 -1
  14. data/mods/core/sets/all/fetch.rb +3 -8
  15. data/mods/core/sets/all/name.rb +10 -10
  16. data/mods/core/sets/all/utils.rb +1 -1
  17. data/mods/standard/sets/all/account.rb +1 -1
  18. data/mods/standard/sets/right/style.rb +1 -1
  19. data/mods/standard/sets/type/file.rb +1 -1
  20. data/mods/standard/sets/type/search_type.rb +2 -2
  21. data/public/assets/{application-7cda003cf1291a165b1eac69ea3027aa.js → application-b0c6081404451e8d3ba4d60c15fcaf40.js} +10 -10
  22. data/public/assets/application-b0c6081404451e8d3ba4d60c15fcaf40.js.gz +0 -0
  23. data/public/assets/application.js +10 -10
  24. data/public/assets/application.js.gz +0 -0
  25. data/public/assets/html5shiv-printshiv-ad36fc7219f4aeaa275f9a7fe2383413.js.gz +0 -0
  26. data/public/assets/html5shiv-printshiv.js.gz +0 -0
  27. data/public/assets/manifest.yml +2 -2
  28. data/public/assets/tinymce-22b5a139d9ff7df7643afae9ce205508.js.gz +0 -0
  29. data/public/assets/tinymce.js.gz +0 -0
  30. data/spec/controllers/account_controller_spec.rb +0 -1
  31. metadata +4 -4
  32. data/public/assets/application-7cda003cf1291a165b1eac69ea3027aa.js.gz +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTNmYzI3MDdkNzE0ZmIwODFjZDgzZGJkZDQwMDFhMGM4MjBmZTUwYQ==
4
+ NWE5ZWQ5N2VkMDI0NTJiYTgwYjIwMDI5M2M5YWZhZTM4NTEzNjljOQ==
5
5
  data.tar.gz: !binary |-
6
- YTJkYzkwODU2NDViYTZiNzNhZTc4Y2U5YmEwZWZhY2M3MTk2MThhNg==
6
+ MDk2OTUxNTBiNDJhNGRmZDliNDAyYmFhMDRjNjYwMTA3ODE0ZTY2YQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZWRiZDc5MzgwOTc5ZGY5ZDllOWRiNzM0N2QxNjhiNDQ3ZjVkNmQ2NWI5NWZh
10
- MGZhMjNkMzEwNjU5NWVjZWIwN2EyNDczOTI3MTE3YTg0MGExYzlkOTE4Yzdl
11
- ZDE2NjY1MjA0YTEwMDNkOTNiYjVkZDRhYjg4ZmI4ZTkxODRkNDg=
9
+ NThjODA4OTcwOWM2ZTM5YTJjZDAxZWYyMDYxNGZmMzg4MWJlNzcyMmU3YzFm
10
+ MGQ3ZTc3NjlkYTkyNTVmYzNiMjAyODlhYTkxNDEzYTRlNzFhMzVlNTY0N2M3
11
+ MWMwNWRmNTRlMGM0MTU0ZTUwZTJhMmUxZDAxMDg2OTg5MTk5NjI=
12
12
  data.tar.gz: !binary |-
13
- OTQ4OGZmYjYyZTFiZDg3MTJkZGNjN2VkMDU1MTBkNjZmNDY5OWU4ZWM0OTIz
14
- YjEzMGQxOGI4MzM4NmQxOTI0NDcxM2Y1NzIzOTk2ODhkOTE2NzUzZTJiMGQ0
15
- ZGQ0NzE1MWM1YTM3ZTMwMzU2MTFjNWZkZTQyZjNhYjljMmQ2Mzg=
13
+ MzI3NTBlNWI4NzA4Zjg3NGY3NDMxOTJhOTBjZmI1ZGQ0MTc4NTgyZTdlOWVh
14
+ ZjE4MzYyNTcwODc2NGU3NDAzMzcwMDA1YmQ1YWEzNTE0NjQ4ZTVhNzUwZTM0
15
+ NjkzN2M2ODE3NDUwZWZkMmYyNTQwMGRiNGUxNmU0NjJkMjgxNzY=
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.12.11
1
+ 1.12.12
@@ -160,8 +160,8 @@ $(window).ready ->
160
160
  if input[1]
161
161
  $(this).notify "Wagn does not yet support multiple files in a single form."
162
162
  return false
163
- widget = input.data 'fileupload' #jQuery UI widget
164
163
 
164
+ widget = input.data 'blueimpFileupload' #jQuery UI widget
165
165
  unless widget._isXHRUpload(widget.options) # browsers that can't do ajax uploads use iframe
166
166
  $(this).find('[name=success]').val('_self') # can't do normal redirects.
167
167
  # iframe response not passed back; all responses treated as success. boo
@@ -3,7 +3,7 @@ class AdminController < CardController
3
3
  before_filter :admin_only, :except=>:setup
4
4
 
5
5
  def setup
6
- raise Wagn::Oops, "Already setup" unless Account.no_logins?
6
+ raise Card::Oops, "Already setup" unless Account.no_logins?
7
7
  if request.post?
8
8
  Wagn::Env[:recaptcha_on] = false
9
9
  handle do
@@ -131,17 +131,17 @@ class WagnController < ActionController::Base
131
131
  view = case exception
132
132
  ## arguably the view and status should be defined in the error class;
133
133
  ## some are redundantly defined in view
134
- when Wagn::PermissionDenied, Card::PermissionDenied
134
+ when Card::Oops, Card::Query
135
+ card.errors.add :exception, exception.message
136
+ # Card::Oops error messages are visible to end users and are generally not treated as bugs.
137
+ # Probably want to rename accordingly.
138
+ :errors
139
+ when Card::PermissionDenied, Wagn::PermissionDenied
135
140
  :denial
136
141
  when Wagn::NotFound, ActiveRecord::RecordNotFound, ActionController::MissingFile
137
142
  :not_found
138
143
  when Wagn::BadAddress
139
144
  :bad_address
140
- when Wagn::Oops
141
- card.errors.add :exception, exception.message
142
- # Wagn:Oops error messages are visible to end users and are generally not treated as bugs.
143
- # Probably want to rename accordingly.
144
- :errors
145
145
  else #the following indicate a code problem and therefore require full logging
146
146
  Rails.logger.info exception.backtrace*"\n"
147
147
  notify_airbrake exception if Airbrake.configuration.api_key
data/app/models/user.rb CHANGED
@@ -36,7 +36,7 @@ class User < ActiveRecord::Base
36
36
  end
37
37
 
38
38
  def send_account_info args
39
- raise Wagn::Oops, "subject and message required" unless args[:subject] && args[:message]
39
+ raise Card::Oops, "subject and message required" unless args[:subject] && args[:message]
40
40
  begin
41
41
  if password.blank?
42
42
  generate_password
data/lib/card.rb CHANGED
@@ -5,14 +5,12 @@ class Card < ActiveRecord::Base
5
5
  require_dependency 'card/constant'
6
6
  require_dependency 'card/set'
7
7
  require_dependency 'card/format'
8
+ require_dependency 'card/exceptions'
8
9
 
9
10
  extend Card::Set
10
11
  extend Card::Constant
11
12
  extend Wagn::Loader
12
13
 
13
- require_dependency 'card/exceptions'
14
- include Card::Exceptions
15
-
16
14
  has_many :revisions, :order => :id
17
15
  has_many :references_from, :class_name => :Reference, :foreign_key => :referee_id
18
16
  has_many :references_to, :class_name => :Reference, :foreign_key => :referer_id
@@ -1,7 +1,16 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- module Card::Exceptions
4
- class PermissionDenied < Wagn::PermissionDenied
3
+ class Card
4
+ class Error < StandardError #code problem
5
+ end
6
+
7
+ class Oops < Error # wagneer problem
8
+ end
9
+
10
+ class BadQuery < Error
11
+ end
12
+
13
+ class PermissionDenied < Error
5
14
  attr_reader :card
6
15
 
7
16
  def initialize card
@@ -10,18 +19,21 @@ module Card::Exceptions
10
19
  end
11
20
 
12
21
  def build_message
13
- "for card #{@card.name}: #{@card.errors[:permission_denied]}"
22
+ if msg = @card.errors[:permission_denied]
23
+ "for card #{@card.name}: #{msg}"
24
+ else
25
+ super
26
+ end
14
27
  end
15
28
  end
16
29
 
17
30
  class Abort < Exception
18
31
  attr_reader :status
32
+
19
33
  def initialize status=:failure, msg=''
20
34
  @status = status
21
35
  super msg
22
36
  end
23
- # def backtrace
24
- # ["\n( card action gently canceled )\n"]
25
- # end
37
+
26
38
  end
27
39
  end
data/lib/card/format.rb CHANGED
@@ -281,7 +281,7 @@ class Card
281
281
  when nil ; {}
282
282
  when Hash ; a.clone
283
283
  when Array ; a[0].merge a[1]
284
- else ; raise Wagn::Error, "bad render args: #{a}"
284
+ else ; raise Card::Error, "bad render args: #{a}"
285
285
  end
286
286
 
287
287
  view_key = canonicalize_view view
@@ -1,517 +1,522 @@
1
1
 
2
- class Card::Query
3
- class CardSpec < Spec
2
+ class Card
3
+ class Query
4
+ class CardSpec < Spec
4
5
 
5
- ATTRIBUTES = {
6
- :basic => %w{ name type_id content id key updater_id left_id right_id creator_id updater_id codename },
7
- :relational => %w{ type part left right editor_of edited_by last_editor_of last_edited_by creator_of created_by member_of member },
8
- :plus_relational => %w{ plus left_plus right_plus },
9
- :ref_relational => %w{ refer_to referred_to_by link_to linked_to_by include included_by },
10
- :conjunction => %w{ and or all any },
11
- :special => %w{ found_by not sort match complete extension_type },
12
- :ignore => %w{ prepend append view params vars size }
13
- }.inject({}) {|h,pair| pair[1].each {|v| h[v.to_sym]=pair[0] }; h }
6
+ ATTRIBUTES = {
7
+ :basic => %w{ name type_id content id key updater_id left_id right_id creator_id updater_id codename },
8
+ :relational => %w{ type part left right editor_of edited_by last_editor_of last_edited_by creator_of created_by member_of member },
9
+ :plus_relational => %w{ plus left_plus right_plus },
10
+ :ref_relational => %w{ refer_to referred_to_by link_to linked_to_by include included_by },
11
+ :conjunction => %w{ and or all any },
12
+ :special => %w{ found_by not sort match complete extension_type },
13
+ :ignore => %w{ prepend append view params vars size }
14
+ }.inject({}) {|h,pair| pair[1].each {|v| h[v.to_sym]=pair[0] }; h }
14
15
 
15
- DEFAULT_ORDER_DIRS = { :update => "desc", :relevance => "desc" }
16
- CONJUNCTIONS = { :any=>:or, :in=>:or, :or=>:or, :all=>:and, :and=>:and }
16
+ DEFAULT_ORDER_DIRS = { :update => "desc", :relevance => "desc" }
17
+ CONJUNCTIONS = { :any=>:or, :in=>:or, :or=>:or, :all=>:and, :and=>:and }
17
18
 
18
- attr_reader :sql, :query, :rawspec, :selfname
19
- attr_accessor :joins
19
+ attr_reader :sql, :query, :rawspec, :selfname
20
+ attr_accessor :joins
20
21
 
21
- class << self
22
- def build query
23
- cardspec = self.new query
24
- cardspec.merge cardspec.rawspec
22
+ class << self
23
+ def build query
24
+ cardspec = self.new query
25
+ cardspec.merge cardspec.rawspec
26
+ end
25
27
  end
26
- end
27
28
 
28
- def initialize query
29
- @mods = MODIFIERS.clone
30
- @spec, @joins = {}, {}
31
- @selfname, @parent = '', nil
32
- @sql = SqlStatement.new
29
+ def initialize query
30
+ @mods = MODIFIERS.clone
31
+ @spec, @joins = {}, {}
32
+ @selfname, @parent = '', nil
33
+ @sql = SqlStatement.new
33
34
 
34
- @query = query.clone
35
- @query.merge! @query.delete(:params) if @query[:params]
36
- @vars = @query.delete(:vars) || {}
37
- @vars.symbolize_keys!
38
- @query = clean(@query)
39
- @rawspec = @query.deep_clone
35
+ @query = query.clone
36
+ @query.merge! @query.delete(:params) if @query[:params]
37
+ @vars = @query.delete(:vars) || {}
38
+ @vars.symbolize_keys!
39
+ @query = clean(@query)
40
+ @rawspec = @query.deep_clone
40
41
 
41
- self
42
- end
42
+ self
43
+ end
43
44
 
44
45
 
45
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
- # QUERY CLEANING - strip strings, absolutize names, interpret contextual parameters
47
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
+ # QUERY CLEANING - strip strings, absolutize names, interpret contextual parameters
48
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48
49
 
49
50
 
50
- def clean query
51
- query = query.symbolize_keys
52
- if s = query.delete(:context) then @selfname = s end
53
- if p = query.delete(:_parent) then @parent = p end
54
- query.each do |key,val|
55
- query[key] = clean_val val
51
+ def clean query
52
+ query = query.symbolize_keys
53
+ if s = query.delete(:context) then @selfname = s end
54
+ if p = query.delete(:_parent) then @parent = p end
55
+ query.each do |key,val|
56
+ query[key] = clean_val val
57
+ end
58
+ query
56
59
  end
57
- query
58
- end
59
60
 
60
- def clean_val val
61
- case val
62
- when String
63
- if val =~ /^\$(\w+)$/
64
- val = @vars[$1.to_sym].to_s.strip
61
+ def clean_val val
62
+ case val
63
+ when String
64
+ if val =~ /^\$(\w+)$/
65
+ val = @vars[$1.to_sym].to_s.strip
66
+ end
67
+ absolute_name val
68
+ when Card::Name ; clean_val val.s
69
+ when Hash ; clean val
70
+ when Array ; val.map { |v| clean_val v }
71
+ when Integer, Float, Symbol ; val
72
+ else ; raise BadQuery, "unknown WQL value type: #{val.class}"
65
73
  end
66
- absolute_name val
67
- when Card::Name ; clean_val val.s
68
- when Hash ; clean val
69
- when Array ; val.map { |v| clean_val v }
70
- when Integer, Float, Symbol ; val
71
- else ; raise "unknown WQL value type: #{val.class}"
72
74
  end
73
- end
74
75
 
75
- def root
76
- @parent ? @parent.root : self
77
- end
76
+ def root
77
+ @parent ? @parent.root : self
78
+ end
78
79
 
79
- def absolute_name name
80
- name =~ /\b_/ ? name.to_name.to_absolute(root.selfname) : name
81
- end
80
+ def absolute_name name
81
+ name =~ /\b_/ ? name.to_name.to_absolute(root.selfname) : name
82
+ end
82
83
 
83
84
 
84
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85
- # MERGE - reduce query to basic attributes and SQL subconditions
86
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
86
+ # MERGE - reduce query to basic attributes and SQL subconditions
87
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87
88
 
88
89
 
89
- def merge s
90
- s = hashify s
91
- translate_to_attributes s
92
- ready_to_sqlize s
93
- @spec.merge! s
94
- self
95
- end
90
+ def merge s
91
+ s = hashify s
92
+ translate_to_attributes s
93
+ ready_to_sqlize s
94
+ @spec.merge! s
95
+ self
96
+ end
96
97
 
97
- def hashify s
98
- case s
99
- when String; { :key => s.to_name.key }
100
- when Integer; { :id => s }
101
- when Hash; s
102
- else raise("Invalid cardspec args #{s.inspect}")
98
+ def hashify s
99
+ case s
100
+ when String; { :key => s.to_name.key }
101
+ when Integer; { :id => s }
102
+ when Hash; s
103
+ else; raise BadQueyr, "Invalid cardspec args #{s.inspect}"
104
+ end
103
105
  end
104
- end
105
106
 
106
- def translate_to_attributes spec
107
- content = nil
108
- spec.each do |key,val|
109
- if key == :_parent
110
- @parent = spec.delete(key)
111
- elsif OPERATORS.has_key?(key.to_s) && !ATTRIBUTES[key]
112
- spec.delete(key)
113
- content = [key,val]
114
- elsif MODIFIERS.has_key?(key)
115
- next if spec[key].is_a? Hash
116
- val = spec.delete key
117
- @mods[key] = Array === val ? val : val.to_s
107
+ def translate_to_attributes spec
108
+ content = nil
109
+ spec.each do |key,val|
110
+ if key == :_parent
111
+ @parent = spec.delete(key)
112
+ elsif OPERATORS.has_key?(key.to_s) && !ATTRIBUTES[key]
113
+ spec.delete(key)
114
+ content = [key,val]
115
+ elsif MODIFIERS.has_key?(key)
116
+ next if spec[key].is_a? Hash
117
+ val = spec.delete key
118
+ @mods[key] = Array === val ? val : val.to_s
119
+ end
118
120
  end
121
+ spec[:content] = content if content
119
122
  end
120
- spec[:content] = content if content
121
- end
122
123
 
123
124
 
124
- def ready_to_sqlize spec
125
- spec.each do |key,val|
126
- keyroot = field_root(key).to_sym
127
- if keyroot==:cond # internal SQL cond (already ready)
128
- elsif ATTRIBUTES[keyroot] == :basic # sqlize knows how to handle these keys; just process value
129
- spec[key] = ValueSpec.new(val, self)
130
- else # keys need additional processing
131
- val = spec.delete key
132
- is_array = Array===val
133
- case ATTRIBUTES[keyroot]
134
- when :ignore #noop
135
- when :relational, :special, :conjunction ; relate is_array, keyroot, val, :send
136
- when :ref_relational ; relate is_array, keyroot, val, :refspec
137
- when :plus_relational
138
- # Arrays can have multiple interpretations for these, so we have to look closer...
139
- subcond = is_array && ( Array===val.first || conjunction(val.first) )
125
+ def ready_to_sqlize spec
126
+ spec.each do |key,val|
127
+ keyroot = field_root(key).to_sym
128
+ if keyroot==:cond # internal SQL cond (already ready)
129
+ elsif ATTRIBUTES[keyroot] == :basic # sqlize knows how to handle these keys; just process value
130
+ spec[key] = ValueSpec.new(val, self)
131
+ else # keys need additional processing
132
+ val = spec.delete key
133
+ is_array = Array===val
134
+ case ATTRIBUTES[keyroot]
135
+ when :ignore #noop
136
+ when :relational, :special, :conjunction ; relate is_array, keyroot, val, :send
137
+ when :ref_relational ; relate is_array, keyroot, val, :refspec
138
+ when :plus_relational
139
+ # Arrays can have multiple interpretations for these, so we have to look closer...
140
+ subcond = is_array && ( Array===val.first || conjunction(val.first) )
140
141
 
141
- relate subcond, keyroot, val, :send
142
- else ; raise "Invalid attribute #{key}"
142
+ relate subcond, keyroot, val, :send
143
+ else ; raise BadQuery, "Invalid attribute #{key}"
144
+ end
143
145
  end
144
146
  end
145
- end
146
147
 
147
- end
148
+ end
148
149
 
149
- def relate subcond, key, val, method
150
- if subcond
151
- conj = conjunction( val.first ) ? conjunction( val.shift ) : :and
152
- if conj == current_conjunction # same conjunction as container, no need for subcondition
153
- val.each { |v| send method, key, v }
150
+ def relate subcond, key, val, method
151
+ if subcond
152
+ conj = conjunction( val.first ) ? conjunction( val.shift ) : :and
153
+ if conj == current_conjunction # same conjunction as container, no need for subcondition
154
+ val.each { |v| send method, key, v }
155
+ else
156
+ send conj, val.inject({}) { |h,v| h[field key] = v; h } # subcondition
157
+ end
154
158
  else
155
- send conj, val.inject({}) { |h,v| h[field key] = v; h } # subcondition
159
+ send method, key, val
156
160
  end
157
- else
158
- send method, key, val
159
161
  end
160
- end
161
162
 
162
- def refspec key, cardspec
163
- if cardspec == '_none'
164
- key = :link_to_missing
165
- cardspec = 'blank'
163
+ def refspec key, cardspec
164
+ if cardspec == '_none'
165
+ key = :link_to_missing
166
+ cardspec = 'blank'
167
+ end
168
+ cardspec = CardSpec.build(:return=>'id', :_parent=>self).merge(cardspec)
169
+ merge field(:id) => ValueSpec.new(['in',RefSpec.new( key, cardspec )], self)
166
170
  end
167
- cardspec = CardSpec.build(:return=>'id', :_parent=>self).merge(cardspec)
168
- merge field(:id) => ValueSpec.new(['in',RefSpec.new( key, cardspec )], self)
169
- end
170
171
 
171
172
 
172
- def conjunction val
173
- if [String, Symbol].member? val.class
174
- CONJUNCTIONS[val.to_sym]
173
+ def conjunction val
174
+ if [String, Symbol].member? val.class
175
+ CONJUNCTIONS[val.to_sym]
176
+ end
175
177
  end
176
- end
177
178
 
178
179
 
179
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180
- # ATTRIBUTE METHODS - called during merge
181
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181
+ # ATTRIBUTE METHODS - called during merge
182
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182
183
 
183
184
 
184
- #~~~~~~ RELATIONAL
185
+ #~~~~~~ RELATIONAL
185
186
 
186
- def type val
187
- merge field(:type_id) => id_or_subspec(val)
188
- end
187
+ def type val
188
+ merge field(:type_id) => id_or_subspec(val)
189
+ end
189
190
 
190
- def part val
191
- right = Integer===val ? val : val.clone
192
- subcondition :left=>val, :right=>right, :conj=>:or
193
- end
191
+ def part val
192
+ right = Integer===val ? val : val.clone
193
+ subcondition :left=>val, :right=>right, :conj=>:or
194
+ end
194
195
 
195
- def left val
196
- merge field(:left_id) => id_or_subspec(val)
197
- end
196
+ def left val
197
+ merge field(:left_id) => id_or_subspec(val)
198
+ end
198
199
 
199
- def right val
200
- merge field(:right_id) => id_or_subspec(val)
201
- end
200
+ def right val
201
+ merge field(:right_id) => id_or_subspec(val)
202
+ end
202
203
 
203
- def editor_of val
204
- revision_spec :creator_id, :card_id, val
205
- end
204
+ def editor_of val
205
+ revision_spec :creator_id, :card_id, val
206
+ end
206
207
 
207
- def edited_by val
208
- revision_spec :card_id, :creator_id, val
209
- end
208
+ def edited_by val
209
+ revision_spec :card_id, :creator_id, val
210
+ end
210
211
 
211
- def last_editor_of val
212
- merge field(:id) => subspec(val, :return=>'updater_id')
213
- end
212
+ def last_editor_of val
213
+ merge field(:id) => subspec(val, :return=>'updater_id')
214
+ end
214
215
 
215
- def last_edited_by val
216
- merge field(:updater_id) => id_or_subspec(val)
217
- end
216
+ def last_edited_by val
217
+ merge field(:updater_id) => id_or_subspec(val)
218
+ end
218
219
 
219
- def creator_of val
220
- merge field(:id)=>subspec(val,:return=>'creator_id')
221
- end
220
+ def creator_of val
221
+ merge field(:id)=>subspec(val,:return=>'creator_id')
222
+ end
222
223
 
223
- def created_by val
224
- merge field(:creator_id) => id_or_subspec(val)
225
- end
224
+ def created_by val
225
+ merge field(:creator_id) => id_or_subspec(val)
226
+ end
226
227
 
227
- def member_of val
228
- merge field(:right_plus) => [Card::RolesID, {:refer_to=>val}]
229
- end
228
+ def member_of val
229
+ merge field(:right_plus) => [RolesID, {:refer_to=>val}]
230
+ end
230
231
 
231
- def member val
232
- merge field(:referred_to_by) => {:left=>val, :right=>Card::RolesID }
233
- end
232
+ def member val
233
+ merge field(:referred_to_by) => {:left=>val, :right=>RolesID }
234
+ end
234
235
 
235
236
 
236
- #~~~~~~ PLUS RELATIONAL
237
+ #~~~~~~ PLUS RELATIONAL
237
238
 
238
- def left_plus(val)
239
- part_spec, junc_spec = val.is_a?(Array) ? val : [ val, {} ]
240
- merge( field(:id) => subspec(junc_spec, :return=>'right_id', :left =>part_spec))
241
- end
239
+ def left_plus(val)
240
+ part_spec, junc_spec = val.is_a?(Array) ? val : [ val, {} ]
241
+ merge( field(:id) => subspec(junc_spec, :return=>'right_id', :left =>part_spec))
242
+ end
242
243
 
243
- def right_plus(val)
244
- part_spec, junc_spec = val.is_a?(Array) ? val : [ val, {} ]
245
- merge( field(:id) => subspec(junc_spec, :return=>'left_id', :right=> part_spec ))
246
- end
244
+ def right_plus(val)
245
+ part_spec, junc_spec = val.is_a?(Array) ? val : [ val, {} ]
246
+ merge( field(:id) => subspec(junc_spec, :return=>'left_id', :right=> part_spec ))
247
+ end
247
248
 
248
- def plus(val)
249
- subcondition( { :left_plus=>val, :right_plus=>val.deep_clone }, :conj=>:or )
250
- end
249
+ def plus(val)
250
+ subcondition( { :left_plus=>val, :right_plus=>val.deep_clone }, :conj=>:or )
251
+ end
251
252
 
252
253
 
253
- #~~~~~~~ CONJUNCTION
254
+ #~~~~~~~ CONJUNCTION
254
255
 
255
- def and val
256
- subcondition val
257
- end
258
- alias :all :and
256
+ def and val
257
+ subcondition val
258
+ end
259
+ alias :all :and
259
260
 
260
- def or val
261
- subcondition val, :conj=>:or
262
- end
263
- alias :any :or
261
+ def or val
262
+ subcondition val, :conj=>:or
263
+ end
264
+ alias :any :or
264
265
 
265
- #~~~~~~ SPECIAL
266
+ #~~~~~~ SPECIAL
266
267
 
267
268
 
268
- def found_by val
269
+ def found_by val
269
270
 
270
- cards = if Hash===val
271
- Card::Query.new(val).run
272
- else
273
- Array.wrap(val).map do |v|
274
- Card.fetch absolute_name(val), :new=>{}
271
+ cards = if Hash===val
272
+ Query.new(val).run
273
+ else
274
+ Array.wrap(val).map do |v|
275
+ Card.fetch absolute_name(val), :new=>{}
276
+ end
275
277
  end
276
- end
277
278
 
278
- cards.each do |c|
279
- raise %{"found_by" value needs to be valid Search card #{c.inspect}} unless c && [Card::SearchTypeID,Card::SetID].include?(c.type_id)
280
- found_by_spec = CardSpec.new(c.get_spec).rawspec
281
- merge(field(:id) => subspec(found_by_spec))
279
+ cards.each do |c|
280
+ unless c && [SearchTypeID,SetID].include?(c.type_id)
281
+ raise BadQuery, %{"found_by" value needs to be valid Search card}
282
+ end
283
+ found_by_spec = CardSpec.new(c.get_spec).rawspec
284
+ merge(field(:id) => subspec(found_by_spec))
285
+ end
282
286
  end
283
- end
284
287
 
285
- def not val
286
- merge field(:id) => subspec( val, {:return=>'id'}, negate=true )
287
- end
288
+ def not val
289
+ merge field(:id) => subspec( val, {:return=>'id'}, negate=true )
290
+ end
288
291
 
289
- def sort val
290
- return nil if @parent
291
- val[:return] = val[:return] ? safe_sql(val[:return]) : 'content'
292
- @mods[:sort] = "t_sort.#{val[:return]}"
293
- item = val.delete(:item) || 'left'
294
-
295
- if val[:return] == 'count'
296
- cs_args = { :return=>'count', :group=>'sort_join_field' }
297
- @mods[:sort] = "coalesce(#{@mods[:sort]},0)"
298
- case item
299
- when 'referred_to'
300
- join_field = 'id'
301
- cs = CardSpec.build cs_args.merge( field(:cond)=>SqlCond.new("referer_id in #{CardSpec.build( val.merge(:return=>'id')).to_sql}") )
302
- cs.add_join :wr, :card_references, :id, :referee_id
303
- else; raise "count with item: #{item} not yet implemented"
304
- end
305
- else
306
- join_field = case item
307
- when 'left' ; 'left_id'
308
- when 'right' ; 'right_id'
309
- else ; raise "sort item: #{item} not yet implemented"
292
+ def sort val
293
+ return nil if @parent
294
+ val[:return] = val[:return] ? safe_sql(val[:return]) : 'content'
295
+ @mods[:sort] = "t_sort.#{val[:return]}"
296
+ item = val.delete(:item) || 'left'
297
+
298
+ if val[:return] == 'count'
299
+ cs_args = { :return=>'count', :group=>'sort_join_field' }
300
+ @mods[:sort] = "coalesce(#{@mods[:sort]},0)"
301
+ case item
302
+ when 'referred_to'
303
+ join_field = 'id'
304
+ cs = CardSpec.build cs_args.merge( field(:cond)=>SqlCond.new("referer_id in #{CardSpec.build( val.merge(:return=>'id')).to_sql}") )
305
+ cs.add_join :wr, :card_references, :id, :referee_id
306
+ else
307
+ raise BadQuery, "count with item: #{item} not yet implemented"
308
+ end
309
+ else
310
+ join_field = case item
311
+ when 'left' ; 'left_id'
312
+ when 'right' ; 'right_id'
313
+ else ; raise BadQuery, "sort item: #{item} not yet implemented"
314
+ end
315
+ cs = CardSpec.build(val)
310
316
  end
311
- cs = CardSpec.build(val)
312
- end
313
317
 
314
- cs.sql.fields << "#{cs.table_alias}.#{join_field} as sort_join_field"
315
- add_join :sort, cs.to_sql, :id, :sort_join_field, :side=>'LEFT'
316
- end
318
+ cs.sql.fields << "#{cs.table_alias}.#{join_field} as sort_join_field"
319
+ add_join :sort, cs.to_sql, :id, :sort_join_field, :side=>'LEFT'
320
+ end
317
321
 
318
- def match(val)
319
- cxn, val = match_prep val
320
- val.gsub! /[^#{Card::Name::OK4KEY_RE}]+/, ' '
321
- return nil if val.strip.empty?
322
+ def match(val)
323
+ cxn, val = match_prep val
324
+ val.gsub! /[^#{Card::Name::OK4KEY_RE}]+/, ' '
325
+ return nil if val.strip.empty?
322
326
 
323
327
 
324
- cond = begin
325
- join_alias = add_revision_join
326
- # FIXME: OMFG this is ugly
327
- val_list = val.split(/\s+/).map do |v|
328
- name_or_content = ["replace(#{self.table_alias}.name,'+',' ')","#{join_alias}.content"].map do |field|
329
- %{#{field} #{ cxn.match quote("[[:<:]]#{v}[[:>:]]") }}
328
+ cond = begin
329
+ join_alias = add_revision_join
330
+ # FIXME: OMFG this is ugly
331
+ val_list = val.split(/\s+/).map do |v|
332
+ name_or_content = ["replace(#{self.table_alias}.name,'+',' ')","#{join_alias}.content"].map do |field|
333
+ %{#{field} #{ cxn.match quote("[[:<:]]#{v}[[:>:]]") }}
334
+ end
335
+ "(#{name_or_content.join ' OR '})"
330
336
  end
331
- "(#{name_or_content.join ' OR '})"
337
+ "(#{val_list.join ' AND '})"
332
338
  end
333
- "(#{val_list.join ' AND '})"
334
- end
335
339
 
336
- merge field(:cond)=>SqlCond.new(cond)
337
- end
340
+ merge field(:cond)=>SqlCond.new(cond)
341
+ end
338
342
 
339
343
 
340
- def complete(val)
341
- no_plus_card = (val=~/\+/ ? '' : "and right_id is null") #FIXME -- this should really be more nuanced -- it breaks down after one plus
342
- merge field(:cond) => SqlCond.new(" lower(name) LIKE lower(#{quote(val.to_s+'%')}) #{no_plus_card}")
343
- end
344
+ def complete(val)
345
+ no_plus_card = (val=~/\+/ ? '' : "and right_id is null") #FIXME -- this should really be more nuanced -- it breaks down after one plus
346
+ merge field(:cond) => SqlCond.new(" lower(name) LIKE lower(#{quote(val.to_s+'%')}) #{no_plus_card}")
347
+ end
344
348
 
345
- def extension_type val
346
- # DEPRECATED!!!
347
- add_join :usr, :users, :id, :card_id
348
- end
349
+ def extension_type val
350
+ # DEPRECATED!!!
351
+ add_join :usr, :users, :id, :card_id
352
+ end
349
353
 
350
354
 
351
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
352
- # ATTRIBUTE METHOD HELPERS - called by attribute methods above
353
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
356
+ # ATTRIBUTE METHOD HELPERS - called by attribute methods above
357
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
354
358
 
355
359
 
356
- def table_alias
357
- case
358
- when @mods[:return]=='condition'
359
- @parent ? @parent.table_alias : "t"
360
- when @parent
361
- @parent.table_alias + "x"
362
- else
363
- "t"
360
+ def table_alias
361
+ case
362
+ when @mods[:return]=='condition'
363
+ @parent ? @parent.table_alias : "t"
364
+ when @parent
365
+ @parent.table_alias + "x"
366
+ else
367
+ "t"
368
+ end
364
369
  end
365
- end
366
370
 
367
- def add_join(name, table, cardfield, otherfield, opts={})
368
- join_alias = "#{table_alias}_#{name}"
369
- @joins[join_alias] = "#{opts[:side]} JOIN #{table} AS #{join_alias} ON #{table_alias}.#{cardfield} = #{join_alias}.#{otherfield}"
370
- join_alias
371
- end
371
+ def add_join(name, table, cardfield, otherfield, opts={})
372
+ join_alias = "#{table_alias}_#{name}"
373
+ @joins[join_alias] = "#{opts[:side]} JOIN #{table} AS #{join_alias} ON #{table_alias}.#{cardfield} = #{join_alias}.#{otherfield}"
374
+ join_alias
375
+ end
372
376
 
373
- def add_revision_join
374
- add_join(:rev, :card_revisions, :current_revision_id, :id)
375
- end
377
+ def add_revision_join
378
+ add_join(:rev, :card_revisions, :current_revision_id, :id)
379
+ end
376
380
 
377
- def field name
378
- @fields ||= {}
379
- @fields[name] ||= 0
380
- @fields[name] += 1
381
- "#{ name }:#{ @fields[name] }"
382
- end
381
+ def field name
382
+ @fields ||= {}
383
+ @fields[name] ||= 0
384
+ @fields[name] += 1
385
+ "#{ name }:#{ @fields[name] }"
386
+ end
383
387
 
384
- def field_root key
385
- key.to_s.gsub /\:\d+/, ''
386
- end
388
+ def field_root key
389
+ key.to_s.gsub /\:\d+/, ''
390
+ end
387
391
 
388
- def subcondition(val, args={})
389
- args = { :return=>:condition, :_parent=>self }.merge(args)
390
- cardspec = CardSpec.build( args )
391
- merge field(:cond) => cardspec.merge(val)
392
- self.joins.merge! cardspec.joins
393
- self.sql.relevance_fields += cardspec.sql.relevance_fields
394
- end
392
+ def subcondition(val, args={})
393
+ args = { :return=>:condition, :_parent=>self }.merge(args)
394
+ cardspec = CardSpec.build( args )
395
+ merge field(:cond) => cardspec.merge(val)
396
+ self.joins.merge! cardspec.joins
397
+ self.sql.relevance_fields += cardspec.sql.relevance_fields
398
+ end
395
399
 
396
400
 
397
- def revision_spec(field, linkfield, val)
398
- card_select = CardSpec.build(:_parent=>self, :return=>'id').merge(val).to_sql
399
- add_join :ed, "(select distinct #{field} from card_revisions where #{linkfield} in #{card_select})", :id, field
400
- end
401
+ def revision_spec(field, linkfield, val)
402
+ card_select = CardSpec.build(:_parent=>self, :return=>'id').merge(val).to_sql
403
+ add_join :ed, "(select distinct #{field} from card_revisions where #{linkfield} in #{card_select})", :id, field
404
+ end
401
405
 
402
406
 
403
- def subspec(spec, additions={ :return=>'id'}, negate=false)
404
- additions = additions.merge(:_parent=>self)
405
- operator = negate ? 'not in' : 'in'
406
- ValueSpec.new([operator,CardSpec.build(additions).merge(spec)], self)
407
- end
407
+ def subspec(spec, additions={ :return=>'id'}, negate=false)
408
+ additions = additions.merge(:_parent=>self)
409
+ operator = negate ? 'not in' : 'in'
410
+ ValueSpec.new([operator,CardSpec.build(additions).merge(spec)], self)
411
+ end
408
412
 
409
- def id_or_subspec spec
410
- id = case spec
411
- when Integer ; spec
412
- when String ; Card.fetch_id(spec)
413
- end
414
- id or subspec spec
415
- end
413
+ def id_or_subspec spec
414
+ id = case spec
415
+ when Integer ; spec
416
+ when String ; Card.fetch_id(spec)
417
+ end
418
+ id or subspec spec
419
+ end
416
420
 
417
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
418
- # SQL GENERATION - translate merged hash into complete SQL statement.
419
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
422
+ # SQL GENERATION - translate merged hash into complete SQL statement.
423
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
420
424
 
421
425
 
422
- def to_sql *args
423
- sql.conditions << basic_conditions
426
+ def to_sql *args
427
+ sql.conditions << basic_conditions
424
428
 
425
- return "(" + sql.conditions.last + ")" if @mods[:return]=='condition'
429
+ return "(" + sql.conditions.last + ")" if @mods[:return]=='condition'
426
430
 
427
- if pconds = permission_conditions
428
- sql.conditions << pconds
429
- end
431
+ if pconds = permission_conditions
432
+ sql.conditions << pconds
433
+ end
430
434
 
431
- sql.fields.unshift fields_to_sql
432
- sql.order = sort_to_sql # has side effects!
433
- sql.tables = "cards #{table_alias}"
434
- sql.joins += @joins.values
435
+ sql.fields.unshift fields_to_sql
436
+ sql.order = sort_to_sql # has side effects!
437
+ sql.tables = "cards #{table_alias}"
438
+ sql.joins += @joins.values
435
439
 
436
- sql.conditions << "#{table_alias}.trash is false"
440
+ sql.conditions << "#{table_alias}.trash is false"
437
441
 
438
- unless @parent or @mods[:return]=='count'
439
- sql.group = "GROUP BY #{safe_sql(@mods[:group])}" if !@mods[:group].blank?
440
- if @mods[:limit].to_i > 0
441
- sql.limit = "LIMIT #{ @mods[:limit ].to_i }"
442
- sql.offset = "OFFSET #{ @mods[:offset].to_i }" if !@mods[:offset].blank?
442
+ unless @parent or @mods[:return]=='count'
443
+ sql.group = "GROUP BY #{safe_sql(@mods[:group])}" if !@mods[:group].blank?
444
+ if @mods[:limit].to_i > 0
445
+ sql.limit = "LIMIT #{ @mods[:limit ].to_i }"
446
+ sql.offset = "OFFSET #{ @mods[:offset].to_i }" if !@mods[:offset].blank?
447
+ end
443
448
  end
444
- end
445
449
 
446
- sql.to_s
447
- end
450
+ sql.to_s
451
+ end
448
452
 
449
- def basic_conditions
450
- @spec.map { |key, val| val.to_sql field_root(key) }.join " #{ current_conjunction } "
451
- end
453
+ def basic_conditions
454
+ @spec.map { |key, val| val.to_sql field_root(key) }.join " #{ current_conjunction } "
455
+ end
452
456
 
453
- def current_conjunction
454
- @mods[:conj].blank? ? :and : @mods[:conj]
455
- end
457
+ def current_conjunction
458
+ @mods[:conj].blank? ? :and : @mods[:conj]
459
+ end
456
460
 
457
- def permission_conditions
458
- unless Account.always_ok? #or ( Card::Query.root_perms_only && !root? )
459
- read_rules = Account.as_card.read_rules
460
- read_rule_list = read_rules.nil? ? 1 : read_rules.join(',')
461
- "(#{table_alias}.read_rule_id IN (#{ read_rule_list }))"
462
- end
463
- end
461
+ def permission_conditions
462
+ unless Account.always_ok? #or ( Card::Query.root_perms_only && !root? )
463
+ read_rules = Account.as_card.read_rules
464
+ read_rule_list = read_rules.nil? ? 1 : read_rules.join(',')
465
+ "(#{table_alias}.read_rule_id IN (#{ read_rule_list }))"
466
+ end
467
+ end
464
468
 
465
- def fields_to_sql
466
- field = @mods[:return]
467
- case (field.blank? ? :card : field.to_sym)
468
- when :raw; "#{table_alias}.*"
469
- when :card; "#{table_alias}.name"
470
- when :count; "coalesce(count(*),0) as count"
471
- when :content
472
- join_alias = add_revision_join
473
- "#{join_alias}.content"
474
- else
475
- ATTRIBUTES[field.to_sym]==:basic ? "#{table_alias}.#{field}" : safe_sql(field)
469
+ def fields_to_sql
470
+ field = @mods[:return]
471
+ case (field.blank? ? :card : field.to_sym)
472
+ when :raw; "#{table_alias}.*"
473
+ when :card; "#{table_alias}.name"
474
+ when :count; "coalesce(count(*),0) as count"
475
+ when :content
476
+ join_alias = add_revision_join
477
+ "#{join_alias}.content"
478
+ else
479
+ ATTRIBUTES[field.to_sym]==:basic ? "#{table_alias}.#{field}" : safe_sql(field)
480
+ end
476
481
  end
477
- end
478
482
 
479
- def sort_to_sql
480
- #fail "order_key = #{@mods[:sort]}, class = #{order_key.class}"
483
+ def sort_to_sql
484
+ #fail "order_key = #{@mods[:sort]}, class = #{order_key.class}"
481
485
 
482
- return nil if @parent or @mods[:return]=='count' #FIXME - extend to all root-only clauses
483
- order_key ||= @mods[:sort].blank? ? "update" : @mods[:sort]
486
+ return nil if @parent or @mods[:return]=='count' #FIXME - extend to all root-only clauses
487
+ order_key ||= @mods[:sort].blank? ? "update" : @mods[:sort]
484
488
 
485
- order_directives = [order_key].flatten.map do |key|
486
- dir = @mods[:dir].blank? ? (DEFAULT_ORDER_DIRS[key.to_sym]||'asc') : safe_sql(@mods[:dir]) #wonky
487
- sort_field key, @mods[:sort_as], dir
488
- end.join ', '
489
- "ORDER BY #{order_directives}"
489
+ order_directives = [order_key].flatten.map do |key|
490
+ dir = @mods[:dir].blank? ? (DEFAULT_ORDER_DIRS[key.to_sym]||'asc') : safe_sql(@mods[:dir]) #wonky
491
+ sort_field key, @mods[:sort_as], dir
492
+ end.join ', '
493
+ "ORDER BY #{order_directives}"
490
494
 
491
- end
495
+ end
492
496
 
493
- def sort_field key, as, dir
494
- order_field = case key
495
- when "id"; "#{table_alias}.id"
496
- when "update"; "#{table_alias}.updated_at"
497
- when "create"; "#{table_alias}.created_at"
498
- when /^(name|alpha)$/; "LOWER( #{table_alias}.key )"
499
- when 'content'
500
- join_alias = add_revision_join
501
- "lower(#{join_alias}.content)"
502
- when "relevance"
503
- if !sql.relevance_fields.empty?
504
- sql.fields << sql.relevance_fields
505
- "name_rank desc, content_rank"
497
+ def sort_field key, as, dir
498
+ order_field = case key
499
+ when "id"; "#{table_alias}.id"
500
+ when "update"; "#{table_alias}.updated_at"
501
+ when "create"; "#{table_alias}.created_at"
502
+ when /^(name|alpha)$/; "LOWER( #{table_alias}.key )"
503
+ when 'content'
504
+ join_alias = add_revision_join
505
+ "lower(#{join_alias}.content)"
506
+ when "relevance"
507
+ if !sql.relevance_fields.empty?
508
+ sql.fields << sql.relevance_fields
509
+ "name_rank desc, content_rank"
510
+ else
511
+ "#{table_alias}.updated_at"
512
+ end
506
513
  else
507
- "#{table_alias}.updated_at"
514
+ safe_sql(key)
508
515
  end
509
- else
510
- safe_sql(key)
511
- end
512
- order_field = "CAST(#{order_field} AS #{cast_type(as)})" if as
513
- "#{order_field} #{dir}"
516
+ order_field = "CAST(#{order_field} AS #{cast_type(as)})" if as
517
+ "#{order_field} #{dir}"
514
518
 
519
+ end
515
520
  end
516
521
  end
517
522
  end