nobrainer 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/no_brainer/config.rb +42 -16
- data/lib/no_brainer/connection.rb +1 -0
- data/lib/no_brainer/connection_manager.rb +1 -1
- data/lib/no_brainer/criteria.rb +1 -1
- data/lib/no_brainer/criteria/aggregate.rb +8 -5
- data/lib/no_brainer/criteria/core.rb +8 -7
- data/lib/no_brainer/criteria/count.rb +1 -1
- data/lib/no_brainer/criteria/delete.rb +1 -1
- data/lib/no_brainer/criteria/extend.rb +31 -0
- data/lib/no_brainer/criteria/first.rb +1 -1
- data/lib/no_brainer/criteria/index.rb +1 -1
- data/lib/no_brainer/criteria/limit.rb +0 -1
- data/lib/no_brainer/criteria/order_by.rb +8 -9
- data/lib/no_brainer/criteria/pluck.rb +1 -1
- data/lib/no_brainer/criteria/raw.rb +1 -1
- data/lib/no_brainer/criteria/scope.rb +6 -6
- data/lib/no_brainer/criteria/update.rb +3 -3
- data/lib/no_brainer/criteria/where.rb +24 -32
- data/lib/no_brainer/document/association.rb +5 -5
- data/lib/no_brainer/document/association/belongs_to.rb +6 -6
- data/lib/no_brainer/document/association/core.rb +11 -11
- data/lib/no_brainer/document/association/eager_loader.rb +1 -1
- data/lib/no_brainer/document/association/has_many.rb +7 -7
- data/lib/no_brainer/document/association/has_many_through.rb +1 -1
- data/lib/no_brainer/document/association/has_one.rb +1 -1
- data/lib/no_brainer/document/atomic_ops.rb +26 -18
- data/lib/no_brainer/document/attributes.rb +9 -8
- data/lib/no_brainer/document/callbacks.rb +1 -1
- data/lib/no_brainer/document/core.rb +1 -1
- data/lib/no_brainer/document/criteria.rb +9 -2
- data/lib/no_brainer/document/dirty.rb +1 -3
- data/lib/no_brainer/document/index.rb +13 -79
- data/lib/no_brainer/document/index/index.rb +83 -0
- data/lib/no_brainer/document/index/meta_store.rb +31 -0
- data/lib/no_brainer/document/index/synchronizer.rb +68 -0
- data/lib/no_brainer/document/lazy_fetch.rb +5 -5
- data/lib/no_brainer/document/persistance.rb +27 -7
- data/lib/no_brainer/document/polymorphic.rb +1 -1
- data/lib/no_brainer/document/types.rb +6 -4
- data/lib/no_brainer/document/uniqueness.rb +3 -3
- data/lib/no_brainer/document/validation.rb +13 -4
- data/lib/no_brainer/fork.rb +1 -0
- data/lib/no_brainer/query_runner/database_on_demand.rb +6 -5
- data/lib/no_brainer/query_runner/logger.rb +10 -6
- data/lib/no_brainer/query_runner/missing_index.rb +5 -4
- data/lib/no_brainer/query_runner/reconnect.rb +20 -17
- data/lib/no_brainer/query_runner/run_options.rb +3 -0
- data/lib/no_brainer/query_runner/table_on_demand.rb +11 -8
- data/lib/no_brainer/railtie.rb +5 -5
- data/lib/no_brainer/railtie/database.rake +12 -12
- data/lib/no_brainer/rql.rb +9 -0
- data/lib/nobrainer.rb +5 -3
- metadata +8 -8
- data/lib/no_brainer/index_manager.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e146036464db0297a156c6987cb51011137f245
|
4
|
+
data.tar.gz: 7f6815c09410489fbe26b1c0faebdc7aefe001e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00b32de4c7ccd965972369698d6619cfa873671d73c5805d03c37e026737eab42cfb5a3d2f94c00323ec05ce84c7baef0702c1572673ed90050f9f02dcf04458
|
7
|
+
data.tar.gz: 661eca7f94fb210e481ecf064829a72b095cc59552de2197856a9226d2978b91c489c26a4045e919368f6d532433b6cbcd3aba8c459c9cd5d2e3bb7f115c6d92
|
data/lib/no_brainer/config.rb
CHANGED
@@ -2,25 +2,34 @@ require 'logger'
|
|
2
2
|
|
3
3
|
module NoBrainer::Config
|
4
4
|
class << self
|
5
|
-
mattr_accessor :
|
5
|
+
mattr_accessor :app_name, :environment, :rethinkdb_url,
|
6
|
+
:logger, :warn_on_active_record,
|
6
7
|
:auto_create_databases, :auto_create_tables,
|
7
|
-
:
|
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.
|
13
|
-
self.
|
14
|
-
self.
|
15
|
-
self.
|
16
|
-
self.
|
17
|
-
self.
|
18
|
-
self.
|
19
|
-
self.
|
20
|
-
self.
|
21
|
-
self.
|
22
|
-
self.
|
23
|
-
self.
|
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 ||= "#{
|
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
|
-
|
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
|
data/lib/no_brainer/criteria.rb
CHANGED
@@ -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
|
5
|
+
instantiate_doc run { aggregate_rql(:min, *a, &b) }
|
6
6
|
end
|
7
7
|
|
8
8
|
def max(*a, &b)
|
9
|
-
instantiate_doc
|
9
|
+
instantiate_doc run { aggregate_rql(:max, *a, &b) }
|
10
10
|
end
|
11
11
|
|
12
12
|
def sum(*a, &b)
|
13
|
-
|
13
|
+
run { aggregate_rql(:sum, *a, &b) }
|
14
14
|
end
|
15
15
|
|
16
16
|
def avg(*a, &b)
|
17
|
-
|
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
|
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
|
11
|
-
init_options[:
|
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
|
19
|
+
# rescue super because sometimes model is not set.
|
20
20
|
to_rql.inspect rescue super
|
21
21
|
end
|
22
22
|
|
23
|
-
def run(
|
24
|
-
|
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
|
52
|
-
|
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
|
@@ -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 =
|
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 ==
|
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
|
@@ -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 || (
|
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.
|
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 =
|
119
|
+
k = model.lookup_index_alias(k)
|
120
120
|
else
|
121
|
-
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
|
131
|
-
#
|
132
|
-
#
|
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,
|
77
|
+
rql = rql.__send__(type, model.with_fields_aliased(attrs))
|
78
78
|
end
|
79
79
|
rql
|
80
80
|
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.
|
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.
|
26
|
-
criteria = self.
|
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
|
-
|
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 =
|
40
|
-
raise "Mixing model issue. Contact developer." if [criteria.
|
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
|
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
|
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] =
|
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
|
-
|
138
|
-
opts = { :attr_name => key, :value => value, :type =>
|
139
|
-
raise NoBrainer::Error::InvalidType.new(opts) unless value.is_a?(
|
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.
|
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.
|
212
|
-
when Regexp then BinaryOperator.new(key, :match, value.inspect[1..-2], self.
|
213
|
-
else BinaryOperator.new(key, :eq, value, self.
|
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.
|
234
|
-
indexes = indexes.select { |
|
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 { |
|
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
|
252
|
-
clause = clauses[
|
253
|
-
|
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 =>
|
259
|
-
when :in then ->(rql){ rql.get_all(*clause.value, :index =>
|
260
|
-
when :between then ->(rql){ rql.between(clause.value.min, clause.value.max, :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
|
-
|
271
|
-
.map
|
272
|
-
.
|
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 =>
|
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
|
290
|
-
op_clauses = Hash[clauses[
|
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
|
-
|
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] =
|
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
|