nobrainer 0.18.0 → 0.18.1
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 +35 -37
- data/lib/no_brainer/criteria/after_find.rb +3 -11
- data/lib/no_brainer/criteria/cache.rb +7 -7
- data/lib/no_brainer/criteria/core.rb +49 -10
- data/lib/no_brainer/criteria/extend.rb +4 -16
- data/lib/no_brainer/criteria/index.rb +7 -13
- data/lib/no_brainer/criteria/limit.rb +5 -12
- data/lib/no_brainer/criteria/order_by.rb +15 -33
- data/lib/no_brainer/criteria/pluck.rb +16 -22
- data/lib/no_brainer/criteria/preload.rb +9 -15
- data/lib/no_brainer/criteria/raw.rb +4 -10
- data/lib/no_brainer/criteria/scope.rb +4 -10
- data/lib/no_brainer/criteria/where.rb +10 -25
- data/lib/no_brainer/document/association/eager_loader.rb +3 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d6a500e008eff372e800b011e917d121c07e00a
|
4
|
+
data.tar.gz: e43be89ac4963422c26559727c9a68011ee25f8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56015e819aba3537ab60ea5f039d4b391ec803cc61b5bf246e44da642787e62606e9c02339b17f05976d5428ec3e4fa0e335cb51694b840bd2ba7821b6d66b20
|
7
|
+
data.tar.gz: d4b78185fed14f5baa28165462a4088096da640d93c0dfb3f20c851e968deceb1f48f13602850075a7eea2408fa23e52c2694d140bea1c9a937d7d49d5084f53
|
data/lib/no_brainer/config.rb
CHANGED
@@ -1,30 +1,25 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
module NoBrainer::Config
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
SETTINGS = {
|
5
|
+
:app_name => { :default => ->{ default_app_name } },
|
6
|
+
:environment => { :default => ->{ default_environment } },
|
7
|
+
:rethinkdb_url => { :default => ->{ default_rethinkdb_url } },
|
8
|
+
:logger => { :default => ->{ default_logger } },
|
9
|
+
:warn_on_active_record => { :default => ->{ true }, :valid_values => [true, false] },
|
10
|
+
:auto_create_databases => { :default => ->{ true }, :valid_values => [true, false] },
|
11
|
+
:auto_create_tables => { :default => ->{ true }, :valid_values => [true, false] },
|
12
|
+
:max_retries_on_connection_failure => { :default => ->{ default_max_retries_on_connection_failure } },
|
13
|
+
:durability => { :default => ->{ default_durability }, :valid_values => [:hard, :soft] },
|
14
|
+
:user_timezone => { :default => ->{ :local }, :valid_values => [:unchanged, :utc, :local] },
|
15
|
+
:db_timezone => { :default => ->{ :utc }, :valid_values => [:unchanged, :utc, :local] },
|
16
|
+
:colorize_logger => { :default => ->{ true }, :valid_values => [true, false] },
|
17
|
+
:distributed_lock_class => { :default => ->{ nil } },
|
18
|
+
:per_thread_connection => { :default => ->{ false }, :valid_values => [true, false] },
|
19
|
+
}
|
11
20
|
|
12
|
-
|
13
|
-
|
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
|
21
|
+
class << self
|
22
|
+
attr_accessor(*SETTINGS.keys)
|
28
23
|
|
29
24
|
def max_reconnection_tries=(value)
|
30
25
|
STDERR.puts "[NoBrainer] config.max_reconnection_tries is deprecated and will be removed"
|
@@ -32,14 +27,23 @@ module NoBrainer::Config
|
|
32
27
|
self.max_retries_on_connection_failure = value
|
33
28
|
end
|
34
29
|
|
30
|
+
def apply_defaults
|
31
|
+
@applied_defaults_for = SETTINGS.keys.reject { |k| instance_variable_defined?("@#{k}") }
|
32
|
+
@applied_defaults_for.each { |k| __send__("#{k}=", SETTINGS[k][:default].call) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def assert_valid_options!
|
36
|
+
SETTINGS.each { |k,v| assert_array_in(k, v[:valid_values]) if v[:valid_values] }
|
37
|
+
end
|
38
|
+
|
35
39
|
def reset!
|
36
|
-
|
37
|
-
apply_defaults
|
40
|
+
instance_variables.each { |ivar| remove_instance_variable(ivar) }
|
38
41
|
end
|
39
42
|
|
40
43
|
def configure(&block)
|
41
|
-
|
44
|
+
@applied_defaults_for.to_a.each { |k| remove_instance_variable("@#{k}") }
|
42
45
|
block.call(self) if block
|
46
|
+
apply_defaults
|
43
47
|
assert_valid_options!
|
44
48
|
@configured = true
|
45
49
|
|
@@ -50,20 +54,18 @@ module NoBrainer::Config
|
|
50
54
|
!!@configured
|
51
55
|
end
|
52
56
|
|
53
|
-
def assert_valid_options!
|
54
|
-
assert_array_in :durability, [:hard, :soft]
|
55
|
-
assert_array_in :user_timezone, [:unchanged, :utc, :local]
|
56
|
-
assert_array_in :db_timezone, [:unchanged, :utc, :local]
|
57
|
-
end
|
58
|
-
|
59
57
|
def assert_array_in(name, values)
|
60
58
|
unless __send__(name).in?(values)
|
61
59
|
raise ArgumentError.new("Unknown configuration for #{name}: #{__send__(name)}. Valid values are: #{values.inspect}")
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
63
|
+
def dev_mode?
|
64
|
+
self.environment.to_s.in? %w(development test)
|
65
|
+
end
|
66
|
+
|
65
67
|
def default_app_name
|
66
|
-
defined?(Rails) ? Rails.application.class.parent_name.underscore : nil
|
68
|
+
defined?(Rails) ? Rails.application.class.parent_name.underscore.presence : nil rescue nil
|
67
69
|
end
|
68
70
|
|
69
71
|
def default_environment
|
@@ -93,9 +95,5 @@ module NoBrainer::Config
|
|
93
95
|
def default_max_retries_on_connection_failure
|
94
96
|
dev_mode? ? 1 : 15
|
95
97
|
end
|
96
|
-
|
97
|
-
def dev_mode?
|
98
|
-
self.environment.to_sym.in?([:development, :test])
|
99
|
-
end
|
100
98
|
end
|
101
99
|
end
|
@@ -1,23 +1,15 @@
|
|
1
1
|
module NoBrainer::Criteria::AfterFind
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :after_find, :merge_with => :append_array }
|
5
5
|
|
6
6
|
def after_find(b=nil, &block)
|
7
|
-
chain
|
8
|
-
end
|
9
|
-
|
10
|
-
def merge!(criteria, options={})
|
11
|
-
super
|
12
|
-
if criteria._after_find.present?
|
13
|
-
self._after_find = (self._after_find || []) + criteria._after_find
|
14
|
-
end
|
15
|
-
self
|
7
|
+
chain(:after_find => [b, block].compact)
|
16
8
|
end
|
17
9
|
|
18
10
|
def _instantiate_doc(attrs)
|
19
11
|
super.tap do |doc|
|
20
|
-
|
12
|
+
@options[:after_find].to_a.each { |block| block.call(doc) }
|
21
13
|
doc.run_callbacks(:find) if doc.is_a?(NoBrainer::Document)
|
22
14
|
end
|
23
15
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module NoBrainer::Criteria::Cache
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :with_cache, :merge_with => :set_scalar }
|
5
5
|
|
6
6
|
def with_cache
|
7
|
-
chain
|
7
|
+
chain(:with_cache => true)
|
8
8
|
end
|
9
9
|
|
10
10
|
def without_cache
|
11
|
-
chain
|
11
|
+
chain(:with_cache => false)
|
12
12
|
end
|
13
13
|
|
14
14
|
def inspect
|
@@ -18,14 +18,14 @@ module NoBrainer::Criteria::Cache
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def merge!(criteria, options={})
|
21
|
+
if options[:copy_cache_from] && options[:copy_cache_from].cached?
|
22
|
+
@cache = options[:copy_cache_from].instance_variable_get(:@cache)
|
23
|
+
end
|
21
24
|
super
|
22
|
-
self._with_cache = criteria._with_cache unless criteria._with_cache.nil?
|
23
|
-
self.reload unless options[:keep_cache]
|
24
|
-
self
|
25
25
|
end
|
26
26
|
|
27
27
|
def with_cache?
|
28
|
-
|
28
|
+
finalized_criteria.options[:with_cache] != false
|
29
29
|
end
|
30
30
|
|
31
31
|
def reload
|
@@ -1,14 +1,26 @@
|
|
1
1
|
module NoBrainer::Criteria::Core
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included
|
4
|
+
included do
|
5
|
+
singleton_class.send(:attr_accessor, :options_definitions)
|
6
|
+
self.options_definitions = {}
|
7
|
+
attr_accessor :options
|
8
|
+
|
9
|
+
criteria_option :model, :merge_with => :set_scalar
|
10
|
+
criteria_option :finalized, :merge_with => :set_scalar
|
11
|
+
end
|
5
12
|
|
6
13
|
def initialize(options={})
|
7
|
-
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
def dup
|
18
|
+
# We don't keep any of the instance variables except options.
|
19
|
+
self.class.new(@options.dup)
|
8
20
|
end
|
9
21
|
|
10
22
|
def model
|
11
|
-
|
23
|
+
@options[:model]
|
12
24
|
end
|
13
25
|
|
14
26
|
def to_rql
|
@@ -26,7 +38,11 @@ module NoBrainer::Criteria::Core
|
|
26
38
|
end
|
27
39
|
|
28
40
|
def merge!(criteria, options={})
|
29
|
-
|
41
|
+
criteria.options.each do |k,v|
|
42
|
+
merge_proc = self.class.options_definitions[k]
|
43
|
+
raise "Non declared option: #{k}" unless merge_proc
|
44
|
+
@options[k] = merge_proc.call(@options[k], v)
|
45
|
+
end
|
30
46
|
self
|
31
47
|
end
|
32
48
|
|
@@ -41,10 +57,8 @@ module NoBrainer::Criteria::Core
|
|
41
57
|
|
42
58
|
private
|
43
59
|
|
44
|
-
def chain(options={}, &block)
|
45
|
-
|
46
|
-
block.call(tmp)
|
47
|
-
merge(tmp, options)
|
60
|
+
def chain(options={}, merge_options={}, &block)
|
61
|
+
merge(self.class.new(options), merge_options)
|
48
62
|
end
|
49
63
|
|
50
64
|
def compile_rql_pass1
|
@@ -59,7 +73,7 @@ module NoBrainer::Criteria::Core
|
|
59
73
|
end
|
60
74
|
|
61
75
|
def finalized?
|
62
|
-
|
76
|
+
!!@options[:finalized]
|
63
77
|
end
|
64
78
|
|
65
79
|
def finalized_criteria
|
@@ -67,8 +81,33 @@ module NoBrainer::Criteria::Core
|
|
67
81
|
end
|
68
82
|
|
69
83
|
module ClassMethods
|
84
|
+
def criteria_option(*names)
|
85
|
+
options = names.extract_options!
|
86
|
+
|
87
|
+
names.map(&:to_sym).each do |name|
|
88
|
+
merge_proc = options[:merge_with]
|
89
|
+
merge_proc = MergeStrategies.method(merge_proc) if merge_proc.is_a?(Symbol)
|
90
|
+
self.options_definitions[name] = merge_proc
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
70
94
|
def _finalize_criteria(base)
|
71
|
-
base.
|
95
|
+
base.__send__(:chain, :finalized => true)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
module MergeStrategies
|
100
|
+
extend self
|
101
|
+
def set_scalar(a, b)
|
102
|
+
b
|
103
|
+
end
|
104
|
+
|
105
|
+
def merge_hash(a, b)
|
106
|
+
a ? a.merge(b) : b
|
107
|
+
end
|
108
|
+
|
109
|
+
def append_array(a, b)
|
110
|
+
a ? a+b : b
|
72
111
|
end
|
73
112
|
end
|
74
113
|
end
|
@@ -1,31 +1,19 @@
|
|
1
1
|
module NoBrainer::Criteria::Extend
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :extend, :merge_with => :append_array }
|
5
5
|
|
6
6
|
def extend(*modules, &block)
|
7
7
|
options = modules.extract_options!
|
8
8
|
modules << Module.new(&block) if block
|
9
9
|
|
10
10
|
return super(*modules) if options[:original_behavior]
|
11
|
-
|
12
|
-
chain do |criteria|
|
13
|
-
criteria.extend_modules ||= []
|
14
|
-
criteria.extend_modules += [modules]
|
15
|
-
end
|
11
|
+
chain(:extend => [modules])
|
16
12
|
end
|
17
13
|
|
18
14
|
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
|
15
|
+
super.tap do
|
16
|
+
@options[:extend].to_a.each { |modules| extend(*modules, :original_behavior => true) }
|
23
17
|
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
18
|
end
|
31
19
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module NoBrainer::Criteria::Index
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :use_index, :merge_with => :set_scalar }
|
5
5
|
|
6
6
|
def with_index(index_name=true)
|
7
|
-
chain
|
7
|
+
chain(:use_index => index_name)
|
8
8
|
end
|
9
9
|
|
10
10
|
def without_index
|
@@ -12,25 +12,19 @@ module NoBrainer::Criteria::Index
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def without_index?
|
15
|
-
finalized_criteria.
|
15
|
+
finalized_criteria.options[:use_index] == false
|
16
16
|
end
|
17
17
|
|
18
18
|
def used_index
|
19
|
-
#
|
19
|
+
# Only one of them will be active.
|
20
20
|
where_index_name || order_by_index_name
|
21
21
|
end
|
22
22
|
|
23
|
-
def merge!(criteria, options={})
|
24
|
-
super
|
25
|
-
self.with_index_name = criteria.with_index_name unless criteria.with_index_name.nil?
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
23
|
def compile_rql_pass2
|
30
24
|
super.tap do
|
31
|
-
|
32
|
-
|
33
|
-
raise NoBrainer::Error::CannotUseIndex.new(
|
25
|
+
# The implicit ordering on the indexed pk does not count.
|
26
|
+
if @options[:use_index] && (!used_index || order_by_index_name.to_s == model.pk_name.to_s)
|
27
|
+
raise NoBrainer::Error::CannotUseIndex.new(@options[:use_index])
|
34
28
|
end
|
35
29
|
end
|
36
30
|
end
|
@@ -1,30 +1,23 @@
|
|
1
1
|
module NoBrainer::Criteria::Limit
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :skip, :limit, :merge_with => :set_scalar }
|
5
5
|
|
6
6
|
def limit(value)
|
7
|
-
chain
|
7
|
+
chain(:limit => value)
|
8
8
|
end
|
9
9
|
|
10
10
|
def skip(value)
|
11
|
-
chain
|
11
|
+
chain(:skip => value)
|
12
12
|
end
|
13
13
|
alias_method :offset, :skip
|
14
14
|
|
15
|
-
def merge!(criteria, options={})
|
16
|
-
super
|
17
|
-
self._skip = criteria._skip if criteria._skip
|
18
|
-
self._limit = criteria._limit if criteria._limit
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
15
|
private
|
23
16
|
|
24
17
|
def compile_rql_pass2
|
25
18
|
rql = super
|
26
|
-
rql = rql.skip(
|
27
|
-
rql = rql.limit(
|
19
|
+
rql = rql.skip(@options[:skip]) if @options[:skip]
|
20
|
+
rql = rql.limit(@options[:limit]) if @options[:limit]
|
28
21
|
rql
|
29
22
|
end
|
30
23
|
end
|
@@ -1,12 +1,8 @@
|
|
1
1
|
module NoBrainer::Criteria::OrderBy
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(options={})
|
7
|
-
super
|
8
|
-
self.order = {}
|
9
|
-
end
|
4
|
+
# The latest order_by() wins
|
5
|
+
included { criteria_option :order_by, :ordering_mode, :merge_with => :set_scalar }
|
10
6
|
|
11
7
|
def order_by(*rules, &block)
|
12
8
|
# Note: We are relying on the fact that Hashes are ordered (since 1.9)
|
@@ -21,34 +17,20 @@ module NoBrainer::Criteria::OrderBy
|
|
21
17
|
end
|
22
18
|
end.reduce({}, :merge)
|
23
19
|
|
24
|
-
chain
|
25
|
-
criteria.order = rules
|
26
|
-
criteria.ordering_mode = :normal
|
27
|
-
end
|
20
|
+
chain(:order_by => rules, :ordering_mode => :normal)
|
28
21
|
end
|
29
22
|
|
30
23
|
def without_ordering
|
31
|
-
chain
|
32
|
-
end
|
33
|
-
|
34
|
-
def merge!(criteria, options={})
|
35
|
-
super
|
36
|
-
# The latest order_by() wins
|
37
|
-
self.order = criteria.order if criteria.order.present?
|
38
|
-
self.ordering_mode = criteria.ordering_mode unless criteria.ordering_mode.nil?
|
39
|
-
self
|
24
|
+
chain(:ordering_mode => :disabled)
|
40
25
|
end
|
41
26
|
|
42
27
|
def reverse_order
|
43
|
-
chain
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
when :disabled then :disabled
|
50
|
-
end
|
51
|
-
end
|
28
|
+
chain(:ordering_mode => case @options[:ordering_mode]
|
29
|
+
when nil then :reversed
|
30
|
+
when :normal then :reversed
|
31
|
+
when :reversed then :normal
|
32
|
+
when :disabled then :disabled
|
33
|
+
end)
|
52
34
|
end
|
53
35
|
|
54
36
|
def order_by_indexed?
|
@@ -62,15 +44,15 @@ module NoBrainer::Criteria::OrderBy
|
|
62
44
|
private
|
63
45
|
|
64
46
|
def effective_order
|
65
|
-
|
47
|
+
@options[:order_by].presence || (model ? {model.pk_name => :asc} : {})
|
66
48
|
end
|
67
49
|
|
68
50
|
def reverse_order?
|
69
|
-
|
51
|
+
@options[:ordering_mode] == :reversed
|
70
52
|
end
|
71
53
|
|
72
54
|
def should_order?
|
73
|
-
|
55
|
+
@options[:ordering_mode] != :disabled
|
74
56
|
end
|
75
57
|
|
76
58
|
class IndexFinder < Struct.new(:criteria, :index_name, :rql_proc)
|
@@ -90,8 +72,8 @@ module NoBrainer::Criteria::OrderBy
|
|
90
72
|
return if criteria.without_index?
|
91
73
|
return unless first_key_indexable?
|
92
74
|
|
93
|
-
if criteria.
|
94
|
-
return unless first_key.to_s == criteria.
|
75
|
+
if criteria.options[:use_index] && criteria.options[:use_index] != true
|
76
|
+
return unless first_key.to_s == criteria.options[:use_index].to_s
|
95
77
|
end
|
96
78
|
|
97
79
|
# We need make sure that the where index finder has been invoked, it has priority.
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module NoBrainer::Criteria::Pluck
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :missing_attributes, :merge_with =>
|
5
|
+
NoBrainer::Criteria::Pluck.method(:merge_missing_attributes) }
|
5
6
|
|
6
7
|
def pluck(*attrs)
|
7
8
|
_missing_attributes_criteria(:pluck, attrs)
|
@@ -16,24 +17,19 @@ module NoBrainer::Criteria::Pluck
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def without_plucking
|
19
|
-
chain
|
20
|
+
chain(:missing_attributes => :remove)
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
-
return
|
23
|
+
def self.merge_missing_attributes(a, b)
|
24
|
+
return nil if b.nil? || b == :remove
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
old_attrs = self.missing_attributes[type] || {}.with_indifferent_access
|
31
|
-
new_attrs = old_attrs.deep_merge(attrs)
|
32
|
-
self.missing_attributes[type] = new_attrs
|
33
|
-
end
|
26
|
+
a = a ? a.dup : {}
|
27
|
+
b.each do |type, attrs|
|
28
|
+
old_attrs = a[type] || {}.with_indifferent_access
|
29
|
+
new_attrs = old_attrs.deep_merge(attrs)
|
30
|
+
a[type] = new_attrs
|
34
31
|
end
|
35
|
-
|
36
|
-
self
|
32
|
+
a
|
37
33
|
end
|
38
34
|
|
39
35
|
private
|
@@ -41,16 +37,14 @@ module NoBrainer::Criteria::Pluck
|
|
41
37
|
def _missing_attributes_criteria(type, args)
|
42
38
|
raise ArgumentError if args.size.zero?
|
43
39
|
args = [Hash[args.flatten.map { |k| [k, true] }]] unless args.size == 1 && args.first.is_a?(Hash)
|
44
|
-
chain
|
45
|
-
|
40
|
+
chain(:missing_attributes => {type => args.first})
|
46
41
|
end
|
47
42
|
|
48
43
|
def effective_missing_attributes
|
49
|
-
return nil if
|
44
|
+
return nil if @options[:missing_attributes].nil?
|
50
45
|
@effective_missing_attributes ||= begin
|
51
46
|
# pluck gets priority
|
52
|
-
|
53
|
-
missing_attributes = Hash[self.missing_attributes.map do |type, attrs|
|
47
|
+
missing_attributes = Hash[@options[:missing_attributes].map do |type, attrs|
|
54
48
|
attrs = attrs.select { |k,v| v } # TODO recursive
|
55
49
|
attrs.empty? ? nil : [type, attrs]
|
56
50
|
end.compact]
|
@@ -65,9 +59,9 @@ module NoBrainer::Criteria::Pluck
|
|
65
59
|
end
|
66
60
|
|
67
61
|
def _instantiate_model(attrs, options={})
|
68
|
-
return super if missing_attributes.nil?
|
62
|
+
return super if @options[:missing_attributes].nil?
|
69
63
|
super(attrs, options.merge(:missing_attributes => effective_missing_attributes,
|
70
|
-
:lazy_fetch => missing_attributes[:lazy_fetch]))
|
64
|
+
:lazy_fetch => @options[:missing_attributes][:lazy_fetch]))
|
71
65
|
end
|
72
66
|
|
73
67
|
def compile_rql_pass2
|
@@ -1,24 +1,18 @@
|
|
1
1
|
module NoBrainer::Criteria::Preload
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
5
|
-
|
6
|
-
def initialize(options={})
|
7
|
-
super
|
8
|
-
self._preloads = []
|
9
|
-
end
|
4
|
+
included { criteria_option :preload, :merge_with => :append_array }
|
10
5
|
|
11
6
|
def preload(*values)
|
12
|
-
chain(:
|
7
|
+
chain({:preload => values}, :copy_cache_from => self)
|
13
8
|
end
|
14
9
|
|
15
10
|
def merge!(criteria, options={})
|
16
|
-
super
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
perform_preloads(@cache)
|
11
|
+
super.tap do
|
12
|
+
# XXX Not pretty hack
|
13
|
+
if criteria.options[:preload].present? && criteria.cached?
|
14
|
+
perform_preloads(@cache)
|
15
|
+
end
|
22
16
|
end
|
23
17
|
end
|
24
18
|
|
@@ -35,7 +29,7 @@ module NoBrainer::Criteria::Preload
|
|
35
29
|
private
|
36
30
|
|
37
31
|
def should_preloads?
|
38
|
-
|
32
|
+
@options[:preload].present? && !raw?
|
39
33
|
end
|
40
34
|
|
41
35
|
def get_one(criteria)
|
@@ -44,7 +38,7 @@ module NoBrainer::Criteria::Preload
|
|
44
38
|
|
45
39
|
def perform_preloads(docs)
|
46
40
|
if should_preloads? && docs.present?
|
47
|
-
NoBrainer::Document::Association::EagerLoader.new.eager_load(docs,
|
41
|
+
NoBrainer::Document::Association::EagerLoader.new.eager_load(docs, @options[:preload])
|
48
42
|
end
|
49
43
|
end
|
50
44
|
end
|
@@ -1,20 +1,14 @@
|
|
1
1
|
module NoBrainer::Criteria::Raw
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :raw, :merge_with => :set_scalar }
|
5
5
|
|
6
|
-
def raw
|
7
|
-
chain
|
8
|
-
end
|
9
|
-
|
10
|
-
def merge!(criteria, options={})
|
11
|
-
super
|
12
|
-
self._raw = criteria._raw unless criteria._raw.nil?
|
13
|
-
self
|
6
|
+
def raw(value = true)
|
7
|
+
chain(:raw => value)
|
14
8
|
end
|
15
9
|
|
16
10
|
def raw?
|
17
|
-
!!finalized_criteria.
|
11
|
+
!!finalized_criteria.options[:raw]
|
18
12
|
end
|
19
13
|
|
20
14
|
private
|
@@ -1,20 +1,14 @@
|
|
1
1
|
module NoBrainer::Criteria::Scope
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included {
|
4
|
+
included { criteria_option :use_default_scope, :merge_with => :set_scalar }
|
5
5
|
|
6
6
|
def scoped
|
7
|
-
chain
|
7
|
+
chain(:use_default_scope => true)
|
8
8
|
end
|
9
9
|
|
10
10
|
def unscoped
|
11
|
-
chain
|
12
|
-
end
|
13
|
-
|
14
|
-
def merge!(criteria, options={})
|
15
|
-
super
|
16
|
-
self.use_default_scope = criteria.use_default_scope unless criteria.use_default_scope.nil?
|
17
|
-
self
|
11
|
+
chain(:use_default_scope => false)
|
18
12
|
end
|
19
13
|
|
20
14
|
def respond_to?(name, include_private = false)
|
@@ -31,7 +25,7 @@ module NoBrainer::Criteria::Scope
|
|
31
25
|
private
|
32
26
|
|
33
27
|
def should_apply_default_scope?
|
34
|
-
model.default_scope_proc && use_default_scope != false
|
28
|
+
model.default_scope_proc && @options[:use_default_scope] != false
|
35
29
|
end
|
36
30
|
|
37
31
|
def _apply_default_scope
|
@@ -1,35 +1,20 @@
|
|
1
1
|
module NoBrainer::Criteria::Where
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
|
-
included
|
5
|
-
|
6
|
-
def initialize(options={})
|
7
|
-
super
|
4
|
+
included do
|
5
|
+
criteria_option :where_ast, :merge_with => NoBrainer::Criteria::Where.method(:merge_where_ast)
|
8
6
|
end
|
9
7
|
|
10
8
|
def where(*args, &block)
|
11
|
-
chain
|
9
|
+
chain(:where_ast => parse_clause([*args, block].compact))
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
if criteria.where_ast
|
18
|
-
if self.where_ast
|
19
|
-
self.where_ast = MultiOperator.new(:and, [self.where_ast, criteria.where_ast])
|
20
|
-
else
|
21
|
-
self.where_ast = criteria.where_ast
|
22
|
-
end
|
23
|
-
self.where_ast = self.where_ast.simplify
|
24
|
-
raise unless criteria.where_ast.is_a?(MultiOperator)
|
25
|
-
end
|
26
|
-
|
27
|
-
self.with_index_name = criteria.with_index_name unless criteria.with_index_name.nil?
|
28
|
-
self
|
12
|
+
def self.merge_where_ast(a, b)
|
13
|
+
(a ? MultiOperator.new(:and, [a, b]) : b).simplify
|
29
14
|
end
|
30
15
|
|
31
16
|
def where_present?
|
32
|
-
finalized_criteria.where_ast.try(:clauses).present?
|
17
|
+
finalized_criteria.options[:where_ast].try(:clauses).present?
|
33
18
|
end
|
34
19
|
|
35
20
|
def where_indexed?
|
@@ -232,8 +217,8 @@ module NoBrainer::Criteria::Where
|
|
232
217
|
@usable_indexes[types] ||= begin
|
233
218
|
indexes = criteria.model.indexes.values
|
234
219
|
indexes = indexes.select { |i| types.include?(i.kind) } if types.present?
|
235
|
-
if criteria.
|
236
|
-
indexes = indexes.select { |i| i.name == criteria.
|
220
|
+
if criteria.options[:use_index] && criteria.options[:use_index] != true
|
221
|
+
indexes = indexes.select { |i| i.name == criteria.options[:use_index].to_sym }
|
237
222
|
end
|
238
223
|
indexes
|
239
224
|
end
|
@@ -327,7 +312,7 @@ module NoBrainer::Criteria::Where
|
|
327
312
|
|
328
313
|
def where_index_finder
|
329
314
|
return finalized_criteria.__send__(:where_index_finder) unless finalized?
|
330
|
-
@where_index_finder ||= IndexFinder.new(self, where_ast).tap { |index_finder| index_finder.find_index }
|
315
|
+
@where_index_finder ||= IndexFinder.new(self, @options[:where_ast]).tap { |index_finder| index_finder.find_index }
|
331
316
|
end
|
332
317
|
|
333
318
|
def compile_rql_pass1
|
@@ -338,7 +323,7 @@ module NoBrainer::Criteria::Where
|
|
338
323
|
|
339
324
|
def compile_rql_pass2
|
340
325
|
rql = super
|
341
|
-
ast = where_index_finder.could_find_index? ? where_index_finder.ast :
|
326
|
+
ast = where_index_finder.could_find_index? ? where_index_finder.ast : @options[:where_ast]
|
342
327
|
rql = rql.filter { |doc| ast.to_rql(doc) } if ast.try(:clauses).present?
|
343
328
|
rql
|
344
329
|
end
|
@@ -45,14 +45,15 @@ class NoBrainer::Document::Association::EagerLoader
|
|
45
45
|
when Hash then preloads.each do |k,v|
|
46
46
|
if v.is_a?(NoBrainer::Criteria)
|
47
47
|
v = v.dup
|
48
|
-
nested_preloads, v.
|
48
|
+
nested_preloads, v.options[:preload] = v.options[:preload], []
|
49
49
|
eager_load(eager_load_association(docs, k, v), nested_preloads)
|
50
50
|
else
|
51
51
|
eager_load(eager_load_association(docs, k), v)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
when Array then preloads.each { |v| eager_load(docs, v) }
|
55
|
-
|
55
|
+
when nil then;
|
56
|
+
else eager_load_association(docs, preloads) # String and Symbol
|
56
57
|
end
|
57
58
|
true
|
58
59
|
end
|