params_ready 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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