active_any 0.0.1
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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +27 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +92 -0
- data/Rakefile +12 -0
- data/active_any.gemspec +36 -0
- data/bin/console +12 -0
- data/bin/setup +8 -0
- data/lib/active_any/adapter.rb +13 -0
- data/lib/active_any/adapters/abstract_adapter.rb +27 -0
- data/lib/active_any/adapters/object_adapter.rb +74 -0
- data/lib/active_any/association_relation.rb +18 -0
- data/lib/active_any/associations/association.rb +94 -0
- data/lib/active_any/associations/association_scope.rb +35 -0
- data/lib/active_any/associations/belongs_to_association.rb +21 -0
- data/lib/active_any/associations/builder/association.rb +62 -0
- data/lib/active_any/associations/builder/belongs_to.rb +13 -0
- data/lib/active_any/associations/builder/has_many.rb +17 -0
- data/lib/active_any/associations/collection_proxy.rb +66 -0
- data/lib/active_any/associations/has_many_association.rb +43 -0
- data/lib/active_any/associations.rb +72 -0
- data/lib/active_any/attribute_assignment.rb +16 -0
- data/lib/active_any/core.rb +26 -0
- data/lib/active_any/finders.rb +28 -0
- data/lib/active_any/reflection/association_reflection.rb +88 -0
- data/lib/active_any/reflection/belongs_to_reflection.rb +29 -0
- data/lib/active_any/reflection/has_many_reflection.rb +29 -0
- data/lib/active_any/reflection.rb +49 -0
- data/lib/active_any/relation/merger.rb +72 -0
- data/lib/active_any/relation/order_clause.rb +60 -0
- data/lib/active_any/relation/where_clause.rb +73 -0
- data/lib/active_any/relation.rb +243 -0
- data/lib/active_any/version.rb +5 -0
- data/lib/active_any.rb +62 -0
- metadata +251 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Associations
|
5
|
+
class CollectionProxy < ActiveAny::Relation
|
6
|
+
attr_reader :association
|
7
|
+
|
8
|
+
delegate :target, :load_target, :load_target,
|
9
|
+
:size, :empty?, :include?, to: :@association
|
10
|
+
|
11
|
+
def initialize(klass, association)
|
12
|
+
@association = association
|
13
|
+
super(klass)
|
14
|
+
end
|
15
|
+
|
16
|
+
def take(limit = nil)
|
17
|
+
load_target if find_from_target?
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def scope
|
22
|
+
@scope ||= @association.scope
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
load_target == other
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_ary
|
30
|
+
load_target.dup
|
31
|
+
end
|
32
|
+
alias to_a to_ary
|
33
|
+
|
34
|
+
def records
|
35
|
+
load_target
|
36
|
+
end
|
37
|
+
|
38
|
+
def proxy_association
|
39
|
+
@association
|
40
|
+
end
|
41
|
+
|
42
|
+
def reset
|
43
|
+
proxy_association.reset
|
44
|
+
proxy_association.reset_scope
|
45
|
+
reset_scope
|
46
|
+
end
|
47
|
+
|
48
|
+
def reload
|
49
|
+
proxy_association.reload
|
50
|
+
reset_scope
|
51
|
+
end
|
52
|
+
|
53
|
+
def reset_scope # :nodoc:
|
54
|
+
@offsets = {}
|
55
|
+
@scope = nil
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def find_from_target?
|
62
|
+
@association.find_from_target?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Associations
|
5
|
+
class HasManyAssociation < Association
|
6
|
+
def reader
|
7
|
+
# TODO: implement
|
8
|
+
# reload if stale_target?
|
9
|
+
|
10
|
+
@proxy ||= CollectionProxy.create(owner, self)
|
11
|
+
@proxy.reset_scope
|
12
|
+
end
|
13
|
+
|
14
|
+
def writer(_records)
|
15
|
+
raise NotImplementedError.new, 'writer is unimplemented'
|
16
|
+
end
|
17
|
+
|
18
|
+
def size
|
19
|
+
if !find_target? || loaded?
|
20
|
+
target.size
|
21
|
+
else
|
22
|
+
scope.count
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def empty?
|
27
|
+
size.zero?
|
28
|
+
end
|
29
|
+
|
30
|
+
def include?(record)
|
31
|
+
if record.is_a?(klass)
|
32
|
+
target.include?(record)
|
33
|
+
else
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_target
|
39
|
+
scope.to_a
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_any/associations/collection_proxy'
|
4
|
+
require 'active_any/associations/association_scope'
|
5
|
+
require 'active_any/associations/builder/association'
|
6
|
+
require 'active_any/associations/builder/has_many'
|
7
|
+
require 'active_any/associations/builder/belongs_to'
|
8
|
+
require 'active_any/associations/association'
|
9
|
+
require 'active_any/associations/has_many_association'
|
10
|
+
require 'active_any/associations/belongs_to_association'
|
11
|
+
|
12
|
+
module ActiveAny
|
13
|
+
module Associations
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
class AssociationNotFoundError < StandardError
|
17
|
+
def initialize(record = nil, association_name = nil)
|
18
|
+
if record && association_name
|
19
|
+
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
20
|
+
else
|
21
|
+
super('Association was not found.')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def has_many(name, scope = nil, options = {})
|
28
|
+
reflection = Builder::HasMany.build(self, name, scope, options)
|
29
|
+
Reflection.add_reflection self, name, reflection
|
30
|
+
end
|
31
|
+
|
32
|
+
def belongs_to(name, scope = nil, options = {})
|
33
|
+
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
34
|
+
Reflection.add_reflection self, name, reflection
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize_dup(*)
|
39
|
+
@association_cache = {}
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def init_internals(*)
|
46
|
+
@association_cache = {}
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def association(name)
|
51
|
+
association = association_instance_get(name)
|
52
|
+
|
53
|
+
if association.nil?
|
54
|
+
reflection = self.class.reflections[name.to_s]
|
55
|
+
raise AssociationNotFoundError.new(self, name) unless reflection
|
56
|
+
|
57
|
+
association = reflection.association_class.new(self, reflection)
|
58
|
+
association_instance_set(name, association)
|
59
|
+
end
|
60
|
+
|
61
|
+
association
|
62
|
+
end
|
63
|
+
|
64
|
+
def association_instance_get(name)
|
65
|
+
@association_cache[name]
|
66
|
+
end
|
67
|
+
|
68
|
+
def association_instance_set(name, association)
|
69
|
+
@association_cache[name] = association
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module AttributeAssignment
|
5
|
+
def init_internals(attributes = {})
|
6
|
+
assign_attributes(attributes) if attributes.present?
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def assign_attributes(data)
|
11
|
+
data.each do |key, value|
|
12
|
+
public_send("#{key}=", value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Core
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
class_attribute :abstract_class, instance_writer: false
|
9
|
+
class_attribute :primary_key, instance_writer: false
|
10
|
+
self.abstract_class = true
|
11
|
+
self.primary_key = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
class_methods do
|
15
|
+
delegate :take, :take!, :first, :last, to: :all
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(*args)
|
19
|
+
init_internals(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def init_internals(*); end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Finders
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
delegate :find_by, :limit, :where, :take, :group, :order, to: :all
|
9
|
+
|
10
|
+
def all
|
11
|
+
Relation.create(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_by_query(where_clause:, limit_value:, group_values:, order_clause:)
|
15
|
+
adapter.query(
|
16
|
+
where_clause: where_clause,
|
17
|
+
limit_value: limit_value,
|
18
|
+
group_values: group_values,
|
19
|
+
order_clause: order_clause
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def adapter
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Reflection
|
5
|
+
class AssociationReflection
|
6
|
+
attr_reader :name, :scope, :options, :record_class
|
7
|
+
|
8
|
+
def initialize(name, scope, options, record_class)
|
9
|
+
@name = name
|
10
|
+
@record_class = record_class
|
11
|
+
@options = options
|
12
|
+
@scope = scope
|
13
|
+
end
|
14
|
+
|
15
|
+
def association_class
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def marco
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
def class_name
|
24
|
+
@class_name ||= (options[:class_name] || derive_class_name).to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def klass
|
28
|
+
@klass ||= compute_class(class_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def compute_class(name)
|
32
|
+
name.constantize
|
33
|
+
end
|
34
|
+
|
35
|
+
def collection?
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
def belongs_to?
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
JoinKeys = Struct.new(:key, :foreign_key)
|
44
|
+
|
45
|
+
def join_keys
|
46
|
+
JoinKeys.new(join_pk, join_fk)
|
47
|
+
end
|
48
|
+
|
49
|
+
def foreign_key
|
50
|
+
@foreign_key ||= options[:foreign_key] || derive_foreign_key.freeze
|
51
|
+
end
|
52
|
+
|
53
|
+
def primary_key
|
54
|
+
@primary_key ||= options[:primary_key] || primary_key_for_record_class
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def join_pk
|
60
|
+
raise NotImplementedError
|
61
|
+
end
|
62
|
+
|
63
|
+
def join_fk
|
64
|
+
raise NotImplementedError
|
65
|
+
end
|
66
|
+
|
67
|
+
def primary_key_for_record_class
|
68
|
+
klass.primary_key || (raise UnknownPrimaryKey.new, klass)
|
69
|
+
end
|
70
|
+
|
71
|
+
def derive_class_name
|
72
|
+
class_name = name.to_s
|
73
|
+
class_name = class_name.singularize if collection?
|
74
|
+
class_name.camelize
|
75
|
+
end
|
76
|
+
|
77
|
+
def derive_foreign_key
|
78
|
+
if belongs_to?
|
79
|
+
"#{name}_id"
|
80
|
+
elsif options[:as]
|
81
|
+
"#{options[:as]}_id"
|
82
|
+
else
|
83
|
+
record_class.name.foreign_key
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Reflection
|
5
|
+
class BelongsToReflection < AssociationReflection
|
6
|
+
def association_class
|
7
|
+
Associations::BelongsToAssociation
|
8
|
+
end
|
9
|
+
|
10
|
+
def macro
|
11
|
+
:belongs_to
|
12
|
+
end
|
13
|
+
|
14
|
+
def belongs_to?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def join_pk
|
21
|
+
primary_key
|
22
|
+
end
|
23
|
+
|
24
|
+
def join_fk
|
25
|
+
foreign_key
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
module Reflection
|
5
|
+
class HasManyReflection < AssociationReflection
|
6
|
+
def association_class
|
7
|
+
Associations::HasManyAssociation
|
8
|
+
end
|
9
|
+
|
10
|
+
def macro
|
11
|
+
:has_many
|
12
|
+
end
|
13
|
+
|
14
|
+
def collection?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def join_pk
|
21
|
+
foreign_key
|
22
|
+
end
|
23
|
+
|
24
|
+
def join_fk
|
25
|
+
primary_key
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_any/reflection/association_reflection'
|
4
|
+
require 'active_any/reflection/has_many_reflection'
|
5
|
+
require 'active_any/reflection/belongs_to_reflection'
|
6
|
+
|
7
|
+
module ActiveAny
|
8
|
+
module Reflection
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
class_attribute :reflections, instance_writer: false
|
13
|
+
self.reflections = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
class UnknownPrimaryKey < StandardError
|
17
|
+
attr_reader :model
|
18
|
+
|
19
|
+
def initialize(model = nil, description = nil)
|
20
|
+
if model
|
21
|
+
message = "Unknown primary key for table #{model.table_name} in model #{model}."
|
22
|
+
message += "\n#{description}" if description
|
23
|
+
@model = model
|
24
|
+
super(message)
|
25
|
+
else
|
26
|
+
super('Unknown primary key.')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.create(macro, name, scope, options, klass)
|
32
|
+
reflection_class =
|
33
|
+
case macro
|
34
|
+
when :belongs_to
|
35
|
+
BelongsToReflection
|
36
|
+
when :has_many
|
37
|
+
HasManyReflection
|
38
|
+
else
|
39
|
+
raise "Unsupported Macro: #{macro}"
|
40
|
+
end
|
41
|
+
|
42
|
+
reflection_class.new(name, scope, options, klass)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.add_reflection(klass, name, reflection)
|
46
|
+
klass.reflections = klass.reflections.merge(name.to_s => reflection)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
class Relation
|
5
|
+
class HashMerger
|
6
|
+
attr_reader :relation, :hash
|
7
|
+
|
8
|
+
def initialize(relation, hash)
|
9
|
+
hash.assert_valid_keys(*Relation::VALUE_METHODS)
|
10
|
+
|
11
|
+
@relation = relation
|
12
|
+
@hash = hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def merge
|
16
|
+
Merger.new(relation, other).merge
|
17
|
+
end
|
18
|
+
|
19
|
+
def other
|
20
|
+
other = Relation.create(relation.klass)
|
21
|
+
hash.each { |k, v| other.public_send("#{k}!", v) }
|
22
|
+
other
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Merger
|
27
|
+
attr_reader :relation, :values, :other
|
28
|
+
|
29
|
+
def initialize(relation, other)
|
30
|
+
@relation = relation
|
31
|
+
@values = other.values
|
32
|
+
@other = other
|
33
|
+
end
|
34
|
+
|
35
|
+
def normal_values
|
36
|
+
Relation::VALUE_METHODS -
|
37
|
+
Relation::CLAUSE_METHODS -
|
38
|
+
%i[includes preload joins order reverse_order lock create_with reordering]
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge
|
42
|
+
normal_values.each do |name|
|
43
|
+
value = values[name]
|
44
|
+
relation.send("#{name}!", *value) unless value.nil? || (value.blank? && value != false)
|
45
|
+
end
|
46
|
+
|
47
|
+
merge_multi_values
|
48
|
+
merge_single_values
|
49
|
+
merge_clauses
|
50
|
+
|
51
|
+
relation
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def merge_multi_values
|
57
|
+
relation.order! other.order_clause unless other.order_clause.empty?
|
58
|
+
relation.group! other.group_values if other.group_values
|
59
|
+
end
|
60
|
+
|
61
|
+
def merge_single_values; end
|
62
|
+
|
63
|
+
def merge_clauses
|
64
|
+
CLAUSE_METHODS.each do |method|
|
65
|
+
clause = relation.get_value(method)
|
66
|
+
other_clause = other.get_value(method)
|
67
|
+
relation.set_value(method, clause.merge(other_clause))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
class Relation
|
5
|
+
class OrderClause
|
6
|
+
def self.empty
|
7
|
+
new
|
8
|
+
end
|
9
|
+
|
10
|
+
OrderValue = Struct.new(:key, :sort_type)
|
11
|
+
|
12
|
+
attr_reader :order_values
|
13
|
+
|
14
|
+
def initialize(values = [], reverse = false)
|
15
|
+
@reverse = reverse
|
16
|
+
@order_values = convert_order_values(values)
|
17
|
+
end
|
18
|
+
|
19
|
+
def reverse?
|
20
|
+
@reverse
|
21
|
+
end
|
22
|
+
|
23
|
+
def reverse!
|
24
|
+
@reverse = true
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def +(other)
|
29
|
+
OrderClause.new(
|
30
|
+
order_values + other.order_values,
|
31
|
+
reverse? || other.reverse?
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
alias merge +
|
36
|
+
|
37
|
+
def ==(other)
|
38
|
+
reverse? == other.reverse? && order_values == other.order_values
|
39
|
+
end
|
40
|
+
|
41
|
+
def empty?
|
42
|
+
order_values.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def convert_order_values(values)
|
48
|
+
values.map do |arg|
|
49
|
+
case arg
|
50
|
+
when ::Hash then OrderValue.new(arg.keys.first, arg.values.first)
|
51
|
+
when ::Symbol, ::String then OrderValue.new(arg, :asc)
|
52
|
+
when OrderValue then arg
|
53
|
+
else
|
54
|
+
raise ArgumentError
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveAny
|
4
|
+
class Relation
|
5
|
+
class WhereClause
|
6
|
+
class Condition
|
7
|
+
attr_reader :key, :value
|
8
|
+
|
9
|
+
def initialize(key, value)
|
10
|
+
@key = key
|
11
|
+
@value = value
|
12
|
+
|
13
|
+
register_handler(BasicObject, :base_handler)
|
14
|
+
register_handler(Regexp, :regexp_handler)
|
15
|
+
register_handler(Range, :range_handler)
|
16
|
+
register_handler(Array, :array_handler)
|
17
|
+
end
|
18
|
+
|
19
|
+
def evaluate(adapter, record)
|
20
|
+
adapter.public_send(handle_for(value), record, key, value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_h
|
24
|
+
{ key => value }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def handle_for(value)
|
30
|
+
handlers.select { |klass, _| value.is_a?(klass) }.last.last
|
31
|
+
end
|
32
|
+
|
33
|
+
def handlers
|
34
|
+
@handlers ||= []
|
35
|
+
end
|
36
|
+
|
37
|
+
def register_handler(klass, method)
|
38
|
+
handlers << [klass, method]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :conditions
|
43
|
+
|
44
|
+
def initialize(hash = {}, conditions = nil)
|
45
|
+
@conditions = conditions ? conditions : hash.map { |key, value| Condition.new(key, value) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.empty
|
49
|
+
new
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
other.conditions.sort_by(&:key) == conditions.sort_by(&:key)
|
54
|
+
end
|
55
|
+
|
56
|
+
def +(other)
|
57
|
+
WhereClause.new({}, (conditions + other.conditions).flatten)
|
58
|
+
end
|
59
|
+
|
60
|
+
alias merge +
|
61
|
+
|
62
|
+
def merge!(hash)
|
63
|
+
hash.each do |key, value|
|
64
|
+
conditions << Condition.new(key, value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def all?(&block)
|
69
|
+
conditions.all?(&block)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|