Guest User

Untitled

a guest
Feb 21st, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.14 KB | None | 0 0
  1. module Sql
  2. module Syntax
  3.  
  4. def self.serialize(sexp)
  5. send(*sexp)
  6. end
  7.  
  8. private
  9. def self.and(*args)
  10. "(" + args.map do |expr|
  11. send(*expr)
  12. end.join(" AND ") + ")"
  13. end
  14.  
  15. def self.or(*args)
  16. "(" + args.map do |expr|
  17. send(*expr)
  18. end.join(" OR ") + ")"
  19. end
  20.  
  21. def self.gt(field, value)
  22. "#{field} > #{value}"
  23. end
  24.  
  25. def self.lt(field, value)
  26. "#{field} < #{value}"
  27. end
  28.  
  29. def self.eq(field, value)
  30. "#{field} = #{value}"
  31. end
  32. end
  33. end
  34.  
  35. class UnboundCondition
  36.  
  37. def self.gt(field, value)
  38. new(:gt, field, value)
  39. end
  40.  
  41. def self.lt(field, value)
  42. new(:lt, field, value)
  43. end
  44.  
  45. def self.eq(field, value)
  46. new(:eq, field, value)
  47. end
  48.  
  49. def initialize(operator, field, value)
  50. @operator = operator
  51. @field = field
  52. @value = value
  53. end
  54.  
  55. def and(*others)
  56. AndExpression.new(self, *others)
  57. end
  58.  
  59. def or(*others)
  60. OrExpression.new(self, *others)
  61. end
  62.  
  63. def to_a
  64. [@operator, @field, @value]
  65. end
  66.  
  67. end
  68.  
  69. class Expression
  70. def initialize(*values)
  71. @values = values
  72. end
  73.  
  74. def or(*values)
  75. OrExpression.new(self, *values)
  76. end
  77.  
  78. def and(*values)
  79. AndExpression.new(self, *values)
  80. end
  81.  
  82. def to_a
  83. [self.class.operator, *@values.map { |value| value.to_a }]
  84. end
  85.  
  86. private
  87. def self.operator
  88. raise NotImplementedError.new("Expression is an abstract class")
  89. end
  90. end
  91.  
  92. class AndExpression < Expression
  93. private
  94. def self.operator
  95. :and
  96. end
  97. end
  98.  
  99. class OrExpression < Expression
  100. private
  101. def self.operator
  102. :or
  103. end
  104. end
  105.  
  106. class Query
  107. class Conditions
  108. def initialize(expression = nil)
  109. @expression = expression
  110. end
  111.  
  112. def and(expression)
  113. append(:and, expression)
  114. self
  115. end
  116.  
  117. def or(expression)
  118. append(:or, expression)
  119. self
  120. end
  121.  
  122. def set(expression)
  123. @expression = expression
  124. self
  125. end
  126.  
  127. def to_a
  128. @expression.to_a
  129. end
  130.  
  131. private
  132. def append(method, expression)
  133. if @expression
  134. @expression = case method
  135. when :and then @expression.and(expression)
  136. when :or then @expression.or(expression)
  137. else raise NotImplementedError.new("Method #{method} unsupported")
  138. end
  139. else
  140. @expression = expression
  141. end
  142. end
  143. end
  144.  
  145. def initialize(root)
  146. @root = root
  147. @conditions = Conditions.new
  148. end
  149.  
  150. def conditions
  151. @conditions
  152. end
  153.  
  154. def conditions=(expression)
  155. @conditions = Conditions.new(expression)
  156. end
  157. end
  158.  
  159. a = [:or,
  160. [:or,
  161. [:eq, :name, "John"],
  162. [:eq, :name, "Jane"]
  163. ],
  164. [:and,
  165. [:gt, :age, 3],
  166. [:lt, :age, 65]
  167. ]
  168. ]
  169.  
  170. p Sql::Syntax.serialize(a)
  171.  
  172. q = Query.new(Object)
  173. john = UnboundCondition.eq(:name, "John")
  174. jane = UnboundCondition.eq(:name, "Jane")
  175. toddler = UnboundCondition.gt(:age, 3)
  176. not_senior = UnboundCondition.lt(:age, 65)
  177.  
  178. q.conditions.set(john.or(jane)).or(toddler.and(not_senior))
  179.  
  180. p Sql::Syntax.serialize(q.conditions.to_a)
Add Comment
Please, Sign In to add comment