params_ready 0.0.1
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 +7 -0
- data/lib/arel/cte_name.rb +20 -0
- data/lib/params_ready.rb +36 -0
- data/lib/params_ready/builder.rb +140 -0
- data/lib/params_ready/error.rb +31 -0
- data/lib/params_ready/extensions/class_reader_writer.rb +33 -0
- data/lib/params_ready/extensions/collection.rb +43 -0
- data/lib/params_ready/extensions/delegation.rb +25 -0
- data/lib/params_ready/extensions/finalizer.rb +26 -0
- data/lib/params_ready/extensions/freezer.rb +49 -0
- data/lib/params_ready/extensions/hash.rb +46 -0
- data/lib/params_ready/extensions/late_init.rb +38 -0
- data/lib/params_ready/extensions/registry.rb +44 -0
- data/lib/params_ready/extensions/undefined.rb +15 -0
- data/lib/params_ready/format.rb +130 -0
- data/lib/params_ready/helpers/arel_builder.rb +68 -0
- data/lib/params_ready/helpers/conditional_block.rb +31 -0
- data/lib/params_ready/helpers/find_in_hash.rb +22 -0
- data/lib/params_ready/helpers/key_map.rb +176 -0
- data/lib/params_ready/helpers/memo.rb +42 -0
- data/lib/params_ready/helpers/options.rb +39 -0
- data/lib/params_ready/helpers/parameter_definer_class_methods.rb +39 -0
- data/lib/params_ready/helpers/parameter_storage_class_methods.rb +36 -0
- data/lib/params_ready/helpers/parameter_user_class_methods.rb +31 -0
- data/lib/params_ready/helpers/relation_builder_wrapper.rb +35 -0
- data/lib/params_ready/helpers/rule.rb +57 -0
- data/lib/params_ready/helpers/storage.rb +30 -0
- data/lib/params_ready/helpers/usage_rule.rb +18 -0
- data/lib/params_ready/input_context.rb +31 -0
- data/lib/params_ready/intent.rb +70 -0
- data/lib/params_ready/marshaller/array_marshallers.rb +132 -0
- data/lib/params_ready/marshaller/builder_module.rb +9 -0
- data/lib/params_ready/marshaller/collection.rb +165 -0
- data/lib/params_ready/marshaller/definition_module.rb +63 -0
- data/lib/params_ready/marshaller/hash_marshallers.rb +100 -0
- data/lib/params_ready/marshaller/hash_set_marshallers.rb +96 -0
- data/lib/params_ready/marshaller/parameter_module.rb +11 -0
- data/lib/params_ready/marshaller/polymorph_marshallers.rb +67 -0
- data/lib/params_ready/marshaller/tuple_marshallers.rb +103 -0
- data/lib/params_ready/ordering/column.rb +60 -0
- data/lib/params_ready/ordering/ordering.rb +276 -0
- data/lib/params_ready/output_parameters.rb +127 -0
- data/lib/params_ready/pagination/abstract_pagination.rb +18 -0
- data/lib/params_ready/pagination/cursor.rb +171 -0
- data/lib/params_ready/pagination/direction.rb +148 -0
- data/lib/params_ready/pagination/keyset_pagination.rb +254 -0
- data/lib/params_ready/pagination/keysets.rb +70 -0
- data/lib/params_ready/pagination/nulls.rb +31 -0
- data/lib/params_ready/pagination/offset_pagination.rb +130 -0
- data/lib/params_ready/pagination/tendency.rb +28 -0
- data/lib/params_ready/parameter/abstract_hash_parameter.rb +204 -0
- data/lib/params_ready/parameter/array_parameter.rb +197 -0
- data/lib/params_ready/parameter/definition.rb +264 -0
- data/lib/params_ready/parameter/hash_parameter.rb +63 -0
- data/lib/params_ready/parameter/hash_set_parameter.rb +101 -0
- data/lib/params_ready/parameter/parameter.rb +456 -0
- data/lib/params_ready/parameter/polymorph_parameter.rb +172 -0
- data/lib/params_ready/parameter/state.rb +132 -0
- data/lib/params_ready/parameter/tuple_parameter.rb +152 -0
- data/lib/params_ready/parameter/value_parameter.rb +182 -0
- data/lib/params_ready/parameter_definer.rb +14 -0
- data/lib/params_ready/parameter_user.rb +43 -0
- data/lib/params_ready/query/array_grouping.rb +68 -0
- data/lib/params_ready/query/custom_predicate.rb +102 -0
- data/lib/params_ready/query/exists_predicate.rb +103 -0
- data/lib/params_ready/query/fixed_operator_predicate.rb +77 -0
- data/lib/params_ready/query/grouping.rb +177 -0
- data/lib/params_ready/query/join_clause.rb +87 -0
- data/lib/params_ready/query/nullness_predicate.rb +71 -0
- data/lib/params_ready/query/polymorph_predicate.rb +77 -0
- data/lib/params_ready/query/predicate.rb +203 -0
- data/lib/params_ready/query/predicate_operator.rb +132 -0
- data/lib/params_ready/query/relation.rb +337 -0
- data/lib/params_ready/query/structured_grouping.rb +58 -0
- data/lib/params_ready/query/variable_operator_predicate.rb +125 -0
- data/lib/params_ready/query_context.rb +21 -0
- data/lib/params_ready/restriction.rb +252 -0
- data/lib/params_ready/result.rb +109 -0
- data/lib/params_ready/value/coder.rb +181 -0
- data/lib/params_ready/value/constraint.rb +198 -0
- data/lib/params_ready/value/custom.rb +56 -0
- data/lib/params_ready/value/validator.rb +68 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 16b29937985fac59ceb959ed77ada492f9e943a81e926eb1fb0d5668f3868f97
|
4
|
+
data.tar.gz: 4aab416caa7d1663265d09eacf8229a3e280db9a1d1e29c8b154d07b74543a50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7e1ae323719b369cf6da284cd95e8596fe7e2071e0d4e7cb4e20253559a02b8ac06d34e1e79b02d7b16fd12ad0acfabd14ea57429895c0f55510e2fbf78a4790
|
7
|
+
data.tar.gz: 9df1e4edf7cb7996a4f91e4036c2656abad0c980100c37166de5b014431f9093ff307a3ff374360a0eae20357b2f60ca28ac64ef33df105ec80f3b76229684a8
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Arel # :nodoc: all
|
2
|
+
module Nodes
|
3
|
+
class CteName < Unary
|
4
|
+
alias :name :expr
|
5
|
+
|
6
|
+
def initialize(expr)
|
7
|
+
expr = SqlLiteral.new(expr)
|
8
|
+
super expr
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Visitors
|
14
|
+
class ToSql < Visitor
|
15
|
+
def visit_Arel_Nodes_CteName(o, collector)
|
16
|
+
collector << o.expr
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/params_ready.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'ruby2_keywords'
|
2
|
+
require 'arel'
|
3
|
+
|
4
|
+
require_relative 'params_ready/parameter/array_parameter'
|
5
|
+
require_relative 'params_ready/parameter/hash_parameter'
|
6
|
+
require_relative 'params_ready/parameter/hash_set_parameter'
|
7
|
+
require_relative 'params_ready/parameter/polymorph_parameter'
|
8
|
+
require_relative 'params_ready/parameter/tuple_parameter'
|
9
|
+
require_relative 'params_ready/parameter/value_parameter'
|
10
|
+
|
11
|
+
require_relative 'params_ready/value/custom'
|
12
|
+
require_relative 'params_ready/value/validator'
|
13
|
+
|
14
|
+
require_relative 'params_ready/input_context'
|
15
|
+
require_relative 'params_ready/output_parameters'
|
16
|
+
require_relative 'params_ready/parameter_definer'
|
17
|
+
require_relative 'params_ready/parameter_user'
|
18
|
+
require_relative 'params_ready/query_context'
|
19
|
+
|
20
|
+
require_relative 'params_ready/query/array_grouping'
|
21
|
+
require_relative 'params_ready/query/custom_predicate'
|
22
|
+
require_relative 'params_ready/query/exists_predicate'
|
23
|
+
require_relative 'params_ready/query/fixed_operator_predicate'
|
24
|
+
require_relative 'params_ready/query/nullness_predicate'
|
25
|
+
require_relative 'params_ready/query/polymorph_predicate'
|
26
|
+
require_relative 'params_ready/query/relation'
|
27
|
+
require_relative 'params_ready/query/variable_operator_predicate'
|
28
|
+
|
29
|
+
|
30
|
+
module ParamsReady
|
31
|
+
VERSION = '0.0.1'.freeze
|
32
|
+
|
33
|
+
def self.gem_version
|
34
|
+
::Gem::Version.new(VERSION)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require_relative 'extensions/registry'
|
2
|
+
require_relative 'helpers/rule'
|
3
|
+
|
4
|
+
module ParamsReady
|
5
|
+
class AbstractBuilder
|
6
|
+
module HavingArelTable
|
7
|
+
def arel_table(arel_table)
|
8
|
+
@definition.set_arel_table arel_table
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module HavingModel
|
13
|
+
def model(model_class)
|
14
|
+
@definition.set_model_class model_class
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
extend Extensions::Registry
|
19
|
+
registry :builders, as: :builder, getter: true do |name, _|
|
20
|
+
full_name = "define_#{name}"
|
21
|
+
raise ParamsReadyError, "Reserved name: #{full_name}" if method_defined?(full_name)
|
22
|
+
Builder.define_singleton_method(full_name) do |*args, **opts, &block|
|
23
|
+
define_parameter(name, *args, **opts, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.register(name)
|
28
|
+
register_builder(name, self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.define_parameter(type, *args, **opts, &block)
|
32
|
+
builder_class = builder(type)
|
33
|
+
builder = builder_class.instance(*args, **opts)
|
34
|
+
builder.include(&block) unless block.nil?
|
35
|
+
builder.build
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.define_registered_parameter(name, *args, **opts, &block)
|
39
|
+
full_name = "define_#{name}"
|
40
|
+
send(full_name, *args, **opts, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.resolve(input, *args, **opts, &block)
|
44
|
+
if input.is_a? Parameter::AbstractDefinition
|
45
|
+
input
|
46
|
+
else
|
47
|
+
define_registered_parameter(input, *args, **opts, &block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.instance(*args, **opts)
|
52
|
+
new *args, **opts
|
53
|
+
end
|
54
|
+
|
55
|
+
private_class_method :new
|
56
|
+
|
57
|
+
def initialize(definition)
|
58
|
+
@definition = definition
|
59
|
+
end
|
60
|
+
|
61
|
+
def include(&block)
|
62
|
+
instance_eval(&block)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def fetch
|
67
|
+
d = @definition
|
68
|
+
@definition = nil
|
69
|
+
d
|
70
|
+
end
|
71
|
+
|
72
|
+
def build
|
73
|
+
@definition.finish
|
74
|
+
@definition
|
75
|
+
end
|
76
|
+
|
77
|
+
def open?
|
78
|
+
return false if @definition.nil?
|
79
|
+
return false if @definition.frozen?
|
80
|
+
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
module HavingValue
|
85
|
+
def optional
|
86
|
+
@definition.set_optional true
|
87
|
+
end
|
88
|
+
|
89
|
+
def default(val)
|
90
|
+
@definition.set_default(val, **{})
|
91
|
+
end
|
92
|
+
|
93
|
+
def no_output(rule: nil)
|
94
|
+
@definition.set_no_output Helpers::Rule(rule) || true
|
95
|
+
end
|
96
|
+
|
97
|
+
def local(*arr, rule: nil)
|
98
|
+
@definition.set_local *arr, rule: rule
|
99
|
+
end
|
100
|
+
|
101
|
+
def preprocess(rule: nil, &block)
|
102
|
+
@definition.set_preprocessor rule: rule, &block
|
103
|
+
end
|
104
|
+
|
105
|
+
def populate(&block)
|
106
|
+
@definition.set_populator block
|
107
|
+
end
|
108
|
+
|
109
|
+
def postprocess(rule: nil, &block)
|
110
|
+
@definition.set_postprocessor rule: rule, &block
|
111
|
+
end
|
112
|
+
|
113
|
+
def marshal(*args, **opts)
|
114
|
+
@definition.set_marshaller(*args, **opts)
|
115
|
+
end
|
116
|
+
|
117
|
+
def memoize(slots = 1)
|
118
|
+
@definition.set_memoize(slots)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class Builder < AbstractBuilder
|
124
|
+
include HavingValue
|
125
|
+
|
126
|
+
def helper(name, &block)
|
127
|
+
@definition.add_helper [name, block]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
module DelegatingBuilder
|
132
|
+
def self.[](delegee_name)
|
133
|
+
mod = Module.new
|
134
|
+
Extensions::Delegation.delegate(mod) do
|
135
|
+
@definition.send(delegee_name)
|
136
|
+
end
|
137
|
+
mod
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
class ParamsReadyError < RuntimeError; end
|
3
|
+
|
4
|
+
class ErrorWrapper < ParamsReadyError
|
5
|
+
attr_reader :error
|
6
|
+
|
7
|
+
def initialize(error)
|
8
|
+
@error = error
|
9
|
+
end
|
10
|
+
|
11
|
+
def message
|
12
|
+
@error.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class PreprocessorError < ErrorWrapper; end
|
17
|
+
class PostprocessorError < ErrorWrapper; end
|
18
|
+
class PopulatorError < ErrorWrapper; end
|
19
|
+
|
20
|
+
class ValueMissingError < StandardError
|
21
|
+
def initialize(name)
|
22
|
+
super "#{name}: value is nil"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class CoercionError < RuntimeError
|
27
|
+
def initialize(input, class_name)
|
28
|
+
super "can't coerce '#{input}' into #{class_name}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../error'
|
2
|
+
|
3
|
+
module ParamsReady
|
4
|
+
module Extensions
|
5
|
+
module ClassReaderWriter
|
6
|
+
def class_reader_writer(method_name)
|
7
|
+
ivar = :"@#{method_name}"
|
8
|
+
define_singleton_method method_name do |*args|
|
9
|
+
if args.length == 0
|
10
|
+
value = instance_variable_get(ivar)
|
11
|
+
if value.nil?
|
12
|
+
if superclass.respond_to? method_name
|
13
|
+
superclass.send method_name
|
14
|
+
else
|
15
|
+
raise ParamsReadyError, "Class variable '#{ivar}' not set for '#{name}'"
|
16
|
+
end
|
17
|
+
else
|
18
|
+
value
|
19
|
+
end
|
20
|
+
elsif args.length == 1
|
21
|
+
if instance_variable_get(ivar).nil?
|
22
|
+
instance_variable_set(ivar, args[0])
|
23
|
+
else
|
24
|
+
raise ParamsReadyError, "Class variable '#{ivar}' already set for '#{name}'"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
raise ParamsReadyError, "Unexpected parameters to '#{method_name}': #{args}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative '../error'
|
2
|
+
|
3
|
+
module ParamsReady
|
4
|
+
module Extensions
|
5
|
+
module Collection
|
6
|
+
def collection(
|
7
|
+
collection_name,
|
8
|
+
element_name,
|
9
|
+
freeze_collection: true,
|
10
|
+
freeze_value: true,
|
11
|
+
getter: true,
|
12
|
+
obligatory: false,
|
13
|
+
&block
|
14
|
+
)
|
15
|
+
full_name = "@#{collection_name}"
|
16
|
+
define_method "add_#{element_name}" do |value|
|
17
|
+
value = instance_exec(value, &block) unless block.nil?
|
18
|
+
next if value == Extensions::Undefined
|
19
|
+
|
20
|
+
collection = send collection_name
|
21
|
+
value.freeze if freeze_value
|
22
|
+
collection << value
|
23
|
+
end
|
24
|
+
|
25
|
+
if getter
|
26
|
+
define_method collection_name do
|
27
|
+
if instance_variable_defined? full_name
|
28
|
+
instance_variable_get full_name
|
29
|
+
elsif frozen?
|
30
|
+
[].freeze
|
31
|
+
else
|
32
|
+
instance_variable_set full_name, []
|
33
|
+
instance_variable_get full_name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
obligatory! collection_name if obligatory
|
39
|
+
freeze_variable collection_name if freeze_collection
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
module Extensions
|
3
|
+
module Delegation
|
4
|
+
def self.delegate(mod, &to)
|
5
|
+
mod.define_method :method_missing do |name, *args, &block|
|
6
|
+
delegee = instance_eval(&to)
|
7
|
+
if delegee.respond_to? name
|
8
|
+
delegee.send name, *args, &block
|
9
|
+
else
|
10
|
+
super name, *args, &block
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
mod.define_method :respond_to_missing? do |name, include_private = false|
|
15
|
+
delegee = instance_eval(&to)
|
16
|
+
if delegee.respond_to? name
|
17
|
+
true
|
18
|
+
else
|
19
|
+
super name, include_private
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
module Extensions
|
3
|
+
module Finalizer
|
4
|
+
def obligatory!(*args)
|
5
|
+
obligatory.concat args
|
6
|
+
end
|
7
|
+
|
8
|
+
def obligatory
|
9
|
+
@obligatory ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def finish
|
14
|
+
self.class.obligatory.each do |name|
|
15
|
+
value = instance_variable_get("@#{name}")
|
16
|
+
raise ParamsReadyError, "Obligatory property is nil: #{name}" if value.nil?
|
17
|
+
if value.respond_to? :empty? and value.empty?
|
18
|
+
raise ParamsReadyError, "Obligatory property is empty: #{name}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
module Extensions
|
3
|
+
module Freezer
|
4
|
+
def variables_to_freeze
|
5
|
+
# This works on assumption classes
|
6
|
+
# are not redefined during runtime
|
7
|
+
@cached_variables_to_freeze ||= begin
|
8
|
+
names = if defined? @variables_to_freeze
|
9
|
+
@variables_to_freeze.dup
|
10
|
+
else
|
11
|
+
[]
|
12
|
+
end
|
13
|
+
names += superclass.variables_to_freeze if superclass.respond_to? :variables_to_freeze
|
14
|
+
names
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def freeze_variable(name, &block)
|
19
|
+
ivar = :"@#{name}"
|
20
|
+
if defined? @variables_to_freeze
|
21
|
+
@variables_to_freeze << [ivar, block]
|
22
|
+
else
|
23
|
+
@variables_to_freeze = [[ivar, block]]
|
24
|
+
define_method :freeze_variables do
|
25
|
+
next if frozen?
|
26
|
+
self.class.variables_to_freeze.each do |(ivar, block)|
|
27
|
+
variable = instance_variable_get ivar
|
28
|
+
block.call(variable) unless block.nil?
|
29
|
+
variable.freeze
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def freeze_variables(*names)
|
36
|
+
names.each do |name|
|
37
|
+
freeze_variable name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module InstanceMethods
|
42
|
+
def freeze
|
43
|
+
freeze_variables if respond_to? :freeze_variables
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
module Extensions
|
3
|
+
module Hash
|
4
|
+
refine ::Hash do
|
5
|
+
def deep_merge(other)
|
6
|
+
merger = proc { |_, v1, v2| ::Hash === v1 && ::Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
7
|
+
merge(other, &merger)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.try_deep_freeze(object)
|
12
|
+
if object.is_a? ::Hash
|
13
|
+
object.values.each do |value|
|
14
|
+
try_deep_freeze(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
object.freeze
|
18
|
+
object
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.acts_as_hash?(object)
|
22
|
+
return false unless object.respond_to? :[]
|
23
|
+
return false unless object.respond_to? :key?
|
24
|
+
return false unless object.respond_to? :fetch
|
25
|
+
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.indifferent_access(hash, key, default)
|
30
|
+
hash.fetch(key) do
|
31
|
+
case key
|
32
|
+
when String
|
33
|
+
hash.fetch(key.to_sym, default)
|
34
|
+
when Symbol
|
35
|
+
hash.fetch(key.to_s, default)
|
36
|
+
else
|
37
|
+
string_key = key.to_s
|
38
|
+
hash.fetch(string_key) do
|
39
|
+
hash.fetch(string_key.to_sym, default)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|