cuprum-collections 0.4.0 → 0.5.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 +73 -0
- data/README.md +5 -5
- data/lib/cuprum/collections/association.rb +9 -28
- data/lib/cuprum/collections/associations/belongs_to.rb +1 -8
- data/lib/cuprum/collections/associations/has_many.rb +1 -10
- data/lib/cuprum/collections/associations/has_one.rb +1 -10
- data/lib/cuprum/collections/basic/collection.rb +56 -49
- data/lib/cuprum/collections/basic/command.rb +22 -88
- data/lib/cuprum/collections/basic/commands/assign_one.rb +2 -6
- data/lib/cuprum/collections/basic/commands/build_one.rb +1 -4
- data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -8
- data/lib/cuprum/collections/basic/commands/find_many.rb +4 -24
- data/lib/cuprum/collections/basic/commands/find_matching.rb +5 -21
- data/lib/cuprum/collections/basic/commands/find_one.rb +3 -20
- data/lib/cuprum/collections/basic/commands/insert_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/update_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/validate_one.rb +13 -18
- data/lib/cuprum/collections/basic/query.rb +26 -40
- data/lib/cuprum/collections/basic/repository.rb +4 -3
- data/lib/cuprum/collections/basic/scopes/all_scope.rb +25 -0
- data/lib/cuprum/collections/basic/scopes/base.rb +32 -0
- data/lib/cuprum/collections/basic/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/basic/scopes/conjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +62 -0
- data/lib/cuprum/collections/basic/scopes/disjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/none_scope.rb +33 -0
- data/lib/cuprum/collections/basic/scopes.rb +23 -0
- data/lib/cuprum/collections/basic.rb +1 -0
- data/lib/cuprum/collections/collection.rb +24 -82
- data/lib/cuprum/collections/collection_command.rb +116 -0
- data/lib/cuprum/collections/commands/abstract_find_many.rb +11 -21
- data/lib/cuprum/collections/commands/abstract_find_matching.rb +43 -24
- data/lib/cuprum/collections/commands/abstract_find_one.rb +7 -10
- data/lib/cuprum/collections/commands/associations/find_many.rb +3 -8
- data/lib/cuprum/collections/commands/associations/require_many.rb +5 -5
- data/lib/cuprum/collections/commands/create.rb +3 -3
- data/lib/cuprum/collections/commands/find_one_matching.rb +6 -6
- data/lib/cuprum/collections/commands/query_command.rb +19 -0
- data/lib/cuprum/collections/commands/update.rb +3 -3
- data/lib/cuprum/collections/commands/upsert.rb +10 -10
- data/lib/cuprum/collections/commands.rb +1 -0
- data/lib/cuprum/collections/constraints/ordering.rb +2 -2
- data/lib/cuprum/collections/errors/abstract_find_error.rb +25 -42
- data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
- data/lib/cuprum/collections/errors/failed_validation.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_parameters.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_query.rb +10 -16
- data/lib/cuprum/collections/errors/missing_default_contract.rb +1 -1
- data/lib/cuprum/collections/errors/unknown_operator.rb +1 -1
- data/lib/cuprum/collections/queries.rb +31 -0
- data/lib/cuprum/collections/query.rb +50 -62
- data/lib/cuprum/collections/relation.rb +5 -383
- data/lib/cuprum/collections/relations/cardinality.rb +66 -0
- data/lib/cuprum/collections/relations/options.rb +18 -0
- data/lib/cuprum/collections/relations/parameters.rb +217 -0
- data/lib/cuprum/collections/relations/primary_keys.rb +23 -0
- data/lib/cuprum/collections/relations/scope.rb +65 -0
- data/lib/cuprum/collections/relations.rb +14 -0
- data/lib/cuprum/collections/repository.rb +5 -5
- data/lib/cuprum/collections/resource.rb +10 -41
- data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +80 -90
- data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +69 -111
- data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +42 -1335
- data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +352 -531
- data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +74 -191
- data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +13 -13
- data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +1029 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +856 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +1430 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +2217 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +297 -0
- data/lib/cuprum/collections/rspec/contracts/scopes.rb +13 -0
- data/lib/cuprum/collections/rspec/contracts.rb +2 -0
- data/lib/cuprum/collections/rspec/deferred/association_examples.rb +2098 -0
- data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +338 -0
- data/lib/cuprum/collections/rspec/deferred/command_examples.rb +160 -0
- data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +178 -0
- data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +94 -0
- data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +118 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +307 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +143 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +116 -0
- data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +103 -0
- data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +99 -0
- data/lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb +117 -0
- data/lib/cuprum/collections/rspec/deferred/commands.rb +8 -0
- data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +1437 -0
- data/lib/cuprum/collections/rspec/deferred/resource_examples.rb +26 -0
- data/lib/cuprum/collections/rspec/deferred.rb +8 -0
- data/lib/cuprum/collections/scope.rb +29 -0
- data/lib/cuprum/collections/scopes/all.rb +51 -0
- data/lib/cuprum/collections/scopes/all_scope.rb +18 -0
- data/lib/cuprum/collections/scopes/base.rb +79 -0
- data/lib/cuprum/collections/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/scopes/building.rb +221 -0
- data/lib/cuprum/collections/scopes/composition.rb +162 -0
- data/lib/cuprum/collections/scopes/conjunction.rb +44 -0
- data/lib/cuprum/collections/scopes/conjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/container.rb +65 -0
- data/lib/cuprum/collections/scopes/criteria/parser.rb +241 -0
- data/lib/cuprum/collections/scopes/criteria.rb +206 -0
- data/lib/cuprum/collections/scopes/criteria_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/disjunction.rb +45 -0
- data/lib/cuprum/collections/scopes/disjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/none.rb +62 -0
- data/lib/cuprum/collections/scopes/none_scope.rb +18 -0
- data/lib/cuprum/collections/scopes.rb +23 -0
- data/lib/cuprum/collections/version.rb +2 -2
- data/lib/cuprum/collections.rb +14 -9
- metadata +61 -15
- data/lib/cuprum/collections/basic/query_builder.rb +0 -69
- data/lib/cuprum/collections/command.rb +0 -26
- data/lib/cuprum/collections/queries/parse.rb +0 -22
- data/lib/cuprum/collections/queries/parse_block.rb +0 -206
- data/lib/cuprum/collections/queries/parse_strategy.rb +0 -91
- data/lib/cuprum/collections/query_builder.rb +0 -61
- data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +0 -484
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a123357ad584d32ba68c2b37f5b8a66b40ff3c17ccd516cdb2cbe9b3a03aa49
|
4
|
+
data.tar.gz: b585c2ad781f2fb534bfaccc9999c039519f4a612aaa5c6ad153c4f74fe8f821
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78fd0fe599f33cf43bf2bd31adadd0d5a086e4770593deceed206e6dc990378547cae6d6c1f18e16fecb96e13558793a32af3b32777296c9d0bad0ac1ea1001b
|
7
|
+
data.tar.gz: 18aef11051a058e8ed51ebed3263e0280339f279f22485fe5069bc3d5c2830d8bc18b3fab961e2204f2c967f4a12d70ec4f10fb4625f0f634f9c57db8e2e24a9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,78 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.5.0
|
4
|
+
|
5
|
+
Major refactoring of Queries. This update is **not** backwards compatible.
|
6
|
+
|
7
|
+
### Collections
|
8
|
+
|
9
|
+
Collection commands no longer define the command subclass, e.g. `rockets_collection::Launch`. Instances of the command can still be created using `rockets_collection#launch`.
|
10
|
+
|
11
|
+
### Commands
|
12
|
+
|
13
|
+
Refactored commands to use more lightweight parameter validation from `SleepingKingStudios::Tools`.
|
14
|
+
|
15
|
+
### Queries
|
16
|
+
|
17
|
+
Query result filtering now uses composable scopes.
|
18
|
+
|
19
|
+
- Implemented `Query#scope`.
|
20
|
+
- Implemented composable methods `Query#and`, `Query#or`, `Query#not`.
|
21
|
+
|
22
|
+
Performing block queries with an implicit receiver is now deprecated. Instead of:
|
23
|
+
|
24
|
+
`where { { author: eq('J.R.R. Tolkien) } }`
|
25
|
+
|
26
|
+
An explicit receiver must be passed to be block in order to use operators:
|
27
|
+
|
28
|
+
`where { |query| { author: query.eq('J.R.R. Tolkien) } }`
|
29
|
+
|
30
|
+
### Relations
|
31
|
+
|
32
|
+
Extracted `Cuprum::Collections::Relations` concerns.
|
33
|
+
|
34
|
+
- Added `#scope` support to `Cuprum::Collections::Resource`.
|
35
|
+
|
36
|
+
### RSpec
|
37
|
+
|
38
|
+
Migrated shared contract objects to deferred example groups:
|
39
|
+
|
40
|
+
- `Cuprum::Collections::RSpec::Deferred::AssociationExamples`
|
41
|
+
- `Cuprum::Collections::RSpec::Deferred::CollectionExamples`
|
42
|
+
- `Cuprum::Collections::RSpec::Deferred::CommandExamples`
|
43
|
+
- `Cuprum::Collections::RSpec::Deferred::Commands::*`
|
44
|
+
- `Cuprum::Collections::RSpec::Deferred::RelationExamples`
|
45
|
+
- `Cuprum::Collections::RSpec::Deferred::ResourceExamples`
|
46
|
+
|
47
|
+
The corresponding contracts are now deprecated.
|
48
|
+
|
49
|
+
### Scopes
|
50
|
+
|
51
|
+
Implemented `Cuprum::Collections::Scopes`. A scope object represents a filter that can be used to select a subset of a collection.
|
52
|
+
|
53
|
+
`Cuprum::Collections` defines generic scope classes for defining scopes in a collection-independant fashion. Each collection must also implement the filtering behavior for each scope type.
|
54
|
+
|
55
|
+
#### Criteria Scopes
|
56
|
+
|
57
|
+
Criteria scopes use a list of criteria to filter data. Each criterion has an attribute name, an operator (such as "equals", "greater than" or "not in"), and an expected value.
|
58
|
+
|
59
|
+
#### Logical Scopes
|
60
|
+
|
61
|
+
Conjunction scopes wrap one or more other scopes with a logical AND operation.
|
62
|
+
|
63
|
+
Disjunction scopes wrap one or more other scopes with a logical OR operation.
|
64
|
+
|
65
|
+
#### Scope Inversion
|
66
|
+
|
67
|
+
Scopes are responsible for defining their own inverse. An inverted scope should match on a collection item if and only if the base scope does not match that item.
|
68
|
+
|
69
|
+
### Other Changes
|
70
|
+
|
71
|
+
Remove deprecations from previous versions:
|
72
|
+
|
73
|
+
- Removed `Cuprum::Collections::Relation::Disambiguation`.
|
74
|
+
- Removed initializing an `AbstractFindError` subclass with `primary_key_name` and `primary_key_values` keywords.
|
75
|
+
|
3
76
|
## 0.4.0
|
4
77
|
|
5
78
|
### Associations
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ The Ruby ecosystem has a wide variety of tools and libraries for managing data a
|
|
26
26
|
|
27
27
|
### Compatibility
|
28
28
|
|
29
|
-
Cuprum::Collections is tested against Ruby (MRI)
|
29
|
+
Cuprum::Collections is tested against Ruby (MRI) 3.1 through 3.4.
|
30
30
|
|
31
31
|
### Documentation
|
32
32
|
|
@@ -34,7 +34,7 @@ Documentation is generated using [YARD](https://yardoc.org/), and can be generat
|
|
34
34
|
|
35
35
|
### License
|
36
36
|
|
37
|
-
Copyright (c) 2020-
|
37
|
+
Copyright (c) 2020-2025 Rob Smith
|
38
38
|
|
39
39
|
Cuprum::Collections is released under the [MIT License](https://opensource.org/licenses/MIT).
|
40
40
|
|
@@ -882,11 +882,11 @@ query.each.map(&:author).uniq
|
|
882
882
|
The simplest way to filter results is by passing a `Hash` to `#where`. The keys of the Hash should be the names of the attributes to filter by, and the values the expected value of that attribute. However, passing a Hash directly only supports equality comparisons. To use advanced operators, use the block form:
|
883
883
|
|
884
884
|
```ruby
|
885
|
-
query = collection.query.where do
|
885
|
+
query = collection.query.where do |scope|
|
886
886
|
{
|
887
887
|
author: 'Ursula K. LeGuin',
|
888
|
-
series: equal('Earthsea'),
|
889
|
-
published_at: greater_than('1970-01-01')
|
888
|
+
series: scope.equal('Earthsea'),
|
889
|
+
published_at: scope.greater_than('1970-01-01')
|
890
890
|
}
|
891
891
|
end
|
892
892
|
query.count
|
@@ -31,33 +31,14 @@ module Cuprum::Collections
|
|
31
31
|
# @option options singular_inverse_name [String, Symbol] the name of an
|
32
32
|
# entity in the inverse association.
|
33
33
|
def initialize(**params)
|
34
|
-
params
|
35
|
-
params = disambiguate_keyword(params, :name, :association_name)
|
34
|
+
super(**params.except(:inverse))
|
36
35
|
|
37
|
-
@inverse = params
|
38
|
-
|
39
|
-
super(**params)
|
36
|
+
@inverse = params[:inverse]
|
40
37
|
end
|
41
38
|
|
42
39
|
# @return [Cuprum::Collections::Resource] the inverse association, if any.
|
43
40
|
attr_reader :inverse
|
44
41
|
|
45
|
-
# @return [Class] the class of entity represented by the resource.
|
46
|
-
def association_class
|
47
|
-
tools.core_tools.deprecate '#association_class method',
|
48
|
-
message: 'Use #entity_class instead'
|
49
|
-
|
50
|
-
entity_class
|
51
|
-
end
|
52
|
-
|
53
|
-
# @return [String] the name of the resource.
|
54
|
-
def association_name
|
55
|
-
tools.core_tools.deprecate '#association_name method',
|
56
|
-
message: 'Use #name instead'
|
57
|
-
|
58
|
-
name
|
59
|
-
end
|
60
|
-
|
61
42
|
# Generates a query for finding matching items.
|
62
43
|
#
|
63
44
|
# @param entities [Array] the entities to query for.
|
@@ -71,12 +52,12 @@ module Cuprum::Collections
|
|
71
52
|
keys =
|
72
53
|
map_entities_to_keys(
|
73
54
|
*entities,
|
74
|
-
allow_nil
|
75
|
-
deduplicate
|
55
|
+
allow_nil:,
|
56
|
+
deduplicate:,
|
76
57
|
strict: true
|
77
58
|
)
|
78
59
|
|
79
|
-
build_keys_query(*keys, allow_nil
|
60
|
+
build_keys_query(*keys, allow_nil:, deduplicate: false)
|
80
61
|
end
|
81
62
|
|
82
63
|
# Generates a query for finding matching items by key.
|
@@ -94,11 +75,11 @@ module Cuprum::Collections
|
|
94
75
|
hash_key = query_key_name
|
95
76
|
|
96
77
|
if keys.empty?
|
97
|
-
-> { {} }
|
78
|
+
->(_) { {} }
|
98
79
|
elsif keys.size == 1
|
99
|
-
-> { { hash_key => keys.first } }
|
80
|
+
->(_) { { hash_key => keys.first } }
|
100
81
|
else
|
101
|
-
-> { { hash_key => one_of(keys) } }
|
82
|
+
->(scope) { { hash_key => scope.one_of(keys) } }
|
102
83
|
end
|
103
84
|
end
|
104
85
|
|
@@ -154,7 +135,7 @@ module Cuprum::Collections
|
|
154
135
|
)
|
155
136
|
entities
|
156
137
|
.compact
|
157
|
-
.map { |entity| map_entity_to_key(entity, strict:
|
138
|
+
.map { |entity| map_entity_to_key(entity, strict:) }
|
158
139
|
.then { |keys| allow_nil ? keys : keys.compact }
|
159
140
|
.then { |keys| deduplicate ? keys.uniq : keys }
|
160
141
|
end
|
@@ -8,10 +8,7 @@ module Cuprum::Collections::Associations
|
|
8
8
|
class BelongsTo < Cuprum::Collections::Association
|
9
9
|
# (see Cuprum::Collections::Association#initialize)
|
10
10
|
def initialize(**params)
|
11
|
-
params.
|
12
|
-
params.delete(:singular)
|
13
|
-
|
14
|
-
super(**params, singular: true)
|
11
|
+
super(**params.except(:plural), singular: true)
|
15
12
|
end
|
16
13
|
|
17
14
|
# (see Cuprum::Collections::Association#primary_key_query?)
|
@@ -24,9 +21,5 @@ module Cuprum::Collections::Associations
|
|
24
21
|
def default_foreign_key_name
|
25
22
|
singular_name&.then { |str| "#{str}_id" }
|
26
23
|
end
|
27
|
-
|
28
|
-
def ignored_parameters
|
29
|
-
@ignored_parameters ||= Set.new(IGNORED_PARAMETERS + %i[singular])
|
30
|
-
end
|
31
24
|
end
|
32
25
|
end
|
@@ -8,16 +8,7 @@ module Cuprum::Collections::Associations
|
|
8
8
|
class HasMany < Cuprum::Collections::Association
|
9
9
|
# (see Cuprum::Collections::Association#initialize)
|
10
10
|
def initialize(**params)
|
11
|
-
params.
|
12
|
-
params.delete(:singular)
|
13
|
-
|
14
|
-
super(**params, singular: false)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def ignored_parameters
|
20
|
-
@ignored_parameters ||= Set.new(IGNORED_PARAMETERS + %i[singular])
|
11
|
+
super(**params.except(:plural), singular: false)
|
21
12
|
end
|
22
13
|
end
|
23
14
|
end
|
@@ -8,16 +8,7 @@ module Cuprum::Collections::Associations
|
|
8
8
|
class HasOne < Cuprum::Collections::Association
|
9
9
|
# (see Cuprum::Collections::Association#initialize)
|
10
10
|
def initialize(**params)
|
11
|
-
params.
|
12
|
-
params.delete(:singular)
|
13
|
-
|
14
|
-
super(**params, singular: true)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def ignored_parameters
|
20
|
-
@ignored_parameters ||= Set.new(IGNORED_PARAMETERS + %i[singular])
|
11
|
+
super(**params.except(:plural), singular: true)
|
21
12
|
end
|
22
13
|
end
|
23
14
|
end
|
@@ -4,6 +4,7 @@ require 'cuprum/command_factory'
|
|
4
4
|
|
5
5
|
require 'cuprum/collections/basic'
|
6
6
|
require 'cuprum/collections/basic/commands'
|
7
|
+
require 'cuprum/collections/basic/scopes/all_scope'
|
7
8
|
require 'cuprum/collections/collection'
|
8
9
|
|
9
10
|
module Cuprum::Collections::Basic
|
@@ -13,29 +14,20 @@ module Cuprum::Collections::Basic
|
|
13
14
|
# @param data [Array<Hash>] the current data in the collection.
|
14
15
|
# @param entity_class [Class, String] the class of entity represented by
|
15
16
|
# the relation.
|
16
|
-
# @param name [String] the name of the relation.
|
17
|
-
# :collection_name.
|
17
|
+
# @param name [String] the name of the relation.
|
18
18
|
# @param qualified_name [String] a scoped name for the relation.
|
19
19
|
# @param singular_name [String] the name of an entity in the relation.
|
20
|
-
# Aliased as :member_name.
|
21
20
|
# @param options [Hash] additional options for the relation.
|
22
21
|
#
|
23
22
|
# @option options primary_key_name [String] the name of the primary key
|
24
23
|
# attribute. Defaults to 'id'.
|
25
|
-
# @option primary_key_type [Class, Stannum::Constraint] the type
|
26
|
-
# the primary key attribute. Defaults to Integer.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
super(
|
35
|
-
entity_class: entity_class,
|
36
|
-
qualified_name: qualified_name,
|
37
|
-
**parameters
|
38
|
-
)
|
24
|
+
# @option options primary_key_type [Class, Stannum::Constraint] the type
|
25
|
+
# of the primary key attribute. Defaults to Integer.
|
26
|
+
# @option options scope
|
27
|
+
# [Cuprum::Collections::Scopes::Base, Hash, Proc, nil] the configured
|
28
|
+
# scope for the relation.
|
29
|
+
def initialize(data: [], **parameters)
|
30
|
+
super(**normalize_parameters(**parameters))
|
39
31
|
|
40
32
|
@data = data
|
41
33
|
end
|
@@ -43,49 +35,40 @@ module Cuprum::Collections::Basic
|
|
43
35
|
# @return [Array<Hash>] the current data in the collection.
|
44
36
|
attr_reader :data
|
45
37
|
|
46
|
-
|
47
|
-
Cuprum::Collections::Basic::Commands::AssignOne
|
48
|
-
.subclass(**command_options)
|
38
|
+
command :assign_one do
|
39
|
+
Cuprum::Collections::Basic::Commands::AssignOne.new(collection: self)
|
49
40
|
end
|
50
41
|
|
51
|
-
|
52
|
-
Cuprum::Collections::Basic::Commands::BuildOne
|
53
|
-
.subclass(**command_options)
|
42
|
+
command :build_one do
|
43
|
+
Cuprum::Collections::Basic::Commands::BuildOne.new(collection: self)
|
54
44
|
end
|
55
45
|
|
56
|
-
|
57
|
-
Cuprum::Collections::Basic::Commands::DestroyOne
|
58
|
-
.subclass(**command_options)
|
46
|
+
command :destroy_one do
|
47
|
+
Cuprum::Collections::Basic::Commands::DestroyOne.new(collection: self)
|
59
48
|
end
|
60
49
|
|
61
|
-
|
62
|
-
Cuprum::Collections::Basic::Commands::FindMany
|
63
|
-
.subclass(**command_options)
|
50
|
+
command :find_many do
|
51
|
+
Cuprum::Collections::Basic::Commands::FindMany.new(collection: self)
|
64
52
|
end
|
65
53
|
|
66
|
-
|
67
|
-
Cuprum::Collections::Basic::Commands::FindMatching
|
68
|
-
.subclass(**command_options)
|
54
|
+
command :find_matching do
|
55
|
+
Cuprum::Collections::Basic::Commands::FindMatching.new(collection: self)
|
69
56
|
end
|
70
57
|
|
71
|
-
|
72
|
-
Cuprum::Collections::Basic::Commands::FindOne
|
73
|
-
.subclass(**command_options)
|
58
|
+
command :find_one do
|
59
|
+
Cuprum::Collections::Basic::Commands::FindOne.new(collection: self)
|
74
60
|
end
|
75
61
|
|
76
|
-
|
77
|
-
Cuprum::Collections::Basic::Commands::InsertOne
|
78
|
-
.subclass(**command_options)
|
62
|
+
command :insert_one do
|
63
|
+
Cuprum::Collections::Basic::Commands::InsertOne.new(collection: self)
|
79
64
|
end
|
80
65
|
|
81
|
-
|
82
|
-
Cuprum::Collections::Basic::Commands::UpdateOne
|
83
|
-
.subclass(**command_options)
|
66
|
+
command :update_one do
|
67
|
+
Cuprum::Collections::Basic::Commands::UpdateOne.new(collection: self)
|
84
68
|
end
|
85
69
|
|
86
|
-
|
87
|
-
Cuprum::Collections::Basic::Commands::ValidateOne
|
88
|
-
.subclass(**command_options)
|
70
|
+
command :validate_one do
|
71
|
+
Cuprum::Collections::Basic::Commands::ValidateOne.new(collection: self)
|
89
72
|
end
|
90
73
|
|
91
74
|
# @return [Stannum::Constraints::Base, nil] the # default contract for
|
@@ -98,16 +81,40 @@ module Cuprum::Collections::Basic
|
|
98
81
|
#
|
99
82
|
# @return [Cuprum::Collections::Basic::Query] the query.
|
100
83
|
def query
|
101
|
-
Cuprum::Collections::Basic::Query.new(data)
|
84
|
+
Cuprum::Collections::Basic::Query.new(data, scope:)
|
102
85
|
end
|
103
86
|
|
104
87
|
protected
|
105
88
|
|
106
|
-
def
|
107
|
-
super
|
108
|
-
data
|
109
|
-
default_contract:
|
89
|
+
def comparable_options
|
90
|
+
@comparable_options ||= super.merge(
|
91
|
+
data:,
|
92
|
+
default_contract:
|
110
93
|
)
|
111
94
|
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def default_scope
|
99
|
+
Cuprum::Collections::Basic::Scopes::AllScope.new
|
100
|
+
end
|
101
|
+
|
102
|
+
def normalize_parameters(**parameters) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
103
|
+
return parameters if parameters.key?(:entity_class)
|
104
|
+
|
105
|
+
return parameters unless parameters[:name] || parameters[:qualified_name]
|
106
|
+
|
107
|
+
parameters = parameters.merge(entity_class: Hash)
|
108
|
+
|
109
|
+
if parameters.key?(:name) && parameters.key?(:qualified_name)
|
110
|
+
parameters
|
111
|
+
elsif parameters.key?(:name)
|
112
|
+
parameters.merge(qualified_name: parameters[:name])
|
113
|
+
elsif parameters.key?(:qualified_name)
|
114
|
+
name = parameters[:qualified_name].split('/').last
|
115
|
+
|
116
|
+
parameters.merge(name:)
|
117
|
+
end
|
118
|
+
end
|
112
119
|
end
|
113
120
|
end
|
@@ -6,107 +6,41 @@ require 'cuprum/collections/basic'
|
|
6
6
|
|
7
7
|
module Cuprum::Collections::Basic
|
8
8
|
# Abstract base class for basic collection commands.
|
9
|
-
class Command < Cuprum::Collections::
|
10
|
-
# Creates a subclass with the given parameters applied to the constructor.
|
11
|
-
def self.subclass(**default_options)
|
12
|
-
Class.new(self) do
|
13
|
-
define_method(:initialize) do |**options|
|
14
|
-
super(**default_options.merge(options))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# @param collection_name [String, Symbol] The name of the collection.
|
20
|
-
# @param data [Array<Hash>] The current data in the collection.
|
21
|
-
# @param default_contract [Stannum::Constraints::Base, nil] The default
|
22
|
-
# contract for validating items in the collection.
|
23
|
-
# @param member_name [String] The name of a collection entity.
|
24
|
-
# @param primary_key_name [Symbol] The name of the primary key attribute.
|
25
|
-
# Defaults to :id.
|
26
|
-
# @param primary_key_type [Class, Stannum::Constraint] The type of the
|
27
|
-
# primary key attribute. Defaults to Integer.
|
28
|
-
# @param options [Hash<Symbol>] Additional options for the command.
|
29
|
-
def initialize( # rubocop:disable Metrics/ParameterLists
|
30
|
-
collection_name:,
|
31
|
-
data:,
|
32
|
-
default_contract: nil,
|
33
|
-
member_name: nil,
|
34
|
-
primary_key_name: :id,
|
35
|
-
primary_key_type: Integer,
|
36
|
-
**options
|
37
|
-
)
|
38
|
-
super()
|
39
|
-
|
40
|
-
@collection_name = collection_name.to_s
|
41
|
-
@data = data
|
42
|
-
@default_contract = default_contract
|
43
|
-
@member_name =
|
44
|
-
member_name ? member_name.to_s : tools.str.singularize(@collection_name)
|
45
|
-
@options = options
|
46
|
-
@primary_key_name = primary_key_name
|
47
|
-
@primary_key_type = primary_key_type
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [String] the name of the collection.
|
51
|
-
attr_reader :collection_name
|
52
|
-
|
9
|
+
class Command < Cuprum::Collections::CollectionCommand
|
53
10
|
# @return [Array<Hash>] the current data in the collection.
|
54
|
-
|
11
|
+
def data
|
12
|
+
collection.data
|
13
|
+
end
|
55
14
|
|
56
15
|
# @return [Stannum::Constraints::Base, nil] the default contract for
|
57
16
|
# validating items in the collection.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
attr_reader :member_name
|
62
|
-
|
63
|
-
# @return [Hash<Symbol>] additional options for the command.
|
64
|
-
attr_reader :options
|
65
|
-
|
66
|
-
# @return [Symbol] the name of the primary key attribute.
|
67
|
-
attr_reader :primary_key_name
|
68
|
-
|
69
|
-
# @return [Class, Stannum::Constraint] the type of the primary key
|
70
|
-
# attribute.
|
71
|
-
attr_reader :primary_key_type
|
17
|
+
def default_contract
|
18
|
+
@default_contract ||= collection.default_contract
|
19
|
+
end
|
72
20
|
|
73
21
|
private
|
74
22
|
|
75
|
-
def
|
76
|
-
|
23
|
+
def validate_entity(value, as: 'entity') # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
24
|
+
return error_message_for(as:, expected: Hash) unless value.is_a?(Hash)
|
77
25
|
|
78
|
-
|
79
|
-
keyword :primary_key, type
|
80
|
-
end
|
81
|
-
end
|
26
|
+
return [] if value.empty?
|
82
27
|
|
83
|
-
|
84
|
-
type = primary_key_type
|
28
|
+
validator = tools.assertions.aggregator_class.new
|
85
29
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
30
|
+
value.each_key do |key|
|
31
|
+
unless key.nil? || key.is_a?(String)
|
32
|
+
validator << error_message_for(
|
33
|
+
as: "#{as}[#{key.inspect}] key",
|
34
|
+
expected: String
|
35
|
+
)
|
91
36
|
|
92
|
-
|
93
|
-
|
94
|
-
end
|
37
|
+
next
|
38
|
+
end
|
95
39
|
|
96
|
-
|
97
|
-
|
98
|
-
contract: primary_key_contract,
|
99
|
-
keywords: { primary_key: primary_key },
|
100
|
-
method_name: :call
|
101
|
-
)
|
102
|
-
end
|
40
|
+
validator.validate_presence(key, as: "#{as}[#{key.inspect}] key")
|
41
|
+
end
|
103
42
|
|
104
|
-
|
105
|
-
match_parameters_to_contract(
|
106
|
-
contract: primary_keys_contract,
|
107
|
-
keywords: { primary_keys: primary_keys },
|
108
|
-
method_name: :call
|
109
|
-
)
|
43
|
+
validator.each.to_a
|
110
44
|
end
|
111
45
|
end
|
112
46
|
end
|
@@ -36,12 +36,8 @@ module Cuprum::Collections::Basic::Commands
|
|
36
36
|
# 'series' => nil,
|
37
37
|
# 'category' => 'Science Fiction and Fantasy'
|
38
38
|
# }
|
39
|
-
|
40
|
-
|
41
|
-
Stannum::Constraints::Types::HashWithIndifferentKeys.new
|
42
|
-
keyword :entity,
|
43
|
-
Stannum::Constraints::Types::HashWithStringKeys.new
|
44
|
-
end
|
39
|
+
validate :attributes
|
40
|
+
validate :entity
|
45
41
|
|
46
42
|
private
|
47
43
|
|
@@ -31,10 +31,7 @@ module Cuprum::Collections::Basic::Commands
|
|
31
31
|
# 'series' => nil,
|
32
32
|
# 'category' => 'Science Fiction and Fantasy'
|
33
33
|
# }
|
34
|
-
|
35
|
-
keyword :attributes,
|
36
|
-
Stannum::Constraints::Types::HashWithIndifferentKeys.new
|
37
|
-
end
|
34
|
+
validate :attributes
|
38
35
|
|
39
36
|
private
|
40
37
|
|
@@ -18,9 +18,7 @@ module Cuprum::Collections::Basic::Commands
|
|
18
18
|
#
|
19
19
|
# @return [Cuprum::Result<Hash{String, Object}>] a result with the
|
20
20
|
# destroyed item.
|
21
|
-
|
22
|
-
keyword :primary_key, Object
|
23
|
-
end
|
21
|
+
validate :primary_key
|
24
22
|
|
25
23
|
private
|
26
24
|
|
@@ -30,18 +28,16 @@ module Cuprum::Collections::Basic::Commands
|
|
30
28
|
error = Cuprum::Collections::Errors::NotFound.new(
|
31
29
|
attribute_name: primary_key_name,
|
32
30
|
attribute_value: primary_key,
|
33
|
-
collection_name
|
31
|
+
collection_name:,
|
34
32
|
primary_key: true
|
35
33
|
)
|
36
|
-
Cuprum::Result.new(error:
|
34
|
+
Cuprum::Result.new(error:)
|
37
35
|
end
|
38
36
|
|
39
37
|
def process(primary_key:)
|
40
|
-
step { validate_primary_key(primary_key) }
|
41
|
-
|
42
38
|
index = data.index { |item| item[primary_key_name.to_s] == primary_key }
|
43
39
|
|
44
|
-
step { handle_missing_item(index
|
40
|
+
step { handle_missing_item(index:, primary_key:) }
|
45
41
|
|
46
42
|
data.delete_at(index)
|
47
43
|
end
|
@@ -11,7 +11,7 @@ module Cuprum::Collections::Basic::Commands
|
|
11
11
|
class FindMany < Cuprum::Collections::Basic::Command
|
12
12
|
include Cuprum::Collections::Commands::AbstractFindMany
|
13
13
|
|
14
|
-
# @!method call(primary_keys:, allow_partial: false, envelope: false
|
14
|
+
# @!method call(primary_keys:, allow_partial: false, envelope: false)
|
15
15
|
# Queries the collection for the items with the given primary keys.
|
16
16
|
#
|
17
17
|
# The command will find and return the entities with the given primary
|
@@ -27,39 +27,19 @@ module Cuprum::Collections::Basic::Commands
|
|
27
27
|
# found.
|
28
28
|
# @param envelope [Boolean] If true, wraps the result value in a Hash.
|
29
29
|
# @param primary_keys [Array] The primary keys of the requested items.
|
30
|
-
# @param scope [Cuprum::Collections::Basic::Query, nil] Optional scope for
|
31
|
-
# the query. Items must match the scope as well as the primary keys.
|
32
30
|
#
|
33
31
|
# @return [Cuprum::Result<Array<Hash{String, Object}>>] a result with the
|
34
32
|
# requested items.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
keyword :primary_keys, Array
|
39
|
-
keyword :scope, Cuprum::Collections::Basic::Query, optional: true
|
40
|
-
end
|
33
|
+
validate :allow_partial, :boolean, optional: true
|
34
|
+
validate :envelope, :boolean, optional: true
|
35
|
+
validate :primary_keys
|
41
36
|
|
42
37
|
private
|
43
38
|
|
44
|
-
def build_query
|
45
|
-
Cuprum::Collections::Basic::Query.new(data)
|
46
|
-
end
|
47
|
-
|
48
39
|
def items_with_primary_keys(items:)
|
49
40
|
# :nocov:
|
50
41
|
items.to_h { |item| [item[primary_key_name.to_s], item] }
|
51
42
|
# :nocov:
|
52
43
|
end
|
53
|
-
|
54
|
-
def process(
|
55
|
-
primary_keys:,
|
56
|
-
allow_partial: false,
|
57
|
-
envelope: false,
|
58
|
-
scope: nil
|
59
|
-
)
|
60
|
-
step { validate_primary_keys(primary_keys) }
|
61
|
-
|
62
|
-
super
|
63
|
-
end
|
64
44
|
end
|
65
45
|
end
|