active_any 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|