veritas-sql-generator 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/Gemfile +33 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +27 -0
  4. data/Rakefile +25 -0
  5. data/TODO +17 -0
  6. data/config/flay.yml +3 -0
  7. data/config/flog.yml +2 -0
  8. data/config/roodi.yml +16 -0
  9. data/config/site.reek +124 -0
  10. data/config/yardstick.yml +2 -0
  11. data/lib/veritas-sql-generator.rb +3 -0
  12. data/lib/veritas/base_relation.rb +36 -0
  13. data/lib/veritas/sql/generator.rb +35 -0
  14. data/lib/veritas/sql/generator/attribute.rb +25 -0
  15. data/lib/veritas/sql/generator/direction.rb +36 -0
  16. data/lib/veritas/sql/generator/identifier.rb +27 -0
  17. data/lib/veritas/sql/generator/literal.rb +160 -0
  18. data/lib/veritas/sql/generator/logic.rb +349 -0
  19. data/lib/veritas/sql/generator/relation.rb +111 -0
  20. data/lib/veritas/sql/generator/relation/base.rb +14 -0
  21. data/lib/veritas/sql/generator/relation/binary.rb +184 -0
  22. data/lib/veritas/sql/generator/relation/set.rb +99 -0
  23. data/lib/veritas/sql/generator/relation/unary.rb +326 -0
  24. data/lib/veritas/sql/generator/version.rb +9 -0
  25. data/lib/veritas/sql/generator/visitor.rb +121 -0
  26. data/spec/rcov.opts +6 -0
  27. data/spec/shared/command_method_behavior.rb +7 -0
  28. data/spec/shared/generated_sql_behavior.rb +15 -0
  29. data/spec/shared/idempotent_method_behavior.rb +7 -0
  30. data/spec/spec.opts +3 -0
  31. data/spec/spec_helper.rb +15 -0
  32. data/spec/unit/veritas/base_relation/name_spec.rb +45 -0
  33. data/spec/unit/veritas/sql/generator/attribute/visit_veritas_attribute_spec.rb +15 -0
  34. data/spec/unit/veritas/sql/generator/direction/visit_veritas_relation_operation_order_ascending_spec.rb +15 -0
  35. data/spec/unit/veritas/sql/generator/direction/visit_veritas_relation_operation_order_descending_spec.rb +15 -0
  36. data/spec/unit/veritas/sql/generator/identifier/visit_identifier_spec.rb +26 -0
  37. data/spec/unit/veritas/sql/generator/literal/class_methods/dup_frozen_spec.rb +23 -0
  38. data/spec/unit/veritas/sql/generator/literal/visit_class_spec.rb +31 -0
  39. data/spec/unit/veritas/sql/generator/literal/visit_date_spec.rb +15 -0
  40. data/spec/unit/veritas/sql/generator/literal/visit_date_time_spec.rb +61 -0
  41. data/spec/unit/veritas/sql/generator/literal/visit_enumerable_spec.rb +15 -0
  42. data/spec/unit/veritas/sql/generator/literal/visit_false_class_spec.rb +14 -0
  43. data/spec/unit/veritas/sql/generator/literal/visit_nil_class_spec.rb +14 -0
  44. data/spec/unit/veritas/sql/generator/literal/visit_numeric_spec.rb +34 -0
  45. data/spec/unit/veritas/sql/generator/literal/visit_string_spec.rb +26 -0
  46. data/spec/unit/veritas/sql/generator/literal/visit_time_spec.rb +97 -0
  47. data/spec/unit/veritas/sql/generator/literal/visit_true_class_spec.rb +14 -0
  48. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_conjunction_spec.rb +16 -0
  49. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_disjunction_spec.rb +16 -0
  50. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_negation_spec.rb +16 -0
  51. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_equality_spec.rb +27 -0
  52. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_exclusion_spec.rb +43 -0
  53. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_or_equal_to_spec.rb +15 -0
  54. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_spec.rb +15 -0
  55. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_inclusion_spec.rb +43 -0
  56. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_inequality_spec.rb +55 -0
  57. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_or_equal_to_spec.rb +15 -0
  58. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_spec.rb +15 -0
  59. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_contradiction_spec.rb +15 -0
  60. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_tautology_spec.rb +15 -0
  61. data/spec/unit/veritas/sql/generator/relation/binary/base/to_subquery_spec.rb +35 -0
  62. data/spec/unit/veritas/sql/generator/relation/binary/base/visit_veritas_base_relation_spec.rb +22 -0
  63. data/spec/unit/veritas/sql/generator/relation/binary/class_methods/subquery_spec.rb +42 -0
  64. data/spec/unit/veritas/sql/generator/relation/binary/to_s_spec.rb +35 -0
  65. data/spec/unit/veritas/sql/generator/relation/binary/to_subquery_spec.rb +35 -0
  66. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_join_spec.rb +138 -0
  67. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_product_spec.rb +139 -0
  68. data/spec/unit/veritas/sql/generator/relation/class_methods/subquery_spec.rb +33 -0
  69. data/spec/unit/veritas/sql/generator/relation/class_methods/visit_spec.rb +61 -0
  70. data/spec/unit/veritas/sql/generator/relation/name_spec.rb +30 -0
  71. data/spec/unit/veritas/sql/generator/relation/set/to_s_spec.rb +55 -0
  72. data/spec/unit/veritas/sql/generator/relation/set/to_subquery_spec.rb +55 -0
  73. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_difference_spec.rb +138 -0
  74. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_intersection_spec.rb +138 -0
  75. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_union_spec.rb +138 -0
  76. data/spec/unit/veritas/sql/generator/relation/to_sql_spec.rb +52 -0
  77. data/spec/unit/veritas/sql/generator/relation/unary/to_s_spec.rb +55 -0
  78. data/spec/unit/veritas/sql/generator/relation/unary/to_subquery_spec.rb +75 -0
  79. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_projection_spec.rb +138 -0
  80. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_rename_spec.rb +136 -0
  81. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_restriction_spec.rb +157 -0
  82. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_base_relation_spec.rb +21 -0
  83. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_limit_spec.rb +125 -0
  84. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_offset_spec.rb +125 -0
  85. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_order_spec.rb +136 -0
  86. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_reverse_spec.rb +125 -0
  87. data/spec/unit/veritas/sql/generator/relation/visit_spec.rb +54 -0
  88. data/spec/unit/veritas/sql/generator/relation/visited_spec.rb +35 -0
  89. data/spec/unit/veritas/sql/generator/visitor/class_methods/handler_for_spec.rb +71 -0
  90. data/spec/unit/veritas/sql/generator/visitor/visit_spec.rb +12 -0
  91. data/spec/unit/veritas/sql/generator/visitor/visited_spec.rb +11 -0
  92. data/tasks/quality/ci.rake +2 -0
  93. data/tasks/quality/flay.rake +41 -0
  94. data/tasks/quality/flog.rake +45 -0
  95. data/tasks/quality/heckle.rake +203 -0
  96. data/tasks/quality/metric_fu.rake +26 -0
  97. data/tasks/quality/reek.rake +9 -0
  98. data/tasks/quality/roodi.rake +15 -0
  99. data/tasks/quality/yardstick.rake +23 -0
  100. data/tasks/spec.rake +38 -0
  101. data/tasks/yard.rake +9 -0
  102. data/veritas-sql-generator.gemspec +222 -0
  103. metadata +285 -0
@@ -0,0 +1,160 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ module SQL
5
+ module Generator
6
+
7
+ # Generates an SQL statement for a literal
8
+ module Literal
9
+
10
+ TRUE = 'TRUE'.freeze
11
+ FALSE = 'FALSE'.freeze
12
+ NULL = 'NULL'.freeze
13
+ QUOTE = "'".freeze
14
+ ESCAPED_QUOTE = "''".freeze
15
+ SEPARATOR = ', '.freeze
16
+ DATE_FORMAT = '%F'.freeze
17
+ DATETIME_FORMAT = "#{DATE_FORMAT}T%T.%N%Z".freeze
18
+ TIME_SCALE = 9
19
+
20
+ # Returns an unfrozen object
21
+ #
22
+ # Some objects, like Date, DateTime and Time memoize values
23
+ # when serialized to a String, so when they are frozen this will
24
+ # dup them and then return the unfrozen copy.
25
+ #
26
+ # @param [Object] object
27
+ #
28
+ # @return [Object]
29
+ # non-frozen object
30
+ #
31
+ # @api private
32
+ def self.dup_frozen(object)
33
+ object.frozen? ? object.dup : object
34
+ end
35
+
36
+ # Visit an Enumerable
37
+ #
38
+ # @param [Enumerable] enumerable
39
+ #
40
+ # @return [#to_s]
41
+ #
42
+ # @api private
43
+ def visit_enumerable(enumerable)
44
+ "(#{enumerable.map { |entry| dispatch entry }.join(SEPARATOR)})"
45
+ end
46
+
47
+ # Visit a String
48
+ #
49
+ # @note The string must be utf-8 encoded
50
+ #
51
+ # @param [String] string
52
+ #
53
+ # @return [#to_s]
54
+ #
55
+ # @api private
56
+ def visit_string(string)
57
+ "#{QUOTE}#{string.gsub(QUOTE, ESCAPED_QUOTE)}#{QUOTE}"
58
+ end
59
+
60
+ # Visit a Numeric
61
+ #
62
+ # @param [Numeric] numeric
63
+ #
64
+ # @return [#to_s]
65
+ #
66
+ # @api private
67
+ def visit_numeric(numeric)
68
+ numeric.to_s
69
+ end
70
+
71
+ # Visit a Class
72
+ #
73
+ # @param [Class] klass
74
+ #
75
+ # @return [#to_s]
76
+ #
77
+ # @api private
78
+ def visit_class(klass)
79
+ name = klass.name.to_s
80
+ name.empty? ? NULL : visit_string(name)
81
+ end
82
+
83
+ # Visit a Date and return in ISO 8601 date format
84
+ #
85
+ # @param [Date] date
86
+ #
87
+ # @return [#to_s]
88
+ #
89
+ # @todo use Date#iso8601 when added to 1.8.7 by backports
90
+ #
91
+ # @api private
92
+ def visit_date(date)
93
+ dispatch Literal.dup_frozen(date).strftime(DATE_FORMAT)
94
+ end
95
+
96
+ # Visit a DateTime and return in ISO 8601 date-time format
97
+ #
98
+ # Converts the DateTime to UTC format.
99
+ #
100
+ # @param [DateTime] date_time
101
+ #
102
+ # @return [#to_s]
103
+ #
104
+ # @todo use DateTime#iso8601(TIME_SCALE) when added to 1.8.7 by backports
105
+ #
106
+ # @api private
107
+ def visit_date_time(date_time)
108
+ dispatch date_time.new_offset.strftime(DATETIME_FORMAT)
109
+ end
110
+
111
+ # Visit a Time
112
+ #
113
+ # Converts the Time to UTC format.
114
+ #
115
+ # @param [Time] time
116
+ #
117
+ # @return [#to_s]
118
+ #
119
+ # @api private
120
+ def visit_time(time)
121
+ dispatch Literal.dup_frozen(time).utc.iso8601(TIME_SCALE)
122
+ end
123
+
124
+ # Visit a true value
125
+ #
126
+ # @param [true]
127
+ #
128
+ # @return [#to_s]
129
+ #
130
+ # @api private
131
+ def visit_true_class(_true)
132
+ TRUE
133
+ end
134
+
135
+ # Visit a false value
136
+ #
137
+ # @param [false]
138
+ #
139
+ # @return [#to_s]
140
+ #
141
+ # @api private
142
+ def visit_false_class(_false)
143
+ FALSE
144
+ end
145
+
146
+ # Visit a nil value
147
+ #
148
+ # @param [nil]
149
+ #
150
+ # @return [#to_s]
151
+ #
152
+ # @api private
153
+ def visit_nil_class(_nil)
154
+ NULL
155
+ end
156
+
157
+ end # module Literal
158
+ end # module Generator
159
+ end # module SQL
160
+ end # module Veritas
@@ -0,0 +1,349 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ module SQL
5
+ module Generator
6
+
7
+ # Generates an SQL statement for a logic expression
8
+ module Logic
9
+ include Attribute, Literal
10
+
11
+ EQUAL_TO = ' = '.freeze
12
+ EQUAL_TO_NULL = ' IS '.freeze
13
+ NOT_EQUAL_TO = ' <> '.freeze
14
+ NOT_EQUAL_TO_NULL = ' IS NOT '.freeze
15
+ GREATER_THAN = ' > '.freeze
16
+ GREATER_THAN_OR_EQUAL_TO = ' >= '.freeze
17
+ LESS_THAN = ' < '.freeze
18
+ LESS_THAN_OR_EQUAL_TO = ' <= '.freeze
19
+ IN = ' IN '.freeze
20
+ NOT_IN = ' NOT IN '.freeze
21
+ BETWEEN = ' BETWEEN '.freeze
22
+ NOT_BETWEEN = ' NOT BETWEEN '.freeze
23
+ AND = ' AND '.freeze
24
+ OR = ' OR '.freeze
25
+ MATCH_ALL = '1 = 1'.freeze
26
+ MATCH_NONE = '1 = 0'.freeze
27
+ EMPTY_ARRAY = [].freeze
28
+
29
+ # Visit an Equality predicate
30
+ #
31
+ # @param [Logic::Predicate::Equality] equality
32
+ #
33
+ # @return [#to_s]
34
+ #
35
+ # @api private
36
+ def visit_veritas_logic_predicate_equality(equality)
37
+ binary_operation_sql(equality.right.nil? ? EQUAL_TO_NULL : EQUAL_TO, equality)
38
+ end
39
+
40
+ # Visit an Inequality predicate
41
+ #
42
+ # @param [Logic::Predicate::Inequality] inequality
43
+ #
44
+ # @return [#to_s]
45
+ #
46
+ # @api private
47
+ def visit_veritas_logic_predicate_inequality(inequality)
48
+ expressions = inequality_expressions(inequality)
49
+ expressions.one? ? expressions.first : "(#{expressions.join(OR)})"
50
+ end
51
+
52
+ # Visit an GreaterThan predicate
53
+ #
54
+ # @param [Logic::Predicate::GreaterThan] greater_than
55
+ #
56
+ # @return [#to_s]
57
+ #
58
+ # @api private
59
+ def visit_veritas_logic_predicate_greater_than(greater_than)
60
+ binary_operation_sql(GREATER_THAN, greater_than)
61
+ end
62
+
63
+ # Visit an GreaterThanOrEqualTo predicate
64
+ #
65
+ # @param [Logic::Predicate::GreaterThanOrEqualTo] greater_than_or_equal_to
66
+ #
67
+ # @return [#to_s]
68
+ #
69
+ # @api private
70
+ def visit_veritas_logic_predicate_greater_than_or_equal_to(greater_than_or_equal_to)
71
+ binary_operation_sql(GREATER_THAN_OR_EQUAL_TO, greater_than_or_equal_to)
72
+ end
73
+
74
+ # Visit an LessThan predicate
75
+ #
76
+ # @param [Logic::Predicate::LessThan] less_than
77
+ #
78
+ # @return [#to_s]
79
+ #
80
+ # @api private
81
+ def visit_veritas_logic_predicate_less_than(less_than)
82
+ binary_operation_sql(LESS_THAN, less_than)
83
+ end
84
+
85
+ # Visit an LessThanOrEqualTo predicate
86
+ #
87
+ # @param [Logic::Predicate::LessThanOrEqualTo] less_than_or_equal_to
88
+ #
89
+ # @return [#to_s]
90
+ #
91
+ # @api private
92
+ def visit_veritas_logic_predicate_less_than_or_equal_to(less_than_or_equal_to)
93
+ binary_operation_sql(LESS_THAN_OR_EQUAL_TO, less_than_or_equal_to)
94
+ end
95
+
96
+ # Visit an Inclusion predicate
97
+ #
98
+ # @param [Logic::Predicate::Inclusion] inclusion
99
+ #
100
+ # @return [#to_s]
101
+ #
102
+ # @api private
103
+ def visit_veritas_logic_predicate_inclusion(inclusion)
104
+ case inclusion.right
105
+ when Range then range_inclusion_sql(inclusion)
106
+ when EMPTY_ARRAY then MATCH_NONE
107
+ else
108
+ binary_operation_sql(IN, inclusion)
109
+ end
110
+ end
111
+
112
+ # Visit an Exclusion predicate
113
+ #
114
+ # @param [Logic::Predicate::Exclusion] exclusion
115
+ #
116
+ # @return [#to_s]
117
+ #
118
+ # @api private
119
+ def visit_veritas_logic_predicate_exclusion(exclusion)
120
+ case exclusion.right
121
+ when Range then range_exclusion_sql(exclusion)
122
+ when EMPTY_ARRAY then MATCH_ALL
123
+ else
124
+ binary_operation_sql(NOT_IN, exclusion)
125
+ end
126
+ end
127
+
128
+ # Visit an Conjunction connective
129
+ #
130
+ # @param [Logic::Connective::Conjunction] conjunction
131
+ #
132
+ # @return [#to_s]
133
+ #
134
+ # @api private
135
+ def visit_veritas_logic_connective_conjunction(conjunction)
136
+ binary_connective_sql(AND, conjunction)
137
+ end
138
+
139
+ # Visit an Disjunction connective
140
+ #
141
+ # @param [Logic::Connective::Disjunction] disjunction
142
+ #
143
+ # @return [#to_s]
144
+ #
145
+ # @api private
146
+ def visit_veritas_logic_connective_disjunction(disjunction)
147
+ binary_connective_sql(OR, disjunction)
148
+ end
149
+
150
+ # Visit an Negation connective
151
+ #
152
+ # @param [Logic::Connective::Negation] negation
153
+ #
154
+ # @return [#to_s]
155
+ #
156
+ # @api private
157
+ def visit_veritas_logic_connective_negation(negation)
158
+ "NOT #{dispatch negation.operand}"
159
+ end
160
+
161
+ # Visit a Tautology
162
+ #
163
+ # @param [Logic::Proposition::Tautology] _tautology
164
+ #
165
+ # @return [#to_s]
166
+ #
167
+ # @api private
168
+ def visit_veritas_logic_proposition_tautology(_tautology)
169
+ MATCH_ALL
170
+ end
171
+
172
+ # Visit a Contradiction
173
+ #
174
+ # @param [Logic::Proposition::Contradiction] _contradiction
175
+ #
176
+ # @return [#to_s]
177
+ #
178
+ # @api private
179
+ def visit_veritas_logic_proposition_contradiction(_contradiction)
180
+ MATCH_NONE
181
+ end
182
+
183
+ private
184
+
185
+ # Return the SQL for an Inclusion using a Range
186
+ #
187
+ # @param [Logic::Predicate::Inclusion] predicate
188
+ #
189
+ # @return [#to_s]
190
+ #
191
+ # @api private
192
+ def range_inclusion_sql(inclusion)
193
+ if inclusion.right.exclude_end?
194
+ exclusive_range_inclusion_sql(inclusion)
195
+ else
196
+ inclusive_range_sql(BETWEEN, inclusion)
197
+ end
198
+ end
199
+
200
+ # Return the SQL for an Exclusion using a Range
201
+ #
202
+ # @param [Logic::Predicate::Exclusion] exclusion
203
+ #
204
+ # @return [#to_s]
205
+ #
206
+ # @api private
207
+ def range_exclusion_sql(exclusion)
208
+ if exclusion.right.exclude_end?
209
+ exclusive_range_exclusion_sql(exclusion)
210
+ else
211
+ inclusive_range_sql(NOT_BETWEEN, exclusion)
212
+ end
213
+ end
214
+
215
+ # Return the SQL for an Inclusion using an exclusive Range
216
+ #
217
+ # @param [Logic::Predicate::Inclusion] inclusion
218
+ #
219
+ # @return [#to_s]
220
+ #
221
+ # @api private
222
+ def exclusive_range_inclusion_sql(inclusion)
223
+ left = new_from_enumerable_predicate(Veritas::Logic::Predicate::GreaterThanOrEqualTo, inclusion, :first)
224
+ right = new_from_enumerable_predicate(Veritas::Logic::Predicate::LessThan, inclusion, :last)
225
+ dispatch left.and(right)
226
+ end
227
+
228
+ # Return the SQL for an Exclusion using an exclusive Range
229
+ #
230
+ # @param [Logic::Predicate::Exclusion] exclusion
231
+ #
232
+ # @return [#to_s]
233
+ #
234
+ # @api private
235
+ def exclusive_range_exclusion_sql(exclusion)
236
+ left = new_from_enumerable_predicate(Veritas::Logic::Predicate::LessThan, exclusion, :first)
237
+ right = new_from_enumerable_predicate(Veritas::Logic::Predicate::GreaterThanOrEqualTo, exclusion, :last)
238
+ dispatch left.or(right)
239
+ end
240
+
241
+ # Instantiate a new Predicate object from an Enumerable Predicate
242
+ #
243
+ # @param [Class<Logic::Predicate>] klass
244
+ # the type of predicate to create
245
+ # @param [Logic::Predicate::Enumerable] predicate
246
+ # the enumerable predicate
247
+ # @param [Symbol] method
248
+ # the method to call on the right operand of the predicate
249
+ # @return [Logic::Predicate]
250
+ #
251
+ # @api private
252
+ def new_from_enumerable_predicate(klass, predicate, method)
253
+ klass.new(predicate.left, predicate.right.send(method))
254
+ end
255
+
256
+ # Return the expressions for an inequality
257
+ #
258
+ # @param [Logic::Predicate::Inequality] inequality
259
+ #
260
+ # @return [Array<#to_s>]
261
+ #
262
+ # @api private
263
+ def inequality_expressions(inequality)
264
+ expressions = [
265
+ inequality_sql(inequality),
266
+ optional_is_null_sql(inequality.left),
267
+ optional_is_null_sql(inequality.right),
268
+ ]
269
+ expressions.compact!
270
+ expressions
271
+ end
272
+
273
+ # Return the SQL for an inequality predicate
274
+ #
275
+ # @param [Logic::Predicate::Inequality] inequality
276
+ #
277
+ # @return [#to_s]
278
+ #
279
+ # @api private
280
+ def inequality_sql(inequality)
281
+ binary_operation_sql(inequality.right.nil? ? NOT_EQUAL_TO_NULL : NOT_EQUAL_TO, inequality)
282
+ end
283
+
284
+ # Return the SQL for a Binary Connective
285
+ #
286
+ # @param [#to_s] operator
287
+ #
288
+ # @param [Logic::Connective::Binary] binary_connective
289
+ #
290
+ # @return [#to_s]
291
+ #
292
+ # @api private
293
+ def binary_connective_sql(operator, binary_connective)
294
+ "(#{binary_operation_sql(operator, binary_connective)})"
295
+ end
296
+
297
+ # Return the SQL for a predicate
298
+ #
299
+ # @param [#to_s] operator
300
+ #
301
+ # @param [Logic::Predicate] predicate
302
+ #
303
+ # @return [#to_s]
304
+ #
305
+ # @api private
306
+ def binary_operation_sql(operator, predicate)
307
+ "#{dispatch(predicate.left)}#{operator}#{dispatch(predicate.right)}"
308
+ end
309
+
310
+ # Return the SQL for an operation using an inclusive Range
311
+ #
312
+ # @param [#to_s] operator
313
+ #
314
+ # @param [Logic::Predicate::Enumerable] predicate
315
+ #
316
+ # @return [#to_s]
317
+ #
318
+ # @api private
319
+ def inclusive_range_sql(operator, predicate)
320
+ right = predicate.right
321
+ "#{dispatch(predicate.left)}#{operator}#{dispatch(right.first)}#{AND}#{dispatch(right.last)}"
322
+ end
323
+
324
+ # Return SQL for an Equality with a nil value for optional attributes
325
+ #
326
+ # @param [Attribute] attribute
327
+ #
328
+ # @return [#to_sql, nil]
329
+ #
330
+ # @api private
331
+ def optional_is_null_sql(attribute)
332
+ dispatch(attribute.eq(nil)) if optional?(attribute)
333
+ end
334
+
335
+ # Test if the object is not required
336
+ #
337
+ # @param [Object] operand
338
+ #
339
+ # @return [Boolean]
340
+ #
341
+ # @api private
342
+ def optional?(operand)
343
+ operand.respond_to?(:required?) && !operand.required?
344
+ end
345
+
346
+ end # module Logic
347
+ end # module Generator
348
+ end # module SQL
349
+ end # module Veritas