cuprum-collections 0.1.0 → 0.3.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +321 -15
- data/lib/cuprum/collections/basic/collection.rb +13 -0
- data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -3
- data/lib/cuprum/collections/basic/commands/find_many.rb +1 -1
- data/lib/cuprum/collections/basic/commands/insert_one.rb +4 -3
- data/lib/cuprum/collections/basic/commands/update_one.rb +4 -3
- data/lib/cuprum/collections/basic/query.rb +3 -3
- data/lib/cuprum/collections/basic/repository.rb +67 -0
- data/lib/cuprum/collections/commands/abstract_find_many.rb +33 -32
- data/lib/cuprum/collections/commands/abstract_find_one.rb +4 -3
- data/lib/cuprum/collections/commands/create.rb +60 -0
- data/lib/cuprum/collections/commands/find_one_matching.rb +134 -0
- data/lib/cuprum/collections/commands/update.rb +74 -0
- data/lib/cuprum/collections/commands/upsert.rb +162 -0
- data/lib/cuprum/collections/commands.rb +7 -2
- data/lib/cuprum/collections/errors/abstract_find_error.rb +210 -0
- data/lib/cuprum/collections/errors/already_exists.rb +4 -72
- data/lib/cuprum/collections/errors/extra_attributes.rb +8 -18
- data/lib/cuprum/collections/errors/failed_validation.rb +5 -18
- data/lib/cuprum/collections/errors/invalid_parameters.rb +7 -15
- data/lib/cuprum/collections/errors/invalid_query.rb +5 -15
- data/lib/cuprum/collections/errors/missing_default_contract.rb +5 -17
- data/lib/cuprum/collections/errors/not_found.rb +4 -67
- data/lib/cuprum/collections/errors/not_unique.rb +18 -0
- data/lib/cuprum/collections/errors/unknown_operator.rb +7 -17
- data/lib/cuprum/collections/errors.rb +13 -1
- data/lib/cuprum/collections/queries/ordering.rb +4 -2
- data/lib/cuprum/collections/repository.rb +105 -0
- data/lib/cuprum/collections/rspec/assign_one_command_contract.rb +2 -2
- data/lib/cuprum/collections/rspec/build_one_command_contract.rb +1 -1
- data/lib/cuprum/collections/rspec/collection_contract.rb +140 -103
- data/lib/cuprum/collections/rspec/destroy_one_command_contract.rb +8 -6
- data/lib/cuprum/collections/rspec/find_many_command_contract.rb +114 -34
- data/lib/cuprum/collections/rspec/find_one_command_contract.rb +12 -9
- data/lib/cuprum/collections/rspec/insert_one_command_contract.rb +4 -3
- data/lib/cuprum/collections/rspec/query_contract.rb +3 -3
- data/lib/cuprum/collections/rspec/querying_contract.rb +2 -2
- data/lib/cuprum/collections/rspec/repository_contract.rb +235 -0
- data/lib/cuprum/collections/rspec/update_one_command_contract.rb +4 -3
- data/lib/cuprum/collections/version.rb +3 -3
- data/lib/cuprum/collections.rb +1 -0
- metadata +25 -91
@@ -17,39 +17,41 @@ module Cuprum::Collections::Commands
|
|
17
17
|
(scope || build_query).where { { key => one_of(primary_keys) } }
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
20
|
+
def build_results(items:, primary_keys:)
|
21
|
+
primary_keys.map do |primary_key_value|
|
22
|
+
next success(items[primary_key_value]) if items.key?(primary_key_value)
|
22
23
|
|
23
|
-
|
24
|
+
failure(not_found_error(primary_key_value))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_result_list(results, allow_partial:, envelope:)
|
29
|
+
unless envelope
|
30
|
+
return Cuprum::ResultList.new(*results, allow_partial: allow_partial)
|
31
|
+
end
|
24
32
|
|
25
|
-
|
33
|
+
value = envelope ? wrap_items(results.map(&:value)) : nil
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
35
|
+
Cuprum::ResultList.new(
|
36
|
+
*results,
|
37
|
+
allow_partial: allow_partial,
|
38
|
+
value: value
|
31
39
|
)
|
32
|
-
Cuprum::Result.new(error: error)
|
33
40
|
end
|
34
41
|
|
35
42
|
def items_with_primary_keys(items:)
|
36
43
|
# :nocov:
|
37
|
-
items.
|
44
|
+
items.to_h { |item| [item.send(primary_key_name), item] }
|
38
45
|
# :nocov:
|
39
46
|
end
|
40
47
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
item.nil? ? (missing << key) : (found << item)
|
50
|
-
end
|
51
|
-
|
52
|
-
[found, missing]
|
48
|
+
def not_found_error(primary_key_value)
|
49
|
+
Cuprum::Collections::Errors::NotFound.new(
|
50
|
+
attribute_name: primary_key_name,
|
51
|
+
attribute_value: primary_key_value,
|
52
|
+
collection_name: collection_name,
|
53
|
+
primary_key: true
|
54
|
+
)
|
53
55
|
end
|
54
56
|
|
55
57
|
def process(
|
@@ -58,16 +60,15 @@ module Cuprum::Collections::Commands
|
|
58
60
|
envelope: false,
|
59
61
|
scope: nil
|
60
62
|
)
|
61
|
-
query
|
62
|
-
items
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
envelope ? wrap_items(items) : items
|
63
|
+
query = apply_query(primary_keys: primary_keys, scope: scope)
|
64
|
+
items = items_with_primary_keys(items: query.to_a)
|
65
|
+
results = build_results(items: items, primary_keys: primary_keys)
|
66
|
+
|
67
|
+
build_result_list(
|
68
|
+
results,
|
69
|
+
allow_partial: allow_partial,
|
70
|
+
envelope: envelope
|
71
|
+
)
|
71
72
|
end
|
72
73
|
|
73
74
|
def wrap_items(items)
|
@@ -21,9 +21,10 @@ module Cuprum::Collections::Commands
|
|
21
21
|
return if item
|
22
22
|
|
23
23
|
error = Cuprum::Collections::Errors::NotFound.new(
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
attribute_name: primary_key_name,
|
25
|
+
attribute_value: primary_key,
|
26
|
+
collection_name: collection_name,
|
27
|
+
primary_key: true
|
27
28
|
)
|
28
29
|
Cuprum::Result.new(error: error)
|
29
30
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/commands'
|
4
|
+
|
5
|
+
module Cuprum::Collections::Commands
|
6
|
+
# Command for building, validating and inserting an entity into a collection.
|
7
|
+
#
|
8
|
+
# @example Creating An Entity
|
9
|
+
# command =
|
10
|
+
# Cuprum::Collections::Commands::Create.new(collection:)
|
11
|
+
# .new(collection: books_collection)
|
12
|
+
#
|
13
|
+
# # With Invalid Attributes
|
14
|
+
# attributes = { 'title' => '' }
|
15
|
+
# result = command.call(attributes: attributes)
|
16
|
+
# result.success?
|
17
|
+
# #=> false
|
18
|
+
# result.error
|
19
|
+
# #=> an instance of Cuprum::Collections::Errors::FailedValidation
|
20
|
+
# books_collection.query.count
|
21
|
+
# #=> 0
|
22
|
+
#
|
23
|
+
# # With Valid Attributes
|
24
|
+
# attributes = { 'title' => 'Gideon the Ninth' }
|
25
|
+
# result = command.call(attributes: attributes)
|
26
|
+
# result.success?
|
27
|
+
# #=> true
|
28
|
+
# result.value
|
29
|
+
# #=> a Book with title 'Gideon the Ninth'
|
30
|
+
# books_collection.query.count
|
31
|
+
# #=> 1
|
32
|
+
class Create < Cuprum::Command
|
33
|
+
# @param collection [Object] The collection used to store the entity.
|
34
|
+
# @param contract [Stannum::Constraint] The constraint used to validate the
|
35
|
+
# entity. If not given, defaults to the default contract for the
|
36
|
+
# collection.
|
37
|
+
def initialize(collection:, contract: nil)
|
38
|
+
super()
|
39
|
+
|
40
|
+
@collection = collection
|
41
|
+
@contract = contract
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Object] the collection used to store the entity.
|
45
|
+
attr_reader :collection
|
46
|
+
|
47
|
+
# @return [Stannum::Constraint] the constraint used to validate the entity.
|
48
|
+
attr_reader :contract
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def process(attributes:)
|
53
|
+
entity = step { collection.build_one.call(attributes: attributes) }
|
54
|
+
|
55
|
+
step { collection.validate_one.call(contract: contract, entity: entity) }
|
56
|
+
|
57
|
+
collection.insert_one.call(entity: entity)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/commands'
|
4
|
+
require 'cuprum/collections/errors/not_found'
|
5
|
+
require 'cuprum/collections/errors/not_unique'
|
6
|
+
|
7
|
+
module Cuprum::Collections::Commands
|
8
|
+
# Command for finding a unique entity by a query or set of attributes.
|
9
|
+
#
|
10
|
+
# @example Finding An Entity By Attributes
|
11
|
+
# command =
|
12
|
+
# Cuprum::Collections::Commands::FindOneMatching
|
13
|
+
# .new(collection: books_collection)
|
14
|
+
#
|
15
|
+
# # With an attributes Hash that matches one entity.
|
16
|
+
# result = command.call(attributes: { 'title' => 'Gideon the Ninth' })
|
17
|
+
# result.success?
|
18
|
+
# #=> true
|
19
|
+
# result.value
|
20
|
+
# #=> a Book with title 'Gideon the Ninth'
|
21
|
+
#
|
22
|
+
# # With an attributes Hash that matches multiple entities.
|
23
|
+
# result = command.call(attributes: { 'author' => 'Tamsyn Muir' })
|
24
|
+
# result.success?
|
25
|
+
# #=> false
|
26
|
+
# result.error
|
27
|
+
# #=> an instance of Cuprum::Collections::NotUnique
|
28
|
+
#
|
29
|
+
# # With an attributes Hash that does not match any entities.
|
30
|
+
# result = command.call(
|
31
|
+
# attributes: {
|
32
|
+
# 'author' => 'Becky Chambers',
|
33
|
+
# 'series' => 'The Locked Tomb'
|
34
|
+
# }
|
35
|
+
# )
|
36
|
+
# result.success?
|
37
|
+
# #=> false
|
38
|
+
# result.error
|
39
|
+
# #=> an instance of Cuprum::Collections::NotFound
|
40
|
+
#
|
41
|
+
# @example Finding An Entity By Query
|
42
|
+
# command =
|
43
|
+
# Cuprum::Collections::Commands::FindOneMatching
|
44
|
+
# .new(collection: collection)
|
45
|
+
#
|
46
|
+
# # With a query that matches one entity.
|
47
|
+
# result = command.call do
|
48
|
+
# {
|
49
|
+
# 'series' => 'The Lord of the Rings',
|
50
|
+
# 'published_at' => greater_than('1955-01-01')
|
51
|
+
# }
|
52
|
+
# end
|
53
|
+
# result.success?
|
54
|
+
# #=> true
|
55
|
+
# result.value
|
56
|
+
# #=> a Book matching the query
|
57
|
+
#
|
58
|
+
# # With a query that matches multiple entities.
|
59
|
+
# result = command.call do
|
60
|
+
# {
|
61
|
+
# 'series' => 'The Lord of the Rings',
|
62
|
+
# 'published_at' => less_than('1955-01-01')
|
63
|
+
# }
|
64
|
+
# end
|
65
|
+
# result.success?
|
66
|
+
# #=> false
|
67
|
+
# result.error
|
68
|
+
# #=> an instance of Cuprum::Collections::NotUnique
|
69
|
+
#
|
70
|
+
# # With an attributes Hash that does not match any entities.
|
71
|
+
# result = command.call do
|
72
|
+
# {
|
73
|
+
# 'series' => 'The Lord of the Rings',
|
74
|
+
# 'published_at' => less_than('1954-01-01')
|
75
|
+
# }
|
76
|
+
# end
|
77
|
+
# result.success?
|
78
|
+
# #=> false
|
79
|
+
# result.error
|
80
|
+
# #=> an instance of Cuprum::Collections::NotFound
|
81
|
+
class FindOneMatching < Cuprum::Command
|
82
|
+
# @param collection [#find_matching] The collection to query.
|
83
|
+
def initialize(collection:)
|
84
|
+
super()
|
85
|
+
|
86
|
+
@collection = collection
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [#find_matching] the collection to query.
|
90
|
+
attr_reader :collection
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def error_params_for(attributes: nil, &block)
|
95
|
+
{ collection_name: collection.collection_name }.merge(
|
96
|
+
if block_given?
|
97
|
+
{ query: collection.query.where(&block) }
|
98
|
+
else
|
99
|
+
{ attributes: attributes }
|
100
|
+
end
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def not_found_error(attributes: nil, &block)
|
105
|
+
Cuprum::Collections::Errors::NotFound.new(
|
106
|
+
**error_params_for(attributes: attributes, &block)
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def not_unique_error(attributes: nil, &block)
|
111
|
+
Cuprum::Collections::Errors::NotUnique.new(
|
112
|
+
**error_params_for(attributes: attributes, &block)
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
def process(attributes: nil, &block)
|
117
|
+
query = block || -> { attributes }
|
118
|
+
entities = step { collection.find_matching.call(limit: 2, &query) }
|
119
|
+
|
120
|
+
require_one_entity(attributes: attributes, entities: entities, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def require_one_entity(attributes:, entities:, &block)
|
124
|
+
case entities.count
|
125
|
+
when 0
|
126
|
+
failure(not_found_error(attributes: attributes, &block))
|
127
|
+
when 1
|
128
|
+
entities.first
|
129
|
+
when 2
|
130
|
+
failure(not_unique_error(attributes: attributes, &block))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/commands'
|
4
|
+
|
5
|
+
module Cuprum::Collections::Commands
|
6
|
+
# Command for assigning, validating and updating an entity in a collection.
|
7
|
+
#
|
8
|
+
# @example Updating An Entity
|
9
|
+
# command =
|
10
|
+
# Cuprum::Collections::Commands::Create.new(collection:)
|
11
|
+
# .new(collection: books_collection)
|
12
|
+
# entity =
|
13
|
+
# books_collection
|
14
|
+
# .find_matching { { 'title' => 'Gideon the Ninth' } }
|
15
|
+
# .value
|
16
|
+
# .first
|
17
|
+
#
|
18
|
+
# # With Invalid Attributes
|
19
|
+
# attributes = { 'author' => '' }
|
20
|
+
# result = command.call(attributes: attributes)
|
21
|
+
# result.success?
|
22
|
+
# #=> false
|
23
|
+
# result.error
|
24
|
+
# #=> an instance of Cuprum::Collections::Errors::FailedValidation
|
25
|
+
# books_collection
|
26
|
+
# .find_matching { { 'title' => 'Gideon the Ninth' } }
|
27
|
+
# .value
|
28
|
+
# .first['author']
|
29
|
+
# #=> 'Tamsyn Muir'
|
30
|
+
#
|
31
|
+
# # With Valid Attributes
|
32
|
+
# attributes = { 'series' => 'The Locked Tomb' }
|
33
|
+
# result = command.call(attributes: attributes)
|
34
|
+
# result.success?
|
35
|
+
# #=> true
|
36
|
+
# result.value
|
37
|
+
# #=> an instance of Book with title 'Gideon the Ninth' and series
|
38
|
+
# 'The Locked Tomb'
|
39
|
+
# books_collection
|
40
|
+
# .find_matching { { 'title' => 'Gideon the Ninth' } }
|
41
|
+
# .value
|
42
|
+
# .first['series']
|
43
|
+
# #=> 'The Locked Tomb'
|
44
|
+
class Update < Cuprum::Command
|
45
|
+
# @param collection [Object] The collection used to store the entity.
|
46
|
+
# @param contract [Stannum::Constraint] The constraint used to validate the
|
47
|
+
# entity. If not given, defaults to the default contract for the
|
48
|
+
# collection.
|
49
|
+
def initialize(collection:, contract: nil)
|
50
|
+
super()
|
51
|
+
|
52
|
+
@collection = collection
|
53
|
+
@contract = contract
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Object] the collection used to store the entity.
|
57
|
+
attr_reader :collection
|
58
|
+
|
59
|
+
# @return [Stannum::Constraint] the constraint used to validate the entity.
|
60
|
+
attr_reader :contract
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def process(attributes:, entity:)
|
65
|
+
entity = step do
|
66
|
+
collection.assign_one.call(attributes: attributes, entity: entity)
|
67
|
+
end
|
68
|
+
|
69
|
+
step { collection.validate_one.call(entity: entity, contract: contract) }
|
70
|
+
|
71
|
+
step { collection.update_one.call(entity: entity) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'cuprum/collections/commands'
|
6
|
+
require 'cuprum/collections/commands/create'
|
7
|
+
require 'cuprum/collections/commands/find_one_matching'
|
8
|
+
require 'cuprum/collections/commands/update'
|
9
|
+
|
10
|
+
module Cuprum::Collections::Commands
|
11
|
+
# Command for creating or updating an entity from an attributes Hash.
|
12
|
+
#
|
13
|
+
# @example Creating Or Updating An Entity By Primary Key
|
14
|
+
# command =
|
15
|
+
# Cuprum::Collections::Commands::Upsert
|
16
|
+
# .new(collection: books_collection)
|
17
|
+
#
|
18
|
+
# # Creating A New Entity
|
19
|
+
# books_collection.query.count
|
20
|
+
# #=> 0
|
21
|
+
# attributes = {
|
22
|
+
# 'id' => 0
|
23
|
+
# 'title' => 'Gideon the Ninth',
|
24
|
+
# 'author' => 'Tamsyn Muir'
|
25
|
+
# }
|
26
|
+
# result = command.call(attributes: attributes)
|
27
|
+
# result.value
|
28
|
+
# #=> a Book with id 0, title 'Gideon the Ninth', and author 'Tamsyn Muir'
|
29
|
+
# books_collection.query.count
|
30
|
+
# #=> 1
|
31
|
+
#
|
32
|
+
# # Updating An Existing Entity
|
33
|
+
# attributes = {
|
34
|
+
# 'id' => 0
|
35
|
+
# 'series' => 'The Locked Tomb'
|
36
|
+
# }
|
37
|
+
# result = command.call(attributes: attributes)
|
38
|
+
# result.value
|
39
|
+
# #=> a Book with id 0, title 'Gideon the Ninth', author 'Tamsyn Muir', and
|
40
|
+
# series 'The Locked Tomb'
|
41
|
+
# books_collection.query.count
|
42
|
+
# #=> 1
|
43
|
+
#
|
44
|
+
# @example Creating Or Updating An Entity By Attributes
|
45
|
+
# command =
|
46
|
+
# Cuprum::Collections::Commands::Upsert
|
47
|
+
# .new(attribute_names: %w[title], collection: books_collection)
|
48
|
+
#
|
49
|
+
# # Creating A New Entity
|
50
|
+
# books_collection.query.count
|
51
|
+
# #=> 0
|
52
|
+
# attributes = {
|
53
|
+
# 'id' => 0
|
54
|
+
# 'title' => 'Gideon the Ninth',
|
55
|
+
# 'author' => 'Tamsyn Muir'
|
56
|
+
# }
|
57
|
+
# result = command.call(attributes: attributes)
|
58
|
+
# result.value
|
59
|
+
# #=> a Book with id 0, title 'Gideon the Ninth', and author 'Tamsyn Muir'
|
60
|
+
# books_collection.query.count
|
61
|
+
# #=> 1
|
62
|
+
#
|
63
|
+
# # Updating An Existing Entity
|
64
|
+
# attributes = {
|
65
|
+
# 'title' => 'Gideon the Ninth',
|
66
|
+
# 'series' => 'The Locked Tomb'
|
67
|
+
# }
|
68
|
+
# result = command.call(attributes: attributes)
|
69
|
+
# result.value
|
70
|
+
# #=> a Book with id 0, title 'Gideon the Ninth', author 'Tamsyn Muir', and
|
71
|
+
# series 'The Locked Tomb'
|
72
|
+
# books_collection.query.count
|
73
|
+
# #=> 1
|
74
|
+
class Upsert < Cuprum::Command
|
75
|
+
# @param attribute_names [String, Symbol, Array<String, Symbol>] The names
|
76
|
+
# of the attributes used to find the unique entity.
|
77
|
+
# @param collection [Object] The collection used to store the entity.
|
78
|
+
# @param contract [Stannum::Constraint] The constraint used to validate the
|
79
|
+
# entity. If not given, defaults to the default contract for the
|
80
|
+
# collection.
|
81
|
+
def initialize(collection:, attribute_names: 'id', contract: nil)
|
82
|
+
super()
|
83
|
+
|
84
|
+
@attribute_names = normalize_attribute_names(attribute_names)
|
85
|
+
@collection = collection
|
86
|
+
@contract = contract
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [Array<String>] the names of the attributes used to find the
|
90
|
+
# unique entity.
|
91
|
+
attr_reader :attribute_names
|
92
|
+
|
93
|
+
# @return [Object] the collection used to store the entity.
|
94
|
+
attr_reader :collection
|
95
|
+
|
96
|
+
# @return [Stannum::Constraint] the constraint used to validate the entity.
|
97
|
+
attr_reader :contract
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def create_entity(attributes:)
|
102
|
+
Cuprum::Collections::Commands::Create
|
103
|
+
.new(collection: collection, contract: contract)
|
104
|
+
.call(attributes: attributes)
|
105
|
+
end
|
106
|
+
|
107
|
+
def filter_attributes(attributes:)
|
108
|
+
tools
|
109
|
+
.hash_tools
|
110
|
+
.convert_keys_to_strings(attributes)
|
111
|
+
.select { |key, _| attribute_names.include?(key) }
|
112
|
+
end
|
113
|
+
|
114
|
+
def find_entity(attributes:)
|
115
|
+
filtered = filter_attributes(attributes: attributes)
|
116
|
+
result =
|
117
|
+
Cuprum::Collections::Commands::FindOneMatching
|
118
|
+
.new(collection: collection)
|
119
|
+
.call(attributes: filtered)
|
120
|
+
|
121
|
+
return if result.error.is_a?(Cuprum::Collections::Errors::NotFound)
|
122
|
+
|
123
|
+
result
|
124
|
+
end
|
125
|
+
|
126
|
+
def normalize_attribute_names(attribute_names)
|
127
|
+
names = Array(attribute_names)
|
128
|
+
|
129
|
+
raise ArgumentError, "attribute names can't be blank" if names.empty?
|
130
|
+
|
131
|
+
names = names.map do |name|
|
132
|
+
unless name.is_a?(String) || name.is_a?(Symbol)
|
133
|
+
raise ArgumentError, "invalid attribute name #{name.inspect}"
|
134
|
+
end
|
135
|
+
|
136
|
+
name.to_s
|
137
|
+
end
|
138
|
+
|
139
|
+
Set.new(names)
|
140
|
+
end
|
141
|
+
|
142
|
+
def process(attributes:)
|
143
|
+
entity = step { find_entity(attributes: attributes) }
|
144
|
+
|
145
|
+
if entity
|
146
|
+
update_entity(attributes: attributes, entity: entity)
|
147
|
+
else
|
148
|
+
create_entity(attributes: attributes)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def tools
|
153
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
154
|
+
end
|
155
|
+
|
156
|
+
def update_entity(attributes:, entity:)
|
157
|
+
Cuprum::Collections::Commands::Update
|
158
|
+
.new(collection: collection, contract: contract)
|
159
|
+
.call(attributes: attributes, entity: entity)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -3,6 +3,11 @@
|
|
3
3
|
require 'cuprum/collections'
|
4
4
|
|
5
5
|
module Cuprum::Collections
|
6
|
-
# Namespace for abstract commands
|
7
|
-
module Commands
|
6
|
+
# Namespace for abstract commands and collection-independent commands.
|
7
|
+
module Commands
|
8
|
+
autoload :Create, 'cuprum/collections/commands/create'
|
9
|
+
autoload :FindOneMatching, 'cuprum/collections/commands/find_one_matching'
|
10
|
+
autoload :Update, 'cuprum/collections/commands/update'
|
11
|
+
autoload :Upsert, 'cuprum/collections/commands/upsert'
|
12
|
+
end
|
8
13
|
end
|