nobrainer 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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