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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/lib/arel/cte_name.rb +20 -0
  3. data/lib/params_ready.rb +36 -0
  4. data/lib/params_ready/builder.rb +140 -0
  5. data/lib/params_ready/error.rb +31 -0
  6. data/lib/params_ready/extensions/class_reader_writer.rb +33 -0
  7. data/lib/params_ready/extensions/collection.rb +43 -0
  8. data/lib/params_ready/extensions/delegation.rb +25 -0
  9. data/lib/params_ready/extensions/finalizer.rb +26 -0
  10. data/lib/params_ready/extensions/freezer.rb +49 -0
  11. data/lib/params_ready/extensions/hash.rb +46 -0
  12. data/lib/params_ready/extensions/late_init.rb +38 -0
  13. data/lib/params_ready/extensions/registry.rb +44 -0
  14. data/lib/params_ready/extensions/undefined.rb +15 -0
  15. data/lib/params_ready/format.rb +130 -0
  16. data/lib/params_ready/helpers/arel_builder.rb +68 -0
  17. data/lib/params_ready/helpers/conditional_block.rb +31 -0
  18. data/lib/params_ready/helpers/find_in_hash.rb +22 -0
  19. data/lib/params_ready/helpers/key_map.rb +176 -0
  20. data/lib/params_ready/helpers/memo.rb +42 -0
  21. data/lib/params_ready/helpers/options.rb +39 -0
  22. data/lib/params_ready/helpers/parameter_definer_class_methods.rb +39 -0
  23. data/lib/params_ready/helpers/parameter_storage_class_methods.rb +36 -0
  24. data/lib/params_ready/helpers/parameter_user_class_methods.rb +31 -0
  25. data/lib/params_ready/helpers/relation_builder_wrapper.rb +35 -0
  26. data/lib/params_ready/helpers/rule.rb +57 -0
  27. data/lib/params_ready/helpers/storage.rb +30 -0
  28. data/lib/params_ready/helpers/usage_rule.rb +18 -0
  29. data/lib/params_ready/input_context.rb +31 -0
  30. data/lib/params_ready/intent.rb +70 -0
  31. data/lib/params_ready/marshaller/array_marshallers.rb +132 -0
  32. data/lib/params_ready/marshaller/builder_module.rb +9 -0
  33. data/lib/params_ready/marshaller/collection.rb +165 -0
  34. data/lib/params_ready/marshaller/definition_module.rb +63 -0
  35. data/lib/params_ready/marshaller/hash_marshallers.rb +100 -0
  36. data/lib/params_ready/marshaller/hash_set_marshallers.rb +96 -0
  37. data/lib/params_ready/marshaller/parameter_module.rb +11 -0
  38. data/lib/params_ready/marshaller/polymorph_marshallers.rb +67 -0
  39. data/lib/params_ready/marshaller/tuple_marshallers.rb +103 -0
  40. data/lib/params_ready/ordering/column.rb +60 -0
  41. data/lib/params_ready/ordering/ordering.rb +276 -0
  42. data/lib/params_ready/output_parameters.rb +127 -0
  43. data/lib/params_ready/pagination/abstract_pagination.rb +18 -0
  44. data/lib/params_ready/pagination/cursor.rb +171 -0
  45. data/lib/params_ready/pagination/direction.rb +148 -0
  46. data/lib/params_ready/pagination/keyset_pagination.rb +254 -0
  47. data/lib/params_ready/pagination/keysets.rb +70 -0
  48. data/lib/params_ready/pagination/nulls.rb +31 -0
  49. data/lib/params_ready/pagination/offset_pagination.rb +130 -0
  50. data/lib/params_ready/pagination/tendency.rb +28 -0
  51. data/lib/params_ready/parameter/abstract_hash_parameter.rb +204 -0
  52. data/lib/params_ready/parameter/array_parameter.rb +197 -0
  53. data/lib/params_ready/parameter/definition.rb +264 -0
  54. data/lib/params_ready/parameter/hash_parameter.rb +63 -0
  55. data/lib/params_ready/parameter/hash_set_parameter.rb +101 -0
  56. data/lib/params_ready/parameter/parameter.rb +456 -0
  57. data/lib/params_ready/parameter/polymorph_parameter.rb +172 -0
  58. data/lib/params_ready/parameter/state.rb +132 -0
  59. data/lib/params_ready/parameter/tuple_parameter.rb +152 -0
  60. data/lib/params_ready/parameter/value_parameter.rb +182 -0
  61. data/lib/params_ready/parameter_definer.rb +14 -0
  62. data/lib/params_ready/parameter_user.rb +43 -0
  63. data/lib/params_ready/query/array_grouping.rb +68 -0
  64. data/lib/params_ready/query/custom_predicate.rb +102 -0
  65. data/lib/params_ready/query/exists_predicate.rb +103 -0
  66. data/lib/params_ready/query/fixed_operator_predicate.rb +77 -0
  67. data/lib/params_ready/query/grouping.rb +177 -0
  68. data/lib/params_ready/query/join_clause.rb +87 -0
  69. data/lib/params_ready/query/nullness_predicate.rb +71 -0
  70. data/lib/params_ready/query/polymorph_predicate.rb +77 -0
  71. data/lib/params_ready/query/predicate.rb +203 -0
  72. data/lib/params_ready/query/predicate_operator.rb +132 -0
  73. data/lib/params_ready/query/relation.rb +337 -0
  74. data/lib/params_ready/query/structured_grouping.rb +58 -0
  75. data/lib/params_ready/query/variable_operator_predicate.rb +125 -0
  76. data/lib/params_ready/query_context.rb +21 -0
  77. data/lib/params_ready/restriction.rb +252 -0
  78. data/lib/params_ready/result.rb +109 -0
  79. data/lib/params_ready/value/coder.rb +181 -0
  80. data/lib/params_ready/value/constraint.rb +198 -0
  81. data/lib/params_ready/value/custom.rb +56 -0
  82. data/lib/params_ready/value/validator.rb +68 -0
  83. metadata +181 -0
@@ -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
@@ -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