cuprum-collections 0.1.0 → 0.3.0.rc.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/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
|