nobrainer 0.18.0 → 0.22.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.
- checksums.yaml +4 -4
- data/lib/no_brainer/autoload.rb +0 -5
- data/lib/no_brainer/config.rb +73 -39
- data/lib/no_brainer/connection.rb +2 -4
- data/lib/no_brainer/criteria/after_find.rb +3 -11
- data/lib/no_brainer/criteria/aggregate.rb +2 -2
- data/lib/no_brainer/criteria/cache.rb +15 -10
- data/lib/no_brainer/criteria/core.rb +46 -11
- data/lib/no_brainer/criteria/delete.rb +2 -2
- data/lib/no_brainer/criteria/eager_load.rb +51 -0
- data/lib/no_brainer/criteria/extend.rb +4 -16
- data/lib/no_brainer/criteria/find.rb +27 -0
- 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 +20 -36
- data/lib/no_brainer/criteria/pluck.rb +16 -22
- data/lib/no_brainer/criteria/raw.rb +4 -10
- data/lib/no_brainer/criteria/scope.rb +6 -19
- data/lib/no_brainer/criteria/update.rb +8 -6
- data/lib/no_brainer/criteria/where.rb +252 -138
- data/lib/no_brainer/criteria.rb +3 -2
- data/lib/no_brainer/document/aliases.rb +3 -3
- data/lib/no_brainer/document/association/belongs_to.rb +9 -5
- data/lib/no_brainer/document/association/core.rb +6 -5
- data/lib/no_brainer/document/association/eager_loader.rb +9 -9
- data/lib/no_brainer/document/association/has_many.rb +23 -9
- data/lib/no_brainer/document/association/has_many_through.rb +12 -3
- data/lib/no_brainer/document/atomic_ops.rb +79 -78
- data/lib/no_brainer/document/attributes.rb +24 -20
- data/lib/no_brainer/document/callbacks.rb +1 -1
- data/lib/no_brainer/document/core.rb +5 -2
- data/lib/no_brainer/document/criteria.rb +14 -19
- data/lib/no_brainer/document/dirty.rb +11 -16
- data/lib/no_brainer/document/index/index.rb +2 -1
- data/lib/no_brainer/document/index/meta_store.rb +1 -1
- data/lib/no_brainer/document/index.rb +14 -10
- data/lib/no_brainer/document/persistance.rb +24 -13
- data/lib/no_brainer/document/primary_key/generator.rb +83 -0
- data/lib/no_brainer/document/{id.rb → primary_key.rb} +9 -36
- data/lib/no_brainer/document/store_in.rb +2 -2
- data/lib/no_brainer/document/timestamps.rb +4 -2
- data/lib/no_brainer/document/types/binary.rb +2 -7
- data/lib/no_brainer/document/types/boolean.rb +2 -4
- data/lib/no_brainer/document/types/date.rb +2 -2
- data/lib/no_brainer/document/types/float.rb +2 -2
- data/lib/no_brainer/document/types/geo.rb +1 -0
- data/lib/no_brainer/document/types/integer.rb +2 -2
- data/lib/no_brainer/document/types/set.rb +2 -2
- data/lib/no_brainer/document/types/string.rb +5 -2
- data/lib/no_brainer/document/types/symbol.rb +2 -2
- data/lib/no_brainer/document/types/text.rb +18 -0
- data/lib/no_brainer/document/types/time.rb +2 -2
- data/lib/no_brainer/document/types.rb +17 -18
- data/lib/no_brainer/document/validation/not_null.rb +15 -0
- data/lib/no_brainer/document/{uniqueness.rb → validation/uniqueness.rb} +11 -11
- data/lib/no_brainer/document/validation.rb +35 -6
- data/lib/no_brainer/document.rb +1 -1
- data/lib/no_brainer/error.rb +21 -19
- data/lib/no_brainer/geo/base.rb +16 -0
- data/lib/no_brainer/geo/circle.rb +25 -0
- data/lib/no_brainer/geo/line_string.rb +11 -0
- data/lib/no_brainer/geo/point.rb +49 -0
- data/lib/no_brainer/geo/polygon.rb +11 -0
- data/lib/no_brainer/geo.rb +4 -0
- data/lib/no_brainer/locale/en.yml +1 -0
- data/lib/no_brainer/lock.rb +114 -0
- data/lib/no_brainer/query_runner/connection_lock.rb +1 -1
- data/lib/no_brainer/query_runner/database_on_demand.rb +0 -1
- data/lib/no_brainer/query_runner/missing_index.rb +1 -1
- data/lib/no_brainer/query_runner/reconnect.rb +9 -11
- data/lib/no_brainer/query_runner/run_options.rb +0 -3
- data/lib/no_brainer/query_runner/table_on_demand.rb +3 -4
- data/lib/no_brainer/railtie/database.rake +2 -2
- data/lib/no_brainer/rql.rb +1 -5
- data/lib/nobrainer.rb +2 -6
- data/lib/rails/generators/nobrainer.rb +1 -1
- metadata +34 -9
- data/lib/no_brainer/criteria/preload.rb +0 -50
- data/lib/no_brainer/decorated_symbol.rb +0 -17
|
@@ -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)
|
|
@@ -83,15 +65,17 @@ module NoBrainer::Criteria::OrderBy
|
|
|
83
65
|
end
|
|
84
66
|
|
|
85
67
|
def first_key_indexable?
|
|
86
|
-
|
|
68
|
+
return false unless first_key.is_a?(Symbol) || first_key.is_a?(String)
|
|
69
|
+
return false unless index = criteria.model.indexes[first_key.to_sym]
|
|
70
|
+
return !index.multi && !index.geo
|
|
87
71
|
end
|
|
88
72
|
|
|
89
73
|
def find_index
|
|
90
74
|
return if criteria.without_index?
|
|
91
75
|
return unless first_key_indexable?
|
|
92
76
|
|
|
93
|
-
if criteria.
|
|
94
|
-
return unless first_key.to_s == criteria.
|
|
77
|
+
if criteria.options[:use_index] && criteria.options[:use_index] != true
|
|
78
|
+
return unless first_key.to_s == criteria.options[:use_index].to_s
|
|
95
79
|
end
|
|
96
80
|
|
|
97
81
|
# We need make sure that the where index finder has been invoked, it has priority.
|
|
@@ -105,7 +89,7 @@ module NoBrainer::Criteria::OrderBy
|
|
|
105
89
|
|
|
106
90
|
def order_by_index_finder
|
|
107
91
|
return finalized_criteria.__send__(:order_by_index_finder) unless finalized?
|
|
108
|
-
@order_by_index_finder ||= IndexFinder.new(self).tap
|
|
92
|
+
@order_by_index_finder ||= IndexFinder.new(self).tap(&:find_index)
|
|
109
93
|
end
|
|
110
94
|
|
|
111
95
|
def compile_rql_pass1
|
|
@@ -150,6 +134,6 @@ module NoBrainer::Criteria::OrderBy
|
|
|
150
134
|
end
|
|
151
135
|
|
|
152
136
|
def raise_bad_rule(rule)
|
|
153
|
-
raise "
|
|
137
|
+
raise "order_by() takes arguments such as `:field1 => :desc, :field2 => :asc', not `#{rule}'"
|
|
154
138
|
end
|
|
155
139
|
end
|
|
@@ -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,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)
|
|
@@ -30,21 +24,14 @@ module NoBrainer::Criteria::Scope
|
|
|
30
24
|
|
|
31
25
|
private
|
|
32
26
|
|
|
33
|
-
def should_apply_default_scope?
|
|
34
|
-
model.default_scope_proc && use_default_scope != false
|
|
35
|
-
end
|
|
36
|
-
|
|
37
27
|
def _apply_default_scope
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
raise "Mixing model issue. Contact developer." if [criteria.model, self.model].compact.uniq.size == 2
|
|
41
|
-
criteria.merge(self)
|
|
28
|
+
return self if @options[:use_default_scope] == false
|
|
29
|
+
(model.default_scopes.map(&:call).compact + [self]).reduce(:merge)
|
|
42
30
|
end
|
|
43
31
|
|
|
44
32
|
module ClassMethods
|
|
45
33
|
def _finalize_criteria(base)
|
|
46
|
-
|
|
47
|
-
criteria.__send__(:_apply_default_scope) || criteria
|
|
34
|
+
super.__send__(:_apply_default_scope)
|
|
48
35
|
end
|
|
49
36
|
end
|
|
50
37
|
end
|
|
@@ -2,18 +2,20 @@ module NoBrainer::Criteria::Update
|
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
4
|
def update_all(*a, &b)
|
|
5
|
-
|
|
6
|
-
run { without_ordering.without_plucking.to_rql.update(*a, &b) }
|
|
5
|
+
perform_update(:update, a, b)
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
def replace_all(*a, &b)
|
|
10
|
-
|
|
11
|
-
run { without_ordering.without_plucking.to_rql.replace(*a, &b) }
|
|
9
|
+
perform_update(:replace, a, b)
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
private
|
|
15
13
|
|
|
16
|
-
def
|
|
17
|
-
|
|
14
|
+
def perform_update(type, args, block)
|
|
15
|
+
args[0] = model.persistable_attributes(args[0]) if !args.empty? && args.first.is_a?(Hash)
|
|
16
|
+
# can't use without_distinct when passed a block as the operation may be
|
|
17
|
+
# performed many times, which might not be idempotent.
|
|
18
|
+
clause = block ? self : without_distinct
|
|
19
|
+
run { clause.without_plucking.to_rql.__send__(type, *args, &block) }
|
|
18
20
|
end
|
|
19
21
|
end
|