nobrainer 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/no_brainer/config.rb +42 -16
  3. data/lib/no_brainer/connection.rb +1 -0
  4. data/lib/no_brainer/connection_manager.rb +1 -1
  5. data/lib/no_brainer/criteria.rb +1 -1
  6. data/lib/no_brainer/criteria/aggregate.rb +8 -5
  7. data/lib/no_brainer/criteria/core.rb +8 -7
  8. data/lib/no_brainer/criteria/count.rb +1 -1
  9. data/lib/no_brainer/criteria/delete.rb +1 -1
  10. data/lib/no_brainer/criteria/extend.rb +31 -0
  11. data/lib/no_brainer/criteria/first.rb +1 -1
  12. data/lib/no_brainer/criteria/index.rb +1 -1
  13. data/lib/no_brainer/criteria/limit.rb +0 -1
  14. data/lib/no_brainer/criteria/order_by.rb +8 -9
  15. data/lib/no_brainer/criteria/pluck.rb +1 -1
  16. data/lib/no_brainer/criteria/raw.rb +1 -1
  17. data/lib/no_brainer/criteria/scope.rb +6 -6
  18. data/lib/no_brainer/criteria/update.rb +3 -3
  19. data/lib/no_brainer/criteria/where.rb +24 -32
  20. data/lib/no_brainer/document/association.rb +5 -5
  21. data/lib/no_brainer/document/association/belongs_to.rb +6 -6
  22. data/lib/no_brainer/document/association/core.rb +11 -11
  23. data/lib/no_brainer/document/association/eager_loader.rb +1 -1
  24. data/lib/no_brainer/document/association/has_many.rb +7 -7
  25. data/lib/no_brainer/document/association/has_many_through.rb +1 -1
  26. data/lib/no_brainer/document/association/has_one.rb +1 -1
  27. data/lib/no_brainer/document/atomic_ops.rb +26 -18
  28. data/lib/no_brainer/document/attributes.rb +9 -8
  29. data/lib/no_brainer/document/callbacks.rb +1 -1
  30. data/lib/no_brainer/document/core.rb +1 -1
  31. data/lib/no_brainer/document/criteria.rb +9 -2
  32. data/lib/no_brainer/document/dirty.rb +1 -3
  33. data/lib/no_brainer/document/index.rb +13 -79
  34. data/lib/no_brainer/document/index/index.rb +83 -0
  35. data/lib/no_brainer/document/index/meta_store.rb +31 -0
  36. data/lib/no_brainer/document/index/synchronizer.rb +68 -0
  37. data/lib/no_brainer/document/lazy_fetch.rb +5 -5
  38. data/lib/no_brainer/document/persistance.rb +27 -7
  39. data/lib/no_brainer/document/polymorphic.rb +1 -1
  40. data/lib/no_brainer/document/types.rb +6 -4
  41. data/lib/no_brainer/document/uniqueness.rb +3 -3
  42. data/lib/no_brainer/document/validation.rb +13 -4
  43. data/lib/no_brainer/fork.rb +1 -0
  44. data/lib/no_brainer/query_runner/database_on_demand.rb +6 -5
  45. data/lib/no_brainer/query_runner/logger.rb +10 -6
  46. data/lib/no_brainer/query_runner/missing_index.rb +5 -4
  47. data/lib/no_brainer/query_runner/reconnect.rb +20 -17
  48. data/lib/no_brainer/query_runner/run_options.rb +3 -0
  49. data/lib/no_brainer/query_runner/table_on_demand.rb +11 -8
  50. data/lib/no_brainer/railtie.rb +5 -5
  51. data/lib/no_brainer/railtie/database.rake +12 -12
  52. data/lib/no_brainer/rql.rb +9 -0
  53. data/lib/nobrainer.rb +5 -3
  54. metadata +8 -8
  55. data/lib/no_brainer/index_manager.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6cf2f24165387c78884eaffc90c04da535bc571f
4
- data.tar.gz: b8d3b1bd887c454e3f017664a559c70bec9a6312
3
+ metadata.gz: 0e146036464db0297a156c6987cb51011137f245
4
+ data.tar.gz: 7f6815c09410489fbe26b1c0faebdc7aefe001e1
5
5
  SHA512:
6
- metadata.gz: fa00190b18bbd8a498c855ef04fe7720c169c51edbb0d360939dc2ea5c4b76db47361615bc86153207e22be8096946bdce120c35d3b3da6fe99a9db4a4b58f94
7
- data.tar.gz: 034d21dabdce9c900b11c899e20d5e69af34560ec2980bbfdba386974bc30828ac6fb9d590fc73a4ac9b568dbfdbdb9a9fb60760c4aeceac963396fd8128e679
6
+ metadata.gz: 00b32de4c7ccd965972369698d6619cfa873671d73c5805d03c37e026737eab42cfb5a3d2f94c00323ec05ce84c7baef0702c1572673ed90050f9f02dcf04458
7
+ data.tar.gz: 661eca7f94fb210e481ecf064829a72b095cc59552de2197856a9226d2978b91c489c26a4045e919368f6d532433b6cbcd3aba8c459c9cd5d2e3bb7f115c6d92
@@ -2,25 +2,34 @@ require 'logger'
2
2
 
3
3
  module NoBrainer::Config
4
4
  class << self
5
- mattr_accessor :rethinkdb_url, :logger, :warn_on_active_record,
5
+ mattr_accessor :app_name, :environment, :rethinkdb_url,
6
+ :logger, :warn_on_active_record,
6
7
  :auto_create_databases, :auto_create_tables,
7
- :max_reconnection_tries, :durability,
8
+ :max_retries_on_connection_failure, :durability,
8
9
  :user_timezone, :db_timezone, :colorize_logger,
9
10
  :distributed_lock_class, :per_thread_connection
10
11
 
11
12
  def apply_defaults
12
- self.rethinkdb_url = default_rethinkdb_url
13
- self.logger = default_logger
14
- self.warn_on_active_record = true
15
- self.auto_create_databases = true
16
- self.auto_create_tables = true
17
- self.max_reconnection_tries = 10
18
- self.durability = default_durability
19
- self.user_timezone = :local
20
- self.db_timezone = :utc
21
- self.colorize_logger = true
22
- self.distributed_lock_class = nil
23
- self.per_thread_connection = false
13
+ self.app_name = default_app_name
14
+ self.environment = default_environment
15
+ self.rethinkdb_url = default_rethinkdb_url
16
+ self.logger = default_logger
17
+ self.warn_on_active_record = true
18
+ self.auto_create_databases = true
19
+ self.auto_create_tables = true
20
+ self.max_retries_on_connection_failure = default_max_retries_on_connection_failure
21
+ self.durability = default_durability
22
+ self.user_timezone = :local
23
+ self.db_timezone = :utc
24
+ self.colorize_logger = true
25
+ self.distributed_lock_class = nil
26
+ self.per_thread_connection = false
27
+ end
28
+
29
+ def max_reconnection_tries=(value)
30
+ STDERR.puts "[NoBrainer] config.max_reconnection_tries is deprecated and will be removed"
31
+ STDERR.puts "[NoBrainer] use config.max_retries_on_connection_failure instead."
32
+ self.max_retries_on_connection_failure = value
24
33
  end
25
34
 
26
35
  def reset!
@@ -53,9 +62,18 @@ module NoBrainer::Config
53
62
  end
54
63
  end
55
64
 
65
+ def default_app_name
66
+ defined?(Rails) ? Rails.application.class.parent_name.underscore : nil
67
+ end
68
+
69
+ def default_environment
70
+ return Rails.env if defined?(Rails.env)
71
+ ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || :production
72
+ end
73
+
56
74
  def default_rethinkdb_url
57
75
  db = ENV['RETHINKDB_DB'] || ENV['RDB_DB']
58
- db ||= "#{Rails.application.class.parent_name.underscore}_#{Rails.env}" rescue nil
76
+ db ||= "#{self.app_name}_#{self.environment}" if self.app_name && self.environment
59
77
  host = ENV['RETHINKDB_HOST'] || ENV['RDB_HOST'] || 'localhost'
60
78
  port = ENV['RETHINKDB_PORT'] || ENV['RDB_PORT']
61
79
  auth = ENV['RETHINKDB_AUTH'] || ENV['RDB_AUTH']
@@ -69,7 +87,15 @@ module NoBrainer::Config
69
87
  end
70
88
 
71
89
  def default_durability
72
- (defined?(Rails.env) && (Rails.env.test? || Rails.env.development?)) ? :soft : :hard
90
+ dev_mode? ? :soft : :hard
91
+ end
92
+
93
+ def default_max_retries_on_connection_failure
94
+ dev_mode? ? 1 : 15
95
+ end
96
+
97
+ def dev_mode?
98
+ self.environment.to_sym.in?([:development, :test])
73
99
  end
74
100
  end
75
101
  end
@@ -52,6 +52,7 @@ class NoBrainer::Connection
52
52
  # database (drop)
53
53
  def purge!(options={})
54
54
  table_list.each do |table_name|
55
+ next if table_name =~ /^nobrainer_/
55
56
  NoBrainer.run { |r| r.table(table_name).delete }
56
57
  end
57
58
  true
@@ -43,7 +43,7 @@ module NoBrainer::ConnectionManager
43
43
  end
44
44
 
45
45
  def _disconnect
46
- self.current_connection.try(:disconnect, :noreply_wait => true) rescue nil
46
+ self.current_connection.try(:close, :noreply_wait => false) rescue nil
47
47
  self.current_connection = nil
48
48
  end
49
49
 
@@ -4,5 +4,5 @@ class NoBrainer::Criteria
4
4
  extend NoBrainer::Autoload
5
5
  autoload_and_include :Core, :Raw, :AfterFind, :Where, :OrderBy, :Limit,
6
6
  :Pluck, :Count, :Delete, :Enumerable, :First, :Aggregate,
7
- :Preload, :Update, :Cache, :Index, :Scope
7
+ :Preload, :Update, :Cache, :Index, :Extend, :Scope
8
8
  end
@@ -2,24 +2,27 @@ module NoBrainer::Criteria::Aggregate
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def min(*a, &b)
5
- instantiate_doc NoBrainer.run { aggregate_rql(:min, *a, &b) }
5
+ instantiate_doc run { aggregate_rql(:min, *a, &b) }
6
6
  end
7
7
 
8
8
  def max(*a, &b)
9
- instantiate_doc NoBrainer.run { aggregate_rql(:max, *a, &b) }
9
+ instantiate_doc run { aggregate_rql(:max, *a, &b) }
10
10
  end
11
11
 
12
12
  def sum(*a, &b)
13
- NoBrainer.run { aggregate_rql(:sum, *a, &b) }
13
+ run { aggregate_rql(:sum, *a, &b) }
14
14
  end
15
15
 
16
16
  def avg(*a, &b)
17
- NoBrainer.run { aggregate_rql(:avg, *a, &b) }
17
+ run { aggregate_rql(:avg, *a, &b) }
18
18
  end
19
19
 
20
20
  private
21
21
 
22
22
  def aggregate_rql(type, *a, &b)
23
- without_ordering.without_plucking.to_rql.__send__(type, *klass.with_fields_aliased(a), &b)
23
+ rql = without_ordering.without_plucking.to_rql
24
+ rql = rql.__send__(type, *model.with_fields_aliased(a), &b)
25
+ rql = rql.default(nil) unless type == :sum
26
+ rql
24
27
  end
25
28
  end
@@ -7,8 +7,8 @@ module NoBrainer::Criteria::Core
7
7
  self.init_options = options
8
8
  end
9
9
 
10
- def klass
11
- init_options[:klass]
10
+ def model
11
+ init_options[:model]
12
12
  end
13
13
 
14
14
  def to_rql
@@ -16,12 +16,13 @@ module NoBrainer::Criteria::Core
16
16
  end
17
17
 
18
18
  def inspect
19
- # rescue super because sometimes klass is not set.
19
+ # rescue super because sometimes model is not set.
20
20
  to_rql.inspect rescue super
21
21
  end
22
22
 
23
- def run(rql=nil)
24
- NoBrainer.run(:criteria => self) { (rql || to_rql) }
23
+ def run(&block)
24
+ block ||= proc { to_rql }
25
+ NoBrainer.run(:criteria => self, &block)
25
26
  end
26
27
 
27
28
  def merge!(criteria, options={})
@@ -48,8 +49,8 @@ module NoBrainer::Criteria::Core
48
49
 
49
50
  def compile_rql_pass1
50
51
  # This method is overriden by other modules.
51
- raise "Criteria not bound to a class" unless klass
52
- klass.rql_table
52
+ raise "Criteria not bound to a model" unless model
53
+ model.rql_table
53
54
  end
54
55
 
55
56
  def compile_rql_pass2
@@ -2,7 +2,7 @@ module NoBrainer::Criteria::Count
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def count
5
- run(without_ordering.without_plucking.to_rql.count)
5
+ run { without_ordering.without_plucking.to_rql.count }
6
6
  end
7
7
 
8
8
  def empty?
@@ -2,7 +2,7 @@ module NoBrainer::Criteria::Delete
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def delete_all
5
- run(without_ordering.without_plucking.to_rql.delete)
5
+ run { without_ordering.without_plucking.to_rql.delete }
6
6
  end
7
7
 
8
8
  def destroy_all
@@ -0,0 +1,31 @@
1
+ module NoBrainer::Criteria::Extend
2
+ extend ActiveSupport::Concern
3
+
4
+ included { attr_accessor :extend_modules }
5
+
6
+ def extend(*modules, &block)
7
+ options = modules.extract_options!
8
+ modules << Module.new(&block) if block
9
+
10
+ return super(*modules) if options[:original_behavior]
11
+
12
+ chain do |criteria|
13
+ criteria.extend_modules ||= []
14
+ criteria.extend_modules += [modules]
15
+ end
16
+ end
17
+
18
+ def merge!(criteria, options={})
19
+ super
20
+
21
+ if criteria.extend_modules.present?
22
+ self.extend_modules = self.extend_modules.to_a + criteria.extend_modules
23
+ end
24
+
25
+ if self.extend_modules.present?
26
+ self.extend_modules.each { |modules| extend(*modules, :original_behavior => true) }
27
+ end
28
+
29
+ self
30
+ end
31
+ end
@@ -18,7 +18,7 @@ module NoBrainer::Criteria::First
18
18
  end
19
19
 
20
20
  def sample(n=nil)
21
- result = NoBrainer.run { self.without_ordering.to_rql.sample(n.nil? ? 1 : n) }
21
+ result = run { self.without_ordering.to_rql.sample(n.nil? ? 1 : n) }
22
22
  result = result.map(&method(:instantiate_doc))
23
23
  n.nil? ? result.first : result
24
24
  end
@@ -28,7 +28,7 @@ module NoBrainer::Criteria::Index
28
28
 
29
29
  def compile_rql_pass2
30
30
  super.tap do
31
- if with_index_name && (!used_index || order_by_index_name.to_s == klass.pk_name.to_s)
31
+ if with_index_name && (!used_index || order_by_index_name.to_s == model.pk_name.to_s)
32
32
  # The implicit ordering on the indexed pk does not count.
33
33
  raise NoBrainer::Error::CannotUseIndex.new(with_index_name)
34
34
  end
@@ -1,5 +1,4 @@
1
1
  module NoBrainer::Criteria::Limit
2
- # TODO Test these guys
3
2
  extend ActiveSupport::Concern
4
3
 
5
4
  included { attr_accessor :_skip, :_limit }
@@ -10,7 +10,7 @@ module NoBrainer::Criteria::OrderBy
10
10
 
11
11
  def order_by(*rules, &block)
12
12
  # Note: We are relying on the fact that Hashes are ordered (since 1.9)
13
- rules = [*rules, block].compact.map do |rule|
13
+ rules = [*rules, block].flatten.compact.map do |rule|
14
14
  case rule
15
15
  when Hash then
16
16
  bad_rule = rule.values.reject { |v| v.in? [:asc, :desc] }.first
@@ -62,7 +62,7 @@ module NoBrainer::Criteria::OrderBy
62
62
  private
63
63
 
64
64
  def effective_order
65
- self.order.presence || (klass ? {klass.pk_name => :asc} : {})
65
+ self.order.presence || (model ? {model.pk_name => :asc} : {})
66
66
  end
67
67
 
68
68
  def reverse_order?
@@ -83,7 +83,7 @@ module NoBrainer::Criteria::OrderBy
83
83
  end
84
84
 
85
85
  def first_key_indexable?
86
- (first_key.is_a?(Symbol) || first_key.is_a?(String)) && criteria.klass.has_index?(first_key)
86
+ (first_key.is_a?(Symbol) || first_key.is_a?(String)) && criteria.model.has_index?(first_key)
87
87
  end
88
88
 
89
89
  def find_index
@@ -116,9 +116,9 @@ module NoBrainer::Criteria::OrderBy
116
116
 
117
117
  rql_rules = _effective_order.map do |k,v|
118
118
  if order_by_index_finder.index_name == k
119
- k = klass.lookup_index_alias(k)
119
+ k = model.lookup_index_alias(k)
120
120
  else
121
- k = klass.lookup_field_alias(k)
121
+ k = model.lookup_field_alias(k)
122
122
  end
123
123
 
124
124
  case v
@@ -127,14 +127,13 @@ module NoBrainer::Criteria::OrderBy
127
127
  end
128
128
  end
129
129
 
130
- # We can only apply an index order_by on a table() term.
131
- # We are going to try to go so and if we cannot, we'll simply apply
132
- # the ordering in pass2, which will happen after a potential filter().
130
+ # We can only apply an indexed order_by on a table() RQL term.
131
+ # If we can, great. Otherwise, the ordering is applied in pass2, which will
132
+ # happen after a potential filter(), which is better for perfs.
133
133
  if order_by_index_finder.could_find_index?
134
134
  options = { :index => rql_rules.shift }
135
135
  rql = rql.order_by(*rql_rules, options)
136
136
  else
137
- # Stashing @rql_rules for pass2
138
137
  @rql_rules_pass2 = rql_rules
139
138
  end
140
139
 
@@ -74,7 +74,7 @@ module NoBrainer::Criteria::Pluck
74
74
  rql = super
75
75
  if effective_missing_attributes
76
76
  type, attrs = effective_missing_attributes.first
77
- rql = rql.__send__(type, klass.with_fields_aliased(attrs))
77
+ rql = rql.__send__(type, model.with_fields_aliased(attrs))
78
78
  end
79
79
  rql
80
80
  end
@@ -28,6 +28,6 @@ module NoBrainer::Criteria::Raw
28
28
  end
29
29
 
30
30
  def _instantiate_model(attrs, options={})
31
- klass.new_from_db(attrs, options)
31
+ model.new_from_db(attrs, options)
32
32
  end
33
33
  end
@@ -18,12 +18,12 @@ module NoBrainer::Criteria::Scope
18
18
  end
19
19
 
20
20
  def respond_to?(name, include_private = false)
21
- super || self.klass.respond_to?(name)
21
+ super || self.model.respond_to?(name)
22
22
  end
23
23
 
24
24
  def method_missing(name, *args, &block)
25
- return super unless self.klass.respond_to?(name)
26
- criteria = self.klass.method(name).call(*args, &block)
25
+ return super unless self.model.respond_to?(name)
26
+ criteria = self.model.method(name).call(*args, &block)
27
27
  raise "#{name} did not return a criteria" unless criteria.is_a?(NoBrainer::Criteria)
28
28
  merge(criteria)
29
29
  end
@@ -31,13 +31,13 @@ module NoBrainer::Criteria::Scope
31
31
  private
32
32
 
33
33
  def should_apply_default_scope?
34
- klass.default_scope_proc && use_default_scope != false
34
+ model.default_scope_proc && use_default_scope != false
35
35
  end
36
36
 
37
37
  def _apply_default_scope
38
38
  return unless should_apply_default_scope?
39
- criteria = klass.default_scope_proc.call
40
- raise "Mixing model issue. Contact developer." if [criteria.klass, self.klass].compact.uniq.size == 2
39
+ criteria = model.default_scope_proc.call
40
+ raise "Mixing model issue. Contact developer." if [criteria.model, self.model].compact.uniq.size == 2
41
41
  criteria.merge(self)
42
42
  end
43
43
 
@@ -3,17 +3,17 @@ module NoBrainer::Criteria::Update
3
3
 
4
4
  def update_all(*a, &b)
5
5
  prepare_args_for_update!(a)
6
- run(without_ordering.without_plucking.to_rql.update(*a, &b))
6
+ run { without_ordering.without_plucking.to_rql.update(*a, &b) }
7
7
  end
8
8
 
9
9
  def replace_all(*a, &b)
10
10
  prepare_args_for_update!(a)
11
- run(without_ordering.without_plucking.to_rql.replace(*a, &b))
11
+ run { without_ordering.without_plucking.to_rql.replace(*a, &b) }
12
12
  end
13
13
 
14
14
  private
15
15
 
16
16
  def prepare_args_for_update!(a)
17
- a[0] = klass.persistable_attributes(a[0]) if !a.empty? && a.first.is_a?(Hash)
17
+ a[0] = model.persistable_attributes(a[0]) if !a.empty? && a.first.is_a?(Hash)
18
18
  end
19
19
  end
@@ -134,9 +134,9 @@ module NoBrainer::Criteria::Where
134
134
 
135
135
  case association
136
136
  when NoBrainer::Document::Association::BelongsTo::Metadata
137
- target_klass = association.target_klass
138
- opts = { :attr_name => key, :value => value, :type => target_klass}
139
- raise NoBrainer::Error::InvalidType.new(opts) unless value.is_a?(target_klass)
137
+ target_model = association.target_model
138
+ opts = { :attr_name => key, :value => value, :type => target_model}
139
+ raise NoBrainer::Error::InvalidType.new(opts) unless value.is_a?(target_model)
140
140
  value.pk_value
141
141
  else
142
142
  model.cast_user_to_db_for(key, value)
@@ -200,7 +200,7 @@ module NoBrainer::Criteria::Where
200
200
  when :nin then parse_clause(:not => { key.symbol.in => value })
201
201
  when :ne then parse_clause(:not => { key.symbol.eq => value })
202
202
  when :eq then parse_clause_stub_eq(key.symbol, value)
203
- else BinaryOperator.new(key.symbol, key.modifier, value, self.klass)
203
+ else BinaryOperator.new(key.symbol, key.modifier, value, self.model)
204
204
  end
205
205
  else raise "Invalid key: #{key}"
206
206
  end
@@ -208,9 +208,9 @@ module NoBrainer::Criteria::Where
208
208
 
209
209
  def parse_clause_stub_eq(key, value)
210
210
  case value
211
- when Range then BinaryOperator.new(key, :between, value, self.klass)
212
- when Regexp then BinaryOperator.new(key, :match, value.inspect[1..-2], self.klass)
213
- else BinaryOperator.new(key, :eq, value, self.klass)
211
+ when Range then BinaryOperator.new(key, :between, value, self.model)
212
+ when Regexp then BinaryOperator.new(key, :match, value.inspect[1..-2], self.model)
213
+ else BinaryOperator.new(key, :eq, value, self.model)
214
214
  end
215
215
  end
216
216
 
@@ -230,10 +230,10 @@ module NoBrainer::Criteria::Where
230
230
  def get_usable_indexes(*types)
231
231
  @usable_indexes = {}
232
232
  @usable_indexes[types] ||= begin
233
- indexes = criteria.klass.indexes
234
- indexes = indexes.select { |k,v| types.include?(v[:kind]) } if types.present?
233
+ indexes = criteria.model.indexes.values
234
+ indexes = indexes.select { |i| types.include?(i.kind) } if types.present?
235
235
  if criteria.with_index_name && criteria.with_index_name != true
236
- indexes = indexes.select { |k,v| k == criteria.with_index_name.to_sym }
236
+ indexes = indexes.select { |i| i.name == criteria.with_index_name.to_sym }
237
237
  end
238
238
  indexes
239
239
  end
@@ -248,16 +248,15 @@ module NoBrainer::Criteria::Where
248
248
  clauses = Hash[get_candidate_clauses(:eq, :in, :between).map { |c| [c.key, c] }]
249
249
  return unless clauses.present?
250
250
 
251
- if index_name = (get_usable_indexes.keys & clauses.keys).first
252
- clause = clauses[index_name]
253
- aliased_index = criteria.klass.indexes[index_name][:as]
254
- self.index_name = index_name
251
+ if index = get_usable_indexes.select { |i| clauses[i.name] }.first
252
+ clause = clauses[index.name]
253
+ self.index_name = index.name
255
254
  self.ast = remove_from_ast([clause])
256
255
  self.index_type = clause.op == :between ? :between : :get_all
257
256
  self.rql_proc = case clause.op
258
- when :eq then ->(rql){ rql.get_all(clause.value, :index => aliased_index) }
259
- when :in then ->(rql){ rql.get_all(*clause.value, :index => aliased_index) }
260
- when :between then ->(rql){ rql.between(clause.value.min, clause.value.max, :index => aliased_index,
257
+ when :eq then ->(rql){ rql.get_all(clause.value, :index => index.aliased_name) }
258
+ when :in then ->(rql){ rql.get_all(*clause.value, :index => index.aliased_name) }
259
+ when :between then ->(rql){ rql.between(clause.value.min, clause.value.max, :index => index.aliased_name,
261
260
  :left_bound => :closed, :right_bound => :closed) }
262
261
  end
263
262
  end
@@ -267,18 +266,12 @@ module NoBrainer::Criteria::Where
267
266
  clauses = Hash[get_candidate_clauses(:eq).map { |c| [c.key, c] }]
268
267
  return unless clauses.present?
269
268
 
270
- index_name, index_values = get_usable_indexes(:compound)
271
- .map { |name, option| [name, option[:what]] }
272
- .select { |name, values| values & clauses.keys == values }
273
- .first
274
-
275
- if index_name
276
- indexed_clauses = index_values.map { |field| clauses[field] }
277
- aliased_index = criteria.klass.indexes[index_name][:as]
278
- self.index_name = index_name
269
+ if index = get_usable_indexes(:compound).select { |i| i.what & clauses.keys == i.what }.first
270
+ indexed_clauses = index.what.map { |field| clauses[field] }
271
+ self.index_name = index.name
279
272
  self.ast = remove_from_ast(indexed_clauses)
280
273
  self.index_type = :get_all
281
- self.rql_proc = ->(rql){ rql.get_all(indexed_clauses.map { |c| c.value }, :index => aliased_index) }
274
+ self.rql_proc = ->(rql){ rql.get_all(indexed_clauses.map { |c| c.value }, :index => index.aliased_name) }
282
275
  end
283
276
  end
284
277
 
@@ -286,17 +279,16 @@ module NoBrainer::Criteria::Where
286
279
  clauses = get_candidate_clauses(:gt, :ge, :lt, :le).group_by(&:key)
287
280
  return unless clauses.present?
288
281
 
289
- if index_name = (get_usable_indexes.keys & clauses.keys).first
290
- op_clauses = Hash[clauses[index_name].map { |c| [c.op, c] }]
282
+ if index = get_usable_indexes.select { |i| clauses[i.name] }.first
283
+ op_clauses = Hash[clauses[index.name].map { |c| [c.op, c] }]
291
284
  left_bound = op_clauses[:gt] || op_clauses[:ge]
292
285
  right_bound = op_clauses[:lt] || op_clauses[:le]
293
286
 
294
- aliased_index = criteria.klass.indexes[index_name][:as]
295
- self.index_name = index_name
287
+ self.index_name = index.name
296
288
  self.ast = remove_from_ast([left_bound, right_bound].compact)
297
289
 
298
290
  options = {}
299
- options[:index] = aliased_index
291
+ options[:index] = index.aliased_name
300
292
  options[:left_bound] = {:gt => :open, :ge => :closed}[left_bound.op] if left_bound
301
293
  options[:right_bound] = {:lt => :open, :le => :closed}[right_bound.op] if right_bound
302
294
  self.index_type = :between