twowaysql 0.2.0

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 (39) hide show
  1. data/History.txt +3 -0
  2. data/License.txt +13 -0
  3. data/Manifest.txt +38 -0
  4. data/README.txt +382 -0
  5. data/Rakefile +4 -0
  6. data/config/hoe.rb +73 -0
  7. data/config/requirements.rb +15 -0
  8. data/issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml +18 -0
  9. data/issues/issue-39023ea09e17e2d64bcef03aa59cdfe38b78ad5b.yaml +26 -0
  10. data/issues/issue-4bc308d55ae91f266e656162a4147d356de1166c.yaml +24 -0
  11. data/issues/issue-897995fa10377eabdf597e8e7692f17087c76923.yaml +26 -0
  12. data/issues/issue-bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8.yaml +26 -0
  13. data/issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml +18 -0
  14. data/issues/issue-f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a.yaml +18 -0
  15. data/issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml +18 -0
  16. data/issues/project.yaml +16 -0
  17. data/lib/twowaysql/node.rb +239 -0
  18. data/lib/twowaysql/parser.rb +489 -0
  19. data/lib/twowaysql/parser.y +226 -0
  20. data/lib/twowaysql/template.rb +75 -0
  21. data/lib/twowaysql/version.rb +9 -0
  22. data/lib/twowaysql.rb +6 -0
  23. data/script/console +10 -0
  24. data/script/destroy +14 -0
  25. data/script/generate +14 -0
  26. data/script/txt2html +82 -0
  27. data/setup.rb +1585 -0
  28. data/spec/large_sql_spec.rb +142 -0
  29. data/spec/learning_regex_spec.rb +234 -0
  30. data/spec/spec.opts +0 -0
  31. data/spec/spec_helper.rb +10 -0
  32. data/spec/twowaysql_spec.rb +736 -0
  33. data/tasks/deployment.rake +53 -0
  34. data/tasks/ditz.rake +8 -0
  35. data/tasks/environment.rake +7 -0
  36. data/tasks/racc.rake +23 -0
  37. data/tasks/rspec.rake +21 -0
  38. data/tasks/website.rake +17 -0
  39. metadata +104 -0
@@ -0,0 +1,18 @@
1
+ --- !ditz.rubyforge.org,2008-03-06/issue
2
+ title: Handle Embedded variable comment at Scanner/Grammer level
3
+ desc: Handle Embedded variable comment at Scanner/Grammer level. Currently it is handled at Node object level, so Scanner does not know the Substitution comment is Bind variable comment or Embedded variable comment. However Node should not be responsible for that, Scanner/Grammer should do.
4
+ type: :task
5
+ component: twowaysql
6
+ release:
7
+ reporter: takuto <takuto.wada@gmail.com>
8
+ status: :unstarted
9
+ disposition:
10
+ creation_time: 2008-09-04 19:53:35.026331 Z
11
+ references: []
12
+
13
+ id: f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a
14
+ log_events:
15
+ - - 2008-09-04 19:53:37.545312 Z
16
+ - takuto <takuto.wada@gmail.com>
17
+ - created
18
+ - ""
@@ -0,0 +1,18 @@
1
+ --- !ditz.rubyforge.org,2008-03-06/issue
2
+ title: preserve actual comment content
3
+ desc: preserve actual comment content
4
+ type: :feature
5
+ component: twowaysql
6
+ release:
7
+ reporter: takuto <takuto.wada@gmail.com>
8
+ status: :unstarted
9
+ disposition:
10
+ creation_time: 2008-09-03 08:33:12.940300 Z
11
+ references: []
12
+
13
+ id: f64d73ed4f9854f1ded77e6496dbf59cfb3770a7
14
+ log_events:
15
+ - - 2008-09-03 08:33:34.448031 Z
16
+ - takuto <takuto.wada@gmail.com>
17
+ - created
18
+ - preserve actual comment content if :preserve_comment is on.
@@ -0,0 +1,16 @@
1
+ --- !ditz.rubyforge.org,2008-03-06/project
2
+ name: twowaysql
3
+ version: "0.4"
4
+ components:
5
+ - !ditz.rubyforge.org,2008-03-06/component
6
+ name: twowaysql
7
+ releases:
8
+ - !ditz.rubyforge.org,2008-03-06/release
9
+ name: 0.2 release
10
+ status: :unreleased
11
+ release_time:
12
+ log_events:
13
+ - - 2008-09-03 08:30:15.096853 Z
14
+ - takuto <takuto.wada@gmail.com>
15
+ - created
16
+ - first published version.
@@ -0,0 +1,239 @@
1
+ unless String.method_defined?(:start_with?)
2
+ class String #:nodoc:
3
+ def start_with?(prefix)
4
+ prefix = prefix.to_s
5
+ self[0, prefix.length] == prefix
6
+ end
7
+ end
8
+ end
9
+
10
+
11
+ module TwoWaySQL
12
+
13
+ class Context
14
+
15
+ def initialize(data)
16
+ @data = data
17
+ @enabled = true
18
+ @bound_variables = []
19
+ @sql_fragments = []
20
+ end
21
+ attr_reader :bound_variables
22
+ attr_reader :sql_fragments
23
+ attr_reader :data
24
+
25
+ def sql(separator="")
26
+ @sql_fragments.join(separator)
27
+ end
28
+
29
+ def fork_child
30
+ child = Context.new(@data)
31
+ child.disable!
32
+ child
33
+ end
34
+
35
+ def join_child(child_ctx)
36
+ @sql_fragments.concat(child_ctx.sql_fragments)
37
+ @bound_variables.concat(child_ctx.bound_variables)
38
+ end
39
+
40
+ def add_sql(sql_fragment)
41
+ @sql_fragments << sql_fragment
42
+ end
43
+
44
+ def add_value(value)
45
+ @sql_fragments << '?'
46
+ @bound_variables << value
47
+ end
48
+
49
+ def add_values(values)
50
+ @sql_fragments << Array.new(values.size, '?').join(', ')
51
+ @bound_variables.concat(values)
52
+ end
53
+
54
+ def enabled?
55
+ @enabled
56
+ end
57
+
58
+ def enable!
59
+ @enabled = true
60
+ end
61
+
62
+ protected
63
+ def disable!
64
+ @enabled = false
65
+ end
66
+ end
67
+
68
+
69
+
70
+ class Node
71
+ protected
72
+ def exec_list(nodes, ctx)
73
+ v = nil
74
+ nodes.each do |i|
75
+ v = i.accept(ctx)
76
+ end
77
+ v
78
+ end
79
+
80
+ def do_eval(ctx, exp)
81
+ safe_eval(ctx.data, exp)
82
+ end
83
+
84
+ private
85
+ def safe_eval(ctx, exp)
86
+ within_safe_level(4) { eval(exp) }
87
+ end
88
+
89
+ def within_safe_level(level)
90
+ result = nil
91
+ Thread.start {
92
+ $SAFE = level
93
+ result = yield
94
+ }.join
95
+ result
96
+ end
97
+ end
98
+
99
+
100
+ class RootNode < Node
101
+ def initialize(tree)
102
+ @tree = tree
103
+ end
104
+ def accept(ctx)
105
+ exec_list(@tree, ctx)
106
+ end
107
+ def children
108
+ @tree
109
+ end
110
+ end
111
+
112
+
113
+ class IfNode < Node
114
+ def initialize(cond, tstmt, fstmt)
115
+ @condition = cond
116
+ @tstmt = tstmt
117
+ @fstmt = fstmt
118
+ end
119
+ def accept(ctx)
120
+ if do_eval(ctx, @condition)
121
+ exec_list(@tstmt, ctx)
122
+ ctx.enable!
123
+ elsif @fstmt
124
+ exec_list(@fstmt, ctx)
125
+ ctx.enable!
126
+ end
127
+ end
128
+ end
129
+
130
+
131
+ class BeginNode < Node
132
+ def initialize(tree)
133
+ @tree = tree
134
+ end
135
+ def accept(ctx)
136
+ child_ctx = ctx.fork_child
137
+ exec_list(@tree, child_ctx)
138
+ if child_ctx.enabled?
139
+ ctx.join_child(child_ctx)
140
+ end
141
+ end
142
+ end
143
+
144
+
145
+ class SubStatementNode < Node
146
+ def initialize(prefix, tree)
147
+ @prefix = prefix
148
+ @tree = tree
149
+ end
150
+ def accept(ctx)
151
+ ctx.add_sql(@prefix) if ctx.enabled?
152
+ exec_list(@tree, ctx)
153
+ end
154
+ def each
155
+ yield self
156
+ end
157
+ end
158
+
159
+
160
+ class SubstitutionNode < Node
161
+ def initialize(exp)
162
+ @exp = exp
163
+ end
164
+ def accept(ctx)
165
+ if @exp.start_with?('$')
166
+ embed_value(ctx)
167
+ else
168
+ substitute(ctx)
169
+ end
170
+ end
171
+ def substitute(ctx)
172
+ ctx.add_value(do_eval(ctx, @exp))
173
+ end
174
+ def embed_value(ctx)
175
+ result = do_eval(ctx, @exp[1..-1])
176
+ ctx.add_sql(result) unless result.nil?
177
+ end
178
+ end
179
+
180
+
181
+ class QuestionNode < Node
182
+ def initialize(num)
183
+ @num = num
184
+ end
185
+ def accept(ctx)
186
+ ctx.add_value(ctx.data[@num])
187
+ end
188
+ end
189
+
190
+
191
+ class ParenSubstitutionNode < Node
192
+ def initialize(exp)
193
+ @exp = exp
194
+ end
195
+ def accept(ctx)
196
+ result = do_eval(ctx, @exp)
197
+ return if result.nil?
198
+ if result.respond_to?('to_ary')
199
+ bind_values(ctx, result.to_ary)
200
+ else
201
+ ctx.add_value(result)
202
+ end
203
+ end
204
+ def bind_values(ctx, ary)
205
+ return if ary.empty?
206
+ ctx.add_sql("(")
207
+ ctx.add_values(ary)
208
+ ctx.add_sql(")")
209
+ end
210
+ end
211
+
212
+
213
+ class LiteralNode < Node
214
+ def initialize(val)
215
+ @val = val
216
+ end
217
+ def accept(ctx)
218
+ ctx.add_sql(@val)
219
+ end
220
+ end
221
+
222
+
223
+ class CommentNode < Node
224
+ def initialize(val)
225
+ @val = val
226
+ end
227
+ def accept(ctx)
228
+ # nothing to do
229
+ end
230
+ end
231
+
232
+
233
+ class EolNode < Node
234
+ def accept(ctx)
235
+ ctx.add_sql("\n")
236
+ end
237
+ end
238
+
239
+ end