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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -0
  3. data/README.md +5 -5
  4. data/lib/cuprum/collections/association.rb +9 -28
  5. data/lib/cuprum/collections/associations/belongs_to.rb +1 -8
  6. data/lib/cuprum/collections/associations/has_many.rb +1 -10
  7. data/lib/cuprum/collections/associations/has_one.rb +1 -10
  8. data/lib/cuprum/collections/basic/collection.rb +56 -49
  9. data/lib/cuprum/collections/basic/command.rb +22 -88
  10. data/lib/cuprum/collections/basic/commands/assign_one.rb +2 -6
  11. data/lib/cuprum/collections/basic/commands/build_one.rb +1 -4
  12. data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -8
  13. data/lib/cuprum/collections/basic/commands/find_many.rb +4 -24
  14. data/lib/cuprum/collections/basic/commands/find_matching.rb +5 -21
  15. data/lib/cuprum/collections/basic/commands/find_one.rb +3 -20
  16. data/lib/cuprum/collections/basic/commands/insert_one.rb +3 -6
  17. data/lib/cuprum/collections/basic/commands/update_one.rb +3 -6
  18. data/lib/cuprum/collections/basic/commands/validate_one.rb +13 -18
  19. data/lib/cuprum/collections/basic/query.rb +26 -40
  20. data/lib/cuprum/collections/basic/repository.rb +4 -3
  21. data/lib/cuprum/collections/basic/scopes/all_scope.rb +25 -0
  22. data/lib/cuprum/collections/basic/scopes/base.rb +32 -0
  23. data/lib/cuprum/collections/basic/scopes/builder.rb +39 -0
  24. data/lib/cuprum/collections/basic/scopes/conjunction_scope.rb +20 -0
  25. data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +62 -0
  26. data/lib/cuprum/collections/basic/scopes/disjunction_scope.rb +20 -0
  27. data/lib/cuprum/collections/basic/scopes/none_scope.rb +33 -0
  28. data/lib/cuprum/collections/basic/scopes.rb +23 -0
  29. data/lib/cuprum/collections/basic.rb +1 -0
  30. data/lib/cuprum/collections/collection.rb +24 -82
  31. data/lib/cuprum/collections/collection_command.rb +116 -0
  32. data/lib/cuprum/collections/commands/abstract_find_many.rb +11 -21
  33. data/lib/cuprum/collections/commands/abstract_find_matching.rb +43 -24
  34. data/lib/cuprum/collections/commands/abstract_find_one.rb +7 -10
  35. data/lib/cuprum/collections/commands/associations/find_many.rb +3 -8
  36. data/lib/cuprum/collections/commands/associations/require_many.rb +5 -5
  37. data/lib/cuprum/collections/commands/create.rb +3 -3
  38. data/lib/cuprum/collections/commands/find_one_matching.rb +6 -6
  39. data/lib/cuprum/collections/commands/query_command.rb +19 -0
  40. data/lib/cuprum/collections/commands/update.rb +3 -3
  41. data/lib/cuprum/collections/commands/upsert.rb +10 -10
  42. data/lib/cuprum/collections/commands.rb +1 -0
  43. data/lib/cuprum/collections/constraints/ordering.rb +2 -2
  44. data/lib/cuprum/collections/errors/abstract_find_error.rb +25 -42
  45. data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
  46. data/lib/cuprum/collections/errors/failed_validation.rb +2 -2
  47. data/lib/cuprum/collections/errors/invalid_parameters.rb +2 -2
  48. data/lib/cuprum/collections/errors/invalid_query.rb +10 -16
  49. data/lib/cuprum/collections/errors/missing_default_contract.rb +1 -1
  50. data/lib/cuprum/collections/errors/unknown_operator.rb +1 -1
  51. data/lib/cuprum/collections/queries.rb +31 -0
  52. data/lib/cuprum/collections/query.rb +50 -62
  53. data/lib/cuprum/collections/relation.rb +5 -383
  54. data/lib/cuprum/collections/relations/cardinality.rb +66 -0
  55. data/lib/cuprum/collections/relations/options.rb +18 -0
  56. data/lib/cuprum/collections/relations/parameters.rb +217 -0
  57. data/lib/cuprum/collections/relations/primary_keys.rb +23 -0
  58. data/lib/cuprum/collections/relations/scope.rb +65 -0
  59. data/lib/cuprum/collections/relations.rb +14 -0
  60. data/lib/cuprum/collections/repository.rb +5 -5
  61. data/lib/cuprum/collections/resource.rb +10 -41
  62. data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +80 -90
  63. data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +69 -111
  64. data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +42 -1335
  65. data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +352 -531
  66. data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +74 -191
  67. data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +13 -13
  68. data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +1029 -0
  69. data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +856 -0
  70. data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +1430 -0
  71. data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +2217 -0
  72. data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +297 -0
  73. data/lib/cuprum/collections/rspec/contracts/scopes.rb +13 -0
  74. data/lib/cuprum/collections/rspec/contracts.rb +2 -0
  75. data/lib/cuprum/collections/rspec/deferred/association_examples.rb +2098 -0
  76. data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +338 -0
  77. data/lib/cuprum/collections/rspec/deferred/command_examples.rb +160 -0
  78. data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +178 -0
  79. data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +94 -0
  80. data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +118 -0
  81. data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +307 -0
  82. data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +143 -0
  83. data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +116 -0
  84. data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +103 -0
  85. data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +99 -0
  86. data/lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb +117 -0
  87. data/lib/cuprum/collections/rspec/deferred/commands.rb +8 -0
  88. data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +1437 -0
  89. data/lib/cuprum/collections/rspec/deferred/resource_examples.rb +26 -0
  90. data/lib/cuprum/collections/rspec/deferred.rb +8 -0
  91. data/lib/cuprum/collections/scope.rb +29 -0
  92. data/lib/cuprum/collections/scopes/all.rb +51 -0
  93. data/lib/cuprum/collections/scopes/all_scope.rb +18 -0
  94. data/lib/cuprum/collections/scopes/base.rb +79 -0
  95. data/lib/cuprum/collections/scopes/builder.rb +39 -0
  96. data/lib/cuprum/collections/scopes/building.rb +221 -0
  97. data/lib/cuprum/collections/scopes/composition.rb +162 -0
  98. data/lib/cuprum/collections/scopes/conjunction.rb +44 -0
  99. data/lib/cuprum/collections/scopes/conjunction_scope.rb +12 -0
  100. data/lib/cuprum/collections/scopes/container.rb +65 -0
  101. data/lib/cuprum/collections/scopes/criteria/parser.rb +241 -0
  102. data/lib/cuprum/collections/scopes/criteria.rb +206 -0
  103. data/lib/cuprum/collections/scopes/criteria_scope.rb +12 -0
  104. data/lib/cuprum/collections/scopes/disjunction.rb +45 -0
  105. data/lib/cuprum/collections/scopes/disjunction_scope.rb +12 -0
  106. data/lib/cuprum/collections/scopes/none.rb +62 -0
  107. data/lib/cuprum/collections/scopes/none_scope.rb +18 -0
  108. data/lib/cuprum/collections/scopes.rb +23 -0
  109. data/lib/cuprum/collections/version.rb +2 -2
  110. data/lib/cuprum/collections.rb +14 -9
  111. metadata +61 -15
  112. data/lib/cuprum/collections/basic/query_builder.rb +0 -69
  113. data/lib/cuprum/collections/command.rb +0 -26
  114. data/lib/cuprum/collections/queries/parse.rb +0 -22
  115. data/lib/cuprum/collections/queries/parse_block.rb +0 -206
  116. data/lib/cuprum/collections/queries/parse_strategy.rb +0 -91
  117. data/lib/cuprum/collections/query_builder.rb +0 -61
  118. data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +0 -484
@@ -6,15 +6,20 @@ require 'cuprum'
6
6
  module Cuprum
7
7
  # A data abstraction layer based on the Cuprum library.
8
8
  module Collections
9
- autoload :Association, 'cuprum/collections/association'
10
- autoload :Associations, 'cuprum/collections/associations'
11
- autoload :Basic, 'cuprum/collections/basic'
12
- autoload :Collection, 'cuprum/collections/collection'
13
- autoload :Command, 'cuprum/collections/command'
14
- autoload :Errors, 'cuprum/collections/errors'
15
- autoload :Relation, 'cuprum/collections/relation'
16
- autoload :Repository, 'cuprum/collections/repository'
17
- autoload :Resource, 'cuprum/collections/resource'
9
+ autoload :Association, 'cuprum/collections/association'
10
+ autoload :Associations, 'cuprum/collections/associations'
11
+ autoload :Basic, 'cuprum/collections/basic'
12
+ autoload :Collection, 'cuprum/collections/collection'
13
+ autoload :CollectionCommand, 'cuprum/collections/collection_command'
14
+ autoload :Commands, 'cuprum/collections/commands'
15
+ autoload :Errors, 'cuprum/collections/errors'
16
+ autoload :Query, 'cuprum/collections/query'
17
+ autoload :Relation, 'cuprum/collections/relation'
18
+ autoload :Relations, 'cuprum/collections/relations'
19
+ autoload :Repository, 'cuprum/collections/repository'
20
+ autoload :Resource, 'cuprum/collections/resource'
21
+ autoload :Scope, 'cuprum/collections/scope'
22
+ autoload :Scopes, 'cuprum/collections/scopes'
18
23
 
19
24
  # @return [String] the absolute path to the gem directory.
20
25
  def self.gem_path
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuprum-collections
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-12-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: cuprum
@@ -70,11 +69,18 @@ files:
70
69
  - lib/cuprum/collections/basic/commands/update_one.rb
71
70
  - lib/cuprum/collections/basic/commands/validate_one.rb
72
71
  - lib/cuprum/collections/basic/query.rb
73
- - lib/cuprum/collections/basic/query_builder.rb
74
72
  - lib/cuprum/collections/basic/repository.rb
75
73
  - lib/cuprum/collections/basic/rspec.rb
74
+ - lib/cuprum/collections/basic/scopes.rb
75
+ - lib/cuprum/collections/basic/scopes/all_scope.rb
76
+ - lib/cuprum/collections/basic/scopes/base.rb
77
+ - lib/cuprum/collections/basic/scopes/builder.rb
78
+ - lib/cuprum/collections/basic/scopes/conjunction_scope.rb
79
+ - lib/cuprum/collections/basic/scopes/criteria_scope.rb
80
+ - lib/cuprum/collections/basic/scopes/disjunction_scope.rb
81
+ - lib/cuprum/collections/basic/scopes/none_scope.rb
76
82
  - lib/cuprum/collections/collection.rb
77
- - lib/cuprum/collections/command.rb
83
+ - lib/cuprum/collections/collection_command.rb
78
84
  - lib/cuprum/collections/commands.rb
79
85
  - lib/cuprum/collections/commands/abstract_find_many.rb
80
86
  - lib/cuprum/collections/commands/abstract_find_matching.rb
@@ -84,6 +90,7 @@ files:
84
90
  - lib/cuprum/collections/commands/associations/require_many.rb
85
91
  - lib/cuprum/collections/commands/create.rb
86
92
  - lib/cuprum/collections/commands/find_one_matching.rb
93
+ - lib/cuprum/collections/commands/query_command.rb
87
94
  - lib/cuprum/collections/commands/update.rb
88
95
  - lib/cuprum/collections/commands/upsert.rb
89
96
  - lib/cuprum/collections/constraints.rb
@@ -108,25 +115,66 @@ files:
108
115
  - lib/cuprum/collections/errors/unknown_operator.rb
109
116
  - lib/cuprum/collections/queries.rb
110
117
  - lib/cuprum/collections/queries/ordering.rb
111
- - lib/cuprum/collections/queries/parse.rb
112
- - lib/cuprum/collections/queries/parse_block.rb
113
- - lib/cuprum/collections/queries/parse_strategy.rb
114
118
  - lib/cuprum/collections/query.rb
115
- - lib/cuprum/collections/query_builder.rb
116
119
  - lib/cuprum/collections/relation.rb
120
+ - lib/cuprum/collections/relations.rb
121
+ - lib/cuprum/collections/relations/cardinality.rb
122
+ - lib/cuprum/collections/relations/options.rb
123
+ - lib/cuprum/collections/relations/parameters.rb
124
+ - lib/cuprum/collections/relations/primary_keys.rb
125
+ - lib/cuprum/collections/relations/scope.rb
117
126
  - lib/cuprum/collections/repository.rb
118
127
  - lib/cuprum/collections/resource.rb
119
128
  - lib/cuprum/collections/rspec.rb
120
129
  - lib/cuprum/collections/rspec/contracts.rb
121
130
  - lib/cuprum/collections/rspec/contracts/association_contracts.rb
122
131
  - lib/cuprum/collections/rspec/contracts/basic.rb
123
- - lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb
124
132
  - lib/cuprum/collections/rspec/contracts/collection_contracts.rb
125
133
  - lib/cuprum/collections/rspec/contracts/command_contracts.rb
126
134
  - lib/cuprum/collections/rspec/contracts/query_contracts.rb
127
135
  - lib/cuprum/collections/rspec/contracts/relation_contracts.rb
128
136
  - lib/cuprum/collections/rspec/contracts/repository_contracts.rb
137
+ - lib/cuprum/collections/rspec/contracts/scope_contracts.rb
138
+ - lib/cuprum/collections/rspec/contracts/scopes.rb
139
+ - lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb
140
+ - lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb
141
+ - lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb
142
+ - lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb
143
+ - lib/cuprum/collections/rspec/deferred.rb
144
+ - lib/cuprum/collections/rspec/deferred/association_examples.rb
145
+ - lib/cuprum/collections/rspec/deferred/collection_examples.rb
146
+ - lib/cuprum/collections/rspec/deferred/command_examples.rb
147
+ - lib/cuprum/collections/rspec/deferred/commands.rb
148
+ - lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb
149
+ - lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb
150
+ - lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb
151
+ - lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb
152
+ - lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb
153
+ - lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb
154
+ - lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb
155
+ - lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb
156
+ - lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb
157
+ - lib/cuprum/collections/rspec/deferred/relation_examples.rb
158
+ - lib/cuprum/collections/rspec/deferred/resource_examples.rb
129
159
  - lib/cuprum/collections/rspec/fixtures.rb
160
+ - lib/cuprum/collections/scope.rb
161
+ - lib/cuprum/collections/scopes.rb
162
+ - lib/cuprum/collections/scopes/all.rb
163
+ - lib/cuprum/collections/scopes/all_scope.rb
164
+ - lib/cuprum/collections/scopes/base.rb
165
+ - lib/cuprum/collections/scopes/builder.rb
166
+ - lib/cuprum/collections/scopes/building.rb
167
+ - lib/cuprum/collections/scopes/composition.rb
168
+ - lib/cuprum/collections/scopes/conjunction.rb
169
+ - lib/cuprum/collections/scopes/conjunction_scope.rb
170
+ - lib/cuprum/collections/scopes/container.rb
171
+ - lib/cuprum/collections/scopes/criteria.rb
172
+ - lib/cuprum/collections/scopes/criteria/parser.rb
173
+ - lib/cuprum/collections/scopes/criteria_scope.rb
174
+ - lib/cuprum/collections/scopes/disjunction.rb
175
+ - lib/cuprum/collections/scopes/disjunction_scope.rb
176
+ - lib/cuprum/collections/scopes/none.rb
177
+ - lib/cuprum/collections/scopes/none_scope.rb
130
178
  - lib/cuprum/collections/version.rb
131
179
  homepage: http://sleepingkingstudios.com
132
180
  licenses:
@@ -135,23 +183,21 @@ metadata:
135
183
  bug_tracker_uri: https://github.com/sleepingkingstudios/cuprum-collections/issues
136
184
  source_code_uri: https://github.com/sleepingkingstudios/cuprum-collections
137
185
  rubygems_mfa_required: 'true'
138
- post_install_message:
139
186
  rdoc_options: []
140
187
  require_paths:
141
188
  - lib
142
189
  required_ruby_version: !ruby/object:Gem::Requirement
143
190
  requirements:
144
- - - ">="
191
+ - - "~>"
145
192
  - !ruby/object:Gem::Version
146
- version: 2.7.0
193
+ version: '3.1'
147
194
  required_rubygems_version: !ruby/object:Gem::Requirement
148
195
  requirements:
149
196
  - - ">="
150
197
  - !ruby/object:Gem::Version
151
198
  version: '0'
152
199
  requirements: []
153
- rubygems_version: 3.4.21
154
- signing_key:
200
+ rubygems_version: 3.6.9
155
201
  specification_version: 4
156
202
  summary: A data abstraction layer based on the Cuprum library.
157
203
  test_files: []
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/collections/basic'
4
- require 'cuprum/collections/query_builder'
5
-
6
- module Cuprum::Collections::Basic
7
- # Concrete implementation of QueryBuilder for a basic query.
8
- class QueryBuilder < Cuprum::Collections::QueryBuilder
9
- # @param base_query [Cuprum::Collections::Basic::Query] The original
10
- # query.
11
- def initialize(base_query)
12
- super
13
-
14
- @filters = base_query.send(:filters)
15
- end
16
-
17
- private
18
-
19
- attr_reader :filters
20
-
21
- def build_filters(criteria)
22
- criteria.map do |(attribute, operator, value)|
23
- send(operator, attribute, value)
24
- end
25
- end
26
-
27
- def build_query(criteria)
28
- super.send(:with_filters, build_filters(criteria))
29
- end
30
-
31
- def equal(attribute, value)
32
- ->(actual) { actual[attribute.to_s] == value }
33
- end
34
- alias eq equal
35
-
36
- def greater_than(attribute, value)
37
- ->(actual) { actual[attribute.to_s] > value }
38
- end
39
- alias gt greater_than
40
-
41
- def greater_than_or_equal_to(attribute, value)
42
- ->(actual) { actual[attribute.to_s] >= value }
43
- end
44
- alias gte greater_than_or_equal_to
45
-
46
- def less_than(attribute, value)
47
- ->(actual) { actual[attribute.to_s] < value }
48
- end
49
- alias lt less_than
50
-
51
- def less_than_or_equal_to(attribute, value)
52
- ->(actual) { actual[attribute.to_s] <= value }
53
- end
54
- alias lte less_than_or_equal_to
55
-
56
- def not_equal(attribute, value)
57
- ->(actual) { actual[attribute.to_s] != value }
58
- end
59
- alias ne not_equal
60
-
61
- def not_one_of(attribute, value)
62
- ->(actual) { !value.include?(actual[attribute.to_s]) }
63
- end
64
-
65
- def one_of(attribute, value)
66
- ->(actual) { value.include?(actual[attribute.to_s]) }
67
- end
68
- end
69
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'stannum/parameter_validation'
4
-
5
- require 'cuprum/collections'
6
- require 'cuprum/collections/errors/invalid_parameters'
7
-
8
- module Cuprum::Collections
9
- # Abstract base class for Cuprum::Collection commands.
10
- class Command < Cuprum::Command
11
- extend Stannum::ParameterValidation
12
- include Stannum::ParameterValidation
13
-
14
- private
15
-
16
- def handle_invalid_parameters(errors:, method_name:)
17
- return super unless method_name == :call
18
-
19
- error = Cuprum::Collections::Errors::InvalidParameters.new(
20
- command: self,
21
- errors: errors
22
- )
23
- failure(error)
24
- end
25
- end
26
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/collections/queries'
4
- require 'cuprum/collections/queries/parse_strategy'
5
-
6
- module Cuprum::Collections::Queries
7
- # Command to parse parameters passed to Query#where into criteria.
8
- class Parse < Cuprum::Command
9
- private
10
-
11
- def process(where:, strategy: nil)
12
- command = step do
13
- Cuprum::Collections::Queries::ParseStrategy.new.call(
14
- strategy: strategy,
15
- where: where
16
- )
17
- end
18
-
19
- command.call(where: where)
20
- end
21
- end
22
- end
@@ -1,206 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'forwardable'
4
-
5
- require 'cuprum/errors/uncaught_exception'
6
- require 'stannum/contracts/parameters_contract'
7
-
8
- require 'cuprum/collections/command'
9
- require 'cuprum/collections/constraints/query_hash'
10
- require 'cuprum/collections/errors/invalid_query'
11
- require 'cuprum/collections/errors/unknown_operator'
12
- require 'cuprum/collections/queries'
13
-
14
- module Cuprum::Collections::Queries
15
- # Command for parsing a Query#where block into criteria.
16
- #
17
- # @example An Empty Query
18
- # command = Cuprum::Collections::Queries::ParseBlock.new
19
- # result = command.call { {} }
20
- # result.value #=> []
21
- #
22
- # @example A Value Query
23
- # command = Cuprum::Collections::Queries::ParseBlock.new
24
- # result = command.call do
25
- # {
26
- # author: 'Nnedi Okorafor',
27
- # series: 'Binti',
28
- # genre: 'Africanfuturism'
29
- # }
30
- # end
31
- # result.value #=>
32
- # # [
33
- # # ['author', :eq, 'Nnedi Okorafor'],
34
- # # ['series', :eq, 'Binti'],
35
- # # ['genre', :eq, 'Africanfuturism']
36
- # # ]
37
- #
38
- # @example A Query With Operators
39
- # command = Cuprum::Collections::Queries::ParseBlock.new
40
- # result = command.call do
41
- # {
42
- # author: equal('Nnedi Okorafor'),
43
- # series: not_equal('Binti')
44
- # }
45
- # end
46
- # result.value #=>
47
- # # [
48
- # # ['author', :eq, 'Nnedi Okorafor'],
49
- # # ['series', :ne, 'Binti']
50
- # # ]
51
- class ParseBlock < Cuprum::Collections::Command
52
- # Evaluation context for query blocks.
53
- class Builder < BasicObject
54
- # Generates an equality criterion.
55
- #
56
- # @return [Array] the equality criterion.
57
- def equals(value)
58
- [nil, Operators::EQUAL, value]
59
- end
60
- alias equal equals
61
- alias eq equals
62
-
63
- # Generates a greater than comparison criterion.
64
- #
65
- # @return [Array] the greater than criterion.
66
- def greater_than(value)
67
- [nil, Operators::GREATER_THAN, value]
68
- end
69
- alias gt greater_than
70
-
71
- # Generates a greater than or equal to comparison criterion.
72
- #
73
- # @return [Array] the greater than or equal to criterion.
74
- def greater_than_or_equal_to(value)
75
- [nil, Operators::GREATER_THAN_OR_EQUAL_TO, value]
76
- end
77
- alias gte greater_than_or_equal_to
78
-
79
- # Generates a less than comparison criterion.
80
- #
81
- # @return [Array] the less than criterion.
82
- def less_than(value)
83
- [nil, Operators::LESS_THAN, value]
84
- end
85
- alias lt less_than
86
-
87
- # Generates a less than or equal to comparison criterion.
88
- #
89
- # @return [Array] the less than or equal to criterion.
90
- def less_than_or_equal_to(value)
91
- [nil, Operators::LESS_THAN_OR_EQUAL_TO, value]
92
- end
93
- alias lte less_than_or_equal_to
94
-
95
- # Generates a negated equality criterion.
96
- #
97
- # @return [Array] the negated equality criterion.
98
- def not_equal(value)
99
- [nil, Operators::NOT_EQUAL, value]
100
- end
101
- alias ne not_equal
102
-
103
- # Generates a negated inclusion criterion.
104
- #
105
- # @return [Array] the negated inclusion criterion.
106
- def not_one_of(value)
107
- [nil, Operators::NOT_ONE_OF, value]
108
- end
109
-
110
- # Generates an inclusion criterion.
111
- #
112
- # @return [Array] the inclusion criterion.
113
- def one_of(value)
114
- [nil, Operators::ONE_OF, value]
115
- end
116
- end
117
-
118
- class << self
119
- extend Forwardable
120
-
121
- def_delegators :validation_contract,
122
- :errors_for,
123
- :match,
124
- :matches?
125
-
126
- private
127
-
128
- def validation_contract
129
- self::MethodValidations.contracts.fetch(:call)
130
- end
131
- end
132
-
133
- validate_parameters :call do
134
- keyword :where, Proc
135
- end
136
-
137
- private
138
-
139
- def call_block(&block)
140
- handle_unknown_operator { Builder.new.instance_exec(&block) }
141
- rescue StandardError => exception
142
- error = Cuprum::Errors::UncaughtException.new(
143
- exception: exception,
144
- message: 'uncaught exception when parsing query block'
145
- )
146
-
147
- failure(error)
148
- end
149
-
150
- def generate_criteria(hsh)
151
- hsh.map do |key, value|
152
- unless partial_criterion?(value)
153
- next [key.to_s, Cuprum::Collections::Queries::Operators::EQUAL, value]
154
- end
155
-
156
- value.tap { |ary| ary[0] = key.to_s }
157
- end
158
- end
159
-
160
- def handle_unknown_operator
161
- yield
162
- rescue NoMethodError => exception
163
- error = Cuprum::Collections::Errors::UnknownOperator.new(
164
- operator: exception.name
165
- )
166
-
167
- failure(error)
168
- end
169
-
170
- def invalid_query_error(errors:, message: nil)
171
- Cuprum::Collections::Errors::InvalidQuery.new(
172
- errors: errors,
173
- message: message,
174
- strategy: :block
175
- )
176
- end
177
-
178
- def partial_criterion?(obj)
179
- return false unless obj.is_a?(Array) && obj.size == 3
180
-
181
- attribute, operator, _value = obj
182
-
183
- return false unless attribute.nil?
184
-
185
- Cuprum::Collections::Queries::VALID_OPERATORS.include?(operator)
186
- end
187
-
188
- def process(where:)
189
- hsh = step { call_block(&where) }
190
-
191
- step { validate_hash(hsh) }
192
-
193
- generate_criteria(hsh)
194
- end
195
-
196
- def validate_hash(obj)
197
- constraint = Cuprum::Collections::Constraints::QueryHash.new
198
- match, errors = constraint.match(obj)
199
-
200
- return if match
201
-
202
- message = 'query block returned invalid value'
203
- failure(invalid_query_error(errors: errors, message: message))
204
- end
205
- end
206
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/collections/queries'
4
- require 'cuprum/collections/queries/parse_block'
5
- require 'cuprum/collections/errors/invalid_query'
6
-
7
- module Cuprum::Collections::Queries
8
- # Command to select the parsing strategy for parsing Query#where parameters.
9
- class ParseStrategy < Cuprum::Command
10
- STRATEGIES = {
11
- block: Cuprum::Collections::Queries::ParseBlock
12
- }.freeze
13
- private_constant :STRATEGIES
14
-
15
- # The :type of the error generated for an unknown parsing strategy.
16
- UNKNOWN_STRATEGY_ERROR =
17
- 'cuprum.collections.errors.queries.unknown_strategy'
18
-
19
- private
20
-
21
- def find_and_validate_strategy(strategy:, where:)
22
- command_class = step { find_strategy_by_key(strategy: strategy) }
23
- parameters = {
24
- arguments: [],
25
- block: nil,
26
- keywords: { where: where }
27
- }
28
-
29
- return command_class if command_class.matches?(parameters)
30
-
31
- errors = command_class.errors_for(parameters)
32
-
33
- failure(invalid_parameters_error(errors: errors, strategy: strategy))
34
- end
35
-
36
- def find_strategy(strategy:, where:)
37
- if strategy
38
- return find_and_validate_strategy(strategy: strategy, where: where)
39
- end
40
-
41
- command_class = find_strategy_by_parameters(where: where)
42
-
43
- return command_class if command_class
44
-
45
- failure(unknown_strategy_error(strategy: strategy))
46
- end
47
-
48
- def find_strategy_by_key(strategy:)
49
- STRATEGIES.fetch(strategy) do
50
- failure(unknown_strategy_error(strategy: strategy))
51
- end
52
- end
53
-
54
- def find_strategy_by_parameters(where:)
55
- STRATEGIES
56
- .values
57
- .find do |command_class|
58
- command_class.matches?(
59
- arguments: [],
60
- block: nil,
61
- keywords: { where: where }
62
- )
63
- end
64
- end
65
-
66
- def invalid_parameters_error(errors:, strategy:)
67
- Cuprum::Collections::Errors::InvalidQuery.new(
68
- errors: errors,
69
- strategy: strategy
70
- )
71
- end
72
-
73
- def process(strategy: nil, where: nil)
74
- command_class = step do
75
- find_strategy(strategy: strategy, where: where)
76
- end
77
-
78
- command_class.new
79
- end
80
-
81
- def unknown_strategy_error(strategy:)
82
- errors = Stannum::Errors.new
83
- errors[:strategy].add(UNKNOWN_STRATEGY_ERROR, strategy: strategy)
84
-
85
- Cuprum::Collections::Errors::InvalidQuery.new(
86
- errors: errors,
87
- strategy: strategy
88
- )
89
- end
90
- end
91
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/collections'
4
- require 'cuprum/collections/queries/parse'
5
-
6
- module Cuprum::Collections
7
- # Internal class that handles parsing and applying criteria to a query.
8
- class QueryBuilder
9
- # Exception class to be raised when the query cannot be parsed.
10
- class ParseError < RuntimeError; end
11
-
12
- # @param base_query [Cuprum::Collections::Query] The original query.
13
- def initialize(base_query)
14
- @base_query = base_query
15
- end
16
-
17
- # @return [Cuprum::Collections::Query] the original query.
18
- attr_reader :base_query
19
-
20
- # Returns a copy of the query updated with the generated criteria.
21
- #
22
- # Classifies the parameters to determine parsing strategy, then uses that
23
- # strategy to parse the parameters into an array of criteria. Then, copies
24
- # the original query and updates the copy with the parsed criteria.
25
- #
26
- # @param strategy [Symbol, nil] The specified strategy for parsing the given
27
- # filter into criteria. If nil, the builder will attempt to guess the
28
- # strategy based on the given filter.
29
- # @param where [Object] The filter used to match items in the collection.
30
- #
31
- # @return [Cuprum::Collections::Query] the copied and updated query.
32
- def call(where:, strategy: nil)
33
- criteria =
34
- if strategy == :unsafe
35
- where
36
- else
37
- parse_criteria(strategy: strategy, where: where)
38
- end
39
-
40
- build_query(criteria)
41
- end
42
-
43
- private
44
-
45
- def build_query(criteria)
46
- base_query
47
- .dup
48
- .send(:with_criteria, criteria)
49
- end
50
-
51
- def parse_criteria(strategy:, where:)
52
- result = Cuprum::Collections::Queries::Parse
53
- .new
54
- .call(strategy: strategy, where: where)
55
-
56
- return result.value if result.success?
57
-
58
- raise ParseError, result.error.message
59
- end
60
- end
61
- end