twowaysql 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +3 -0
- data/License.txt +13 -0
- data/Manifest.txt +38 -0
- data/README.txt +382 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +15 -0
- data/issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml +18 -0
- data/issues/issue-39023ea09e17e2d64bcef03aa59cdfe38b78ad5b.yaml +26 -0
- data/issues/issue-4bc308d55ae91f266e656162a4147d356de1166c.yaml +24 -0
- data/issues/issue-897995fa10377eabdf597e8e7692f17087c76923.yaml +26 -0
- data/issues/issue-bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8.yaml +26 -0
- data/issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml +18 -0
- data/issues/issue-f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a.yaml +18 -0
- data/issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml +18 -0
- data/issues/project.yaml +16 -0
- data/lib/twowaysql/node.rb +239 -0
- data/lib/twowaysql/parser.rb +489 -0
- data/lib/twowaysql/parser.y +226 -0
- data/lib/twowaysql/template.rb +75 -0
- data/lib/twowaysql/version.rb +9 -0
- data/lib/twowaysql.rb +6 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/large_sql_spec.rb +142 -0
- data/spec/learning_regex_spec.rb +234 -0
- data/spec/spec.opts +0 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/twowaysql_spec.rb +736 -0
- data/tasks/deployment.rake +53 -0
- data/tasks/ditz.rake +8 -0
- data/tasks/environment.rake +7 -0
- data/tasks/racc.rake +23 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +104 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2004-2008 the Seasar Foundation and the Others.
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
12
|
+
either express or implied. See the License for the specific language
|
13
|
+
governing permissions and limitations under the License.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml
|
9
|
+
issues/issue-39023ea09e17e2d64bcef03aa59cdfe38b78ad5b.yaml
|
10
|
+
issues/issue-4bc308d55ae91f266e656162a4147d356de1166c.yaml
|
11
|
+
issues/issue-897995fa10377eabdf597e8e7692f17087c76923.yaml
|
12
|
+
issues/issue-bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8.yaml
|
13
|
+
issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml
|
14
|
+
issues/issue-f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a.yaml
|
15
|
+
issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml
|
16
|
+
issues/project.yaml
|
17
|
+
lib/twowaysql.rb
|
18
|
+
lib/twowaysql/node.rb
|
19
|
+
lib/twowaysql/parser.rb
|
20
|
+
lib/twowaysql/parser.y
|
21
|
+
lib/twowaysql/template.rb
|
22
|
+
lib/twowaysql/version.rb
|
23
|
+
script/console
|
24
|
+
script/destroy
|
25
|
+
script/generate
|
26
|
+
script/txt2html
|
27
|
+
setup.rb
|
28
|
+
spec/large_sql_spec.rb
|
29
|
+
spec/learning_regex_spec.rb
|
30
|
+
spec/spec.opts
|
31
|
+
spec/spec_helper.rb
|
32
|
+
spec/twowaysql_spec.rb
|
33
|
+
tasks/deployment.rake
|
34
|
+
tasks/ditz.rake
|
35
|
+
tasks/environment.rake
|
36
|
+
tasks/racc.rake
|
37
|
+
tasks/rspec.rake
|
38
|
+
tasks/website.rake
|
data/README.txt
ADDED
@@ -0,0 +1,382 @@
|
|
1
|
+
= TwoWaySQL
|
2
|
+
|
3
|
+
=== sites:
|
4
|
+
* {Web Site}[http://twowaysql.rubyforge.org/]
|
5
|
+
* {Project Page}[http://rubyforge.org/projects/twowaysql]
|
6
|
+
* {API Doc}[http://twowaysql.rubyforge.org/rdoc/]
|
7
|
+
* {Issue Tracking}[http://twowaysql.rubyforge.org/issues/]
|
8
|
+
|
9
|
+
=== sources:
|
10
|
+
* http://github.com/twada/twowaysql/tree/master
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
== DESCRIPTION:
|
15
|
+
|
16
|
+
|
17
|
+
=== What is TwoWaySQL
|
18
|
+
|
19
|
+
'TwoWaySQL' is a concept, looks like a Template Engine for SQL.
|
20
|
+
|
21
|
+
It is initially invented and implemented in Seasar project's S2Dao[http://s2dao.seasar.org/en/index.html].
|
22
|
+
|
23
|
+
This package is a Ruby implementation of TwoWaySQL concept.
|
24
|
+
|
25
|
+
|
26
|
+
=== Why TwoWaySQL
|
27
|
+
|
28
|
+
Like any other technology, SQL is also in 80:20 world. 80% of SQL can be generated easily and automatically by O-R Mappers, 20% can not. 20% of your SQLs may large and complex, using CASE clause, self JOIN, UNION ALL, EXCEPT, ... these are the real strength of SQL and its set-based operations.
|
29
|
+
|
30
|
+
We better use them, to get the most out of RDBMS power.
|
31
|
+
|
32
|
+
TwoWaySQL encourages to write complex SQL manually. Just develop SQL using tools like pgAdmin3 in try and error style, then markup the SQL by TwoWaySQL. Usage and Features are in this doc.
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
=== Advantage
|
37
|
+
TwoWaySQL provides better separation of host language and SQL.
|
38
|
+
|
39
|
+
With TwoWaySQL, you can
|
40
|
+
* separate SQL (as file) from host language
|
41
|
+
* bind variables to SQL using Substitution comments
|
42
|
+
* modify SQL conditionally by using Directive comments
|
43
|
+
* run and preview TwoWaySQL-style SQL by tools like pgAdmin3, since the SQL is still valid SQL.
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
== One minute example
|
48
|
+
|
49
|
+
# given SQL string with TwoWaySQL comments
|
50
|
+
sql = <<-EOS
|
51
|
+
SELECT * FROM emp
|
52
|
+
/*BEGIN*/WHERE
|
53
|
+
/*IF ctx[:job]*/ job = /*ctx[:job]*/'CLERK' /*END*/
|
54
|
+
/*IF ctx[:deptno_list]*/ AND deptno IN /*ctx[:deptno_list]*/(20, 30) /*END*/
|
55
|
+
/*IF ctx[:age]*/ AND age > /*ctx[:age]*/30 /*END*/
|
56
|
+
/*END*/
|
57
|
+
/*IF ctx[:order_by] */ ORDER BY /*$ctx[:order_by]*/id /*$ctx[:order]*/ASC /*END*/
|
58
|
+
EOS
|
59
|
+
|
60
|
+
|
61
|
+
# parse the SQL to create template object
|
62
|
+
template = TwoWaySQL::Template.parse(sql)
|
63
|
+
|
64
|
+
|
65
|
+
# merge data with template
|
66
|
+
data = {
|
67
|
+
:age => 35,
|
68
|
+
:deptno_list => [10,20,30],
|
69
|
+
:order_by => 'age',
|
70
|
+
:order => 'DESC'
|
71
|
+
}
|
72
|
+
merged = template.merge(data)
|
73
|
+
|
74
|
+
|
75
|
+
expected_sql = <<-EOS
|
76
|
+
SELECT * FROM emp
|
77
|
+
WHERE
|
78
|
+
|
79
|
+
deptno IN (?, ?, ?)
|
80
|
+
AND age > ?
|
81
|
+
|
82
|
+
ORDER BY age DESC
|
83
|
+
EOS
|
84
|
+
|
85
|
+
merged.sql == expected_sql #=> true
|
86
|
+
merged.bound_variables #=> [10,20,30,35]
|
87
|
+
|
88
|
+
|
89
|
+
# use merged SQL and variables with any O-R Mapper you like (ex. Sequel)
|
90
|
+
require 'sequel'
|
91
|
+
DB = Sequel.connect('postgres://user:pass@localhost:5432/mydb')
|
92
|
+
rows = DB.fetch(merged.sql, *merged.bound_variables).all
|
93
|
+
. . .
|
94
|
+
|
95
|
+
|
96
|
+
==== What TwoWaySQL intended to do
|
97
|
+
* TwoWaySQL is intended to be a small and simple module.
|
98
|
+
* TwoWaySQL respects SQL and its set-based operations. TwoWaySQL assists writing complex SQL with ease.
|
99
|
+
* TwoWaySQL is not a replacement of ActiveRecord,Sequel,or any other O-R Mappers. Instead, TwoWaySQL will work with O-R Mappers well as a SQL construction module.
|
100
|
+
|
101
|
+
|
102
|
+
==== What TwoWaySQL is not
|
103
|
+
TwoWaySQL is not
|
104
|
+
* an O-R Mapper
|
105
|
+
* a SQL Parser
|
106
|
+
* a framework
|
107
|
+
* a Prepared Statement
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
== FEATURES/PROBLEMS:
|
112
|
+
|
113
|
+
* Substitution comments
|
114
|
+
* Bind variable comment
|
115
|
+
* Embedded variable comment
|
116
|
+
|
117
|
+
* Directive comments
|
118
|
+
* IF comment
|
119
|
+
* ELSE comment
|
120
|
+
* BEGIN comment
|
121
|
+
|
122
|
+
* actual SQL comment
|
123
|
+
|
124
|
+
|
125
|
+
=== Known limitations
|
126
|
+
|
127
|
+
* currently, ruby version of TwoWaySQL cannot parse multi-line comments.
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
== SYNOPSIS:
|
132
|
+
|
133
|
+
NOTE: some of this section is based on docs for S2Dao[http://s2dao.seasar.org/en/s2dao.html#SQLBind]
|
134
|
+
|
135
|
+
|
136
|
+
=== Published Classes
|
137
|
+
|
138
|
+
TwoWaySQL::Template is the class you may only use. TwoWaySQL::Template acts as a Facade for this package, others are for internal use.
|
139
|
+
|
140
|
+
|
141
|
+
=== Basic Usage
|
142
|
+
|
143
|
+
==== Input
|
144
|
+
* TwoWaySQL-style SQL(string,file or anything like IO) to TwoWaySQL::Template.parse to create template object (note: template object is stateless and reentrant, so you can cache it)
|
145
|
+
* (Optionally) TwoWaySQL::Template.parse accepts Hash of parse options as second argument
|
146
|
+
* data object(Hash-like object) to the TwoWaySQL::Template#merge then TwoWaySQL will evaluate the data as 'ctx'.
|
147
|
+
|
148
|
+
==== Output
|
149
|
+
* SQL String with placeholders (generally, '?' is used for placeholders)
|
150
|
+
* Array of bound variables for placeholders
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
=== SQL comment
|
155
|
+
|
156
|
+
Firstly, In TwoWaySQL, expressions are written within SQL comment such as within "/**/" and "--". SQL may still be executed since TwoWaySQL specific, non-SQL expressions are written within comments. As a best practice, it is better to first write and test SQL and then write expressions within comments.
|
157
|
+
|
158
|
+
To write actual comments in SQL, *insert a space* after "/*" before the comment string. For example, /* hoge*/. TwoWaySQL will recognize the space(s) after the comment start ("/*") and treat the enclosed content as an actual comment.
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
=== Bind variable comment
|
163
|
+
|
164
|
+
Bind variable comment is used to bind value(s) to the SQL.
|
165
|
+
Literal to the right of bind variable comment is automatically replaced with a value.
|
166
|
+
Bind variable comment syntax is as follows:
|
167
|
+
|
168
|
+
/*variable_name*/Literal
|
169
|
+
|
170
|
+
TwoWaySQL may use bind variable as follows. In this case, value of ctx[:empno] is automatically set. Data object that is passed to TwoWaySQL::Template#merge is evaled as name 'ctx'.
|
171
|
+
|
172
|
+
SELECT * FROM emp WHERE empno = /*ctx[:empno]*/7788
|
173
|
+
|
174
|
+
===== usage
|
175
|
+
|
176
|
+
sql = "SELECT * FROM emp WHERE job = /*ctx[:job]*/'CLERK' AND deptno = /*ctx[:deptno]*/20"
|
177
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
178
|
+
|
179
|
+
merged = template.merge(:job => "HOGE", :deptno => 30)
|
180
|
+
merged.sql #=> "SELECT * FROM emp WHERE job = ? AND deptno = ?"
|
181
|
+
merged.bound_variables #=> ["HOGE", 30]
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
==== IN clause
|
186
|
+
|
187
|
+
To bind multiple values in an IN clause, you can also use bind variable comment as well.
|
188
|
+
|
189
|
+
IN /*argument name*/(...)
|
190
|
+
|
191
|
+
TwoWaySQL may use bind variable as follows. In this case, ctx[:names] is automatically replaced with placeholders associated with number of values in the data.
|
192
|
+
|
193
|
+
IN /*ctx[:names]*/('aaa', 'bbb')
|
194
|
+
|
195
|
+
acceptable argument for IN clause is an array-like object. Say, Object that respond_to 'to_ary'.
|
196
|
+
|
197
|
+
===== usage
|
198
|
+
|
199
|
+
sql = "SELECT * FROM emp WHERE deptno IN /*ctx[:deptnoList]*/(10, 20) ORDER BY ename"
|
200
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
201
|
+
|
202
|
+
merged = template.merge(:deptnoList => [30,40,50])
|
203
|
+
merged.sql #=> "SELECT * FROM emp WHERE deptno IN (?, ?, ?) ORDER BY ename"
|
204
|
+
merged.bound_variables #=> [30,40,50]
|
205
|
+
|
206
|
+
merged2 = template.merge(:deptnoList => [80])
|
207
|
+
merged2.sql #=> "SELECT * FROM emp WHERE deptno IN (?) ORDER BY ename"
|
208
|
+
merged2.bound_variables #=> [80]
|
209
|
+
|
210
|
+
|
211
|
+
==== LIKE
|
212
|
+
|
213
|
+
If you want to use "LIKE", you may write bind variables:
|
214
|
+
|
215
|
+
ename LIKE /*ctx[:ename]*/'hoge'
|
216
|
+
|
217
|
+
Unfortunately, there is no special support for "LIKE". So, to use a wildcard character, add wildcard directy to the data. For example, to specify to include "COT", add wildcard character in the value as follows:
|
218
|
+
|
219
|
+
:ename => "%COT%"
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
==== Embedded variable comment
|
224
|
+
|
225
|
+
You can use Embedded variable comment to embed value directly (say without quoting or escaping) into the SQL as a string. Literal to the right of the Embedded variable comment will be replaced with value. Embedded variable comment has the following syntax:
|
226
|
+
|
227
|
+
/*$variable name*/Literal
|
228
|
+
|
229
|
+
===== CAUTION:
|
230
|
+
As you noticed. Embedded variable comment has risk for SQL Injection. Please note, like any other 'eval' usage of TwoWaySQL, Embedded variable comment evals the data in safe level 4. Therefore, dangerous actions in Ruby world (ex. system call, valiable assignments, tainted strings) are never executed. However, this is not enough. Valid ruby string is still dangerous string as SQL fragments. Do NOT use user input or any other strings outside your code. If you use Embedded variable comment, you should carefully check the data and its origin.
|
231
|
+
|
232
|
+
===== usage
|
233
|
+
|
234
|
+
sql = "SELECT * FROM emp ORDER BY /*$ctx[:order_by]*/ename /*$ctx[:order]*/ASC"
|
235
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
236
|
+
|
237
|
+
merged = template.merge(:order_by => 'id, :order => 'DESC')
|
238
|
+
merged.sql #=> "SELECT * FROM emp ORDER BY id DESC"
|
239
|
+
merged.bound_variables #=> []
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
=== IF comment
|
244
|
+
|
245
|
+
To change SQL during execution based on a condition, use IF comments. IF comment has the following syntax:
|
246
|
+
|
247
|
+
/*IF condition*/ .../*END*/
|
248
|
+
|
249
|
+
An example of IF comment is as follows:
|
250
|
+
|
251
|
+
/*IF ctx[:foo]*/hoge = /*ctx[:hoge]*/'abc'/*END*/
|
252
|
+
|
253
|
+
When the condition returns a truthy value, TwoWaySQL treats statements in "/*IF*/" and "/*END*/" as active. In the above example, "hoge = /*ctx[:hoge]*/'abc'" will be output only when 'eval(ctx[:foo])' retuens an truthy value.
|
254
|
+
|
255
|
+
|
256
|
+
==== usage
|
257
|
+
|
258
|
+
sql = "SELECT * FROM emp/*IF ctx[:job] */ WHERE job = /*ctx[:job]*/'CLERK'/*END*/"
|
259
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
260
|
+
|
261
|
+
|
262
|
+
# active case
|
263
|
+
merged = template.merge(:job => 'MANAGER')
|
264
|
+
merged.sql #=> 'SELECT * FROM emp WHERE job = ?'
|
265
|
+
merged.bound_variables #=> ['MANAGER']
|
266
|
+
|
267
|
+
# inactive case
|
268
|
+
ctx = {}
|
269
|
+
merged2 = template.merge(ctx)
|
270
|
+
merged2.sql #=> 'SELECT * FROM emp'
|
271
|
+
merged2.bound_variables #=> []
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
=== ELSE comment
|
276
|
+
|
277
|
+
You can use ELSE comment to activate statements when condition is false. Sn example of IF comment with ELSE is as follows.
|
278
|
+
|
279
|
+
/*IF ctx[:foo]*/hoge = /*ctx[:hoge]*/'abc'
|
280
|
+
-- ELSE hoge IS NULL
|
281
|
+
/*END*/
|
282
|
+
|
283
|
+
In this case, when the eval(ctx[:foo]) returns an falsy value, string "hoge IS NULL" will be active.
|
284
|
+
|
285
|
+
|
286
|
+
==== ELSE comment sample
|
287
|
+
|
288
|
+
sql = "SELECT * FROM emp WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'-- ELSE job IS NULL/*END*/"
|
289
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
290
|
+
|
291
|
+
# active case
|
292
|
+
merged = template.merge(:job => 'MANAGER')
|
293
|
+
merged.sql #=> 'SELECT * FROM emp WHERE job = ?'
|
294
|
+
merged.bound_variables #=> ['MANAGER']
|
295
|
+
|
296
|
+
# inactive case
|
297
|
+
ctx = {}
|
298
|
+
merged2 = template.merge(ctx)
|
299
|
+
merged2.sql #=> 'SELECT * FROM emp WHERE job IS NULL'
|
300
|
+
merged2.bound_variables #=> []
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
=== BEGIN comment
|
306
|
+
|
307
|
+
BEGIN comment is used to not output WHERE clause when all IF comment in a WHERE clause, which does not include an ELSE, is false. BEGIN comment should used with IF comment.
|
308
|
+
|
309
|
+
BEGIN comment syntax is as follows:
|
310
|
+
|
311
|
+
/*BEGIN*/WHERE clause/*END*/
|
312
|
+
|
313
|
+
So, BEGIN comment example is as follows:
|
314
|
+
|
315
|
+
/*BEGIN*/WHERE
|
316
|
+
/*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'/*END*/
|
317
|
+
/*IF ctx[:deptno]*/AND deptno = /*ctx[:deptno]*/20/*END*/
|
318
|
+
/*END*/
|
319
|
+
|
320
|
+
In the above example,
|
321
|
+
* when job and deptno are nil, WHERE clause will not be outputted.
|
322
|
+
* When ctx[:job] == nil and ctx[:deptno] != nil, then sql will "WHERE depno = ?".
|
323
|
+
* When ctx[:job] != nil and ctx[:deptno] == nil, then sql will "WHERE job = ?".
|
324
|
+
* When ctx[:job] != nil and ctx[:deptno] != nil, then sql will "WHERE job = ? AND depno = ?".
|
325
|
+
|
326
|
+
|
327
|
+
==== usage
|
328
|
+
|
329
|
+
sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'/*END*//*IF ctx[:deptno]*/ AND deptno = /*ctx[:deptno]*/20/*END*//*END*/"
|
330
|
+
template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
331
|
+
|
332
|
+
# when data is empty (no param exists)
|
333
|
+
ctx = {}
|
334
|
+
merged = template.merge(ctx)
|
335
|
+
merged.sql #=> 'SELECT * FROM emp'
|
336
|
+
merged.bound_variables #=> []
|
337
|
+
|
338
|
+
# when :job param exists
|
339
|
+
merged2 = template.merge(:job => 'MANAGER')
|
340
|
+
merged2.sql #=> 'SELECT * FROM emp WHERE job = ?'
|
341
|
+
merged2.bound_variables #=> ['MANAGER']
|
342
|
+
|
343
|
+
# when :job and :deptno param exists
|
344
|
+
ctx3 = {}
|
345
|
+
ctx3[:job] = "MANAGER"
|
346
|
+
ctx3[:deptno] = 20
|
347
|
+
merged3 = template.merge(ctx3)
|
348
|
+
merged3.sql #=> 'SELECT * FROM emp WHERE job = ? AND deptno = ?'
|
349
|
+
merged3.bound_variables #=> ['MANAGER',20]
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
== REQUIREMENTS:
|
354
|
+
|
355
|
+
* racc/parser (basically bundled with ruby)
|
356
|
+
|
357
|
+
|
358
|
+
== INSTALL:
|
359
|
+
|
360
|
+
* sudo gem install twowaysql
|
361
|
+
|
362
|
+
|
363
|
+
== AUTHOR:
|
364
|
+
|
365
|
+
* Takuto Wada(takuto.wada at gmail dot com)
|
366
|
+
|
367
|
+
|
368
|
+
== LICENSE:
|
369
|
+
|
370
|
+
Copyright 2004-2008 the Seasar Foundation and the Others.
|
371
|
+
|
372
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
373
|
+
you may not use this file except in compliance with the License.
|
374
|
+
You may obtain a copy of the License at
|
375
|
+
|
376
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
377
|
+
|
378
|
+
Unless required by applicable law or agreed to in writing, software
|
379
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
380
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
381
|
+
either express or implied. See the License for the specific language
|
382
|
+
governing permissions and limitations under the License.
|
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'twowaysql/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Takuto Wada' # can also be an array of Authors
|
4
|
+
EMAIL = "takuto.wada at gmail dot com"
|
5
|
+
DESCRIPTION = "Template Engine for SQL"
|
6
|
+
GEM_NAME = 'twowaysql' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'twowaysql' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
EXTRA_DEPENDENCIES = [
|
11
|
+
# ['activesupport', '>= 1.3.1']
|
12
|
+
] # An array of rubygem dependencies [name, version]
|
13
|
+
|
14
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
15
|
+
@config = nil
|
16
|
+
RUBYFORGE_USERNAME = "twada"
|
17
|
+
def rubyforge_username
|
18
|
+
unless @config
|
19
|
+
begin
|
20
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
21
|
+
rescue
|
22
|
+
puts <<-EOS
|
23
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
24
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
25
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
26
|
+
EOS
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
REV = nil
|
35
|
+
# UNCOMMENT IF REQUIRED:
|
36
|
+
# REV = YAML.load(`svn info`)['Revision']
|
37
|
+
VERS = TwoWaySQL::VERSION::STRING + (REV ? ".#{REV}" : "")
|
38
|
+
RDOC_OPTS = ['--quiet', '--title', 'twowaysql documentation',
|
39
|
+
"--opname", "index.html",
|
40
|
+
"--line-numbers",
|
41
|
+
"--main", "README",
|
42
|
+
"--inline-source"]
|
43
|
+
|
44
|
+
class Hoe
|
45
|
+
def extra_deps
|
46
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
47
|
+
@extra_deps
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Generate all the Rake tasks
|
52
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
53
|
+
$hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
54
|
+
p.developer(AUTHOR, EMAIL)
|
55
|
+
p.description = DESCRIPTION
|
56
|
+
p.summary = DESCRIPTION
|
57
|
+
p.url = HOMEPATH
|
58
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
59
|
+
p.test_globs = ["test/**/test_*.rb"]
|
60
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
61
|
+
|
62
|
+
# == Optional
|
63
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
64
|
+
#p.extra_deps = EXTRA_DEPENDENCIES
|
65
|
+
|
66
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
67
|
+
end
|
68
|
+
|
69
|
+
CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
70
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
71
|
+
$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
72
|
+
$hoe.rsync_args = '-av --delete --ignore-errors'
|
73
|
+
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
@@ -0,0 +1,18 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: better whitespace handling
|
3
|
+
desc: better whitespace handling on Scanner/Grammer.
|
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 09:00:15.483485 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: 25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-03 09:01:47.792705 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- fix some dirty rules for whitespaces, if possible.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: integrate ditz html into site
|
3
|
+
desc: Integrate ditz html output into site. Ditz site(http://ditz.rubyforge.org/ditz) may help.
|
4
|
+
type: :task
|
5
|
+
component: twowaysql
|
6
|
+
release:
|
7
|
+
reporter: takuto <takuto.wada@gmail.com>
|
8
|
+
status: :closed
|
9
|
+
disposition: :fixed
|
10
|
+
creation_time: 2008-09-04 17:19:57.462508 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: 39023ea09e17e2d64bcef03aa59cdfe38b78ad5b
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-04 17:20:02.538939 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- ""
|
19
|
+
- - 2008-09-04 21:28:42.162604 Z
|
20
|
+
- takuto <takuto.wada@gmail.com>
|
21
|
+
- changed status from unstarted to in_progress
|
22
|
+
- integrate using rake
|
23
|
+
- - 2008-09-04 22:00:49.377211 Z
|
24
|
+
- takuto <takuto.wada@gmail.com>
|
25
|
+
- closed with disposition fixed
|
26
|
+
- done.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: "'binding' object support"
|
3
|
+
desc: TwoWaySQL::Template#merge should accept 'binding' object?
|
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:37:03.712475 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: 4bc308d55ae91f266e656162a4147d356de1166c
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-03 08:41:40.758367 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- |-
|
19
|
+
pros:
|
20
|
+
- user can control names in TwoWaySQL comments
|
21
|
+
- works well with ActiveRecord?
|
22
|
+
cons:
|
23
|
+
- any security risk?
|
24
|
+
- increase coupling between host language and SQL
|
@@ -0,0 +1,26 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: RubyForge settings
|
3
|
+
desc: Releases and documents will be hosted on RubyForge
|
4
|
+
type: :task
|
5
|
+
component: twowaysql
|
6
|
+
release: 0.2 release
|
7
|
+
reporter: takuto <takuto.wada@gmail.com>
|
8
|
+
status: :in_progress
|
9
|
+
disposition:
|
10
|
+
creation_time: 2008-09-04 17:02:51.175082 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: 897995fa10377eabdf597e8e7692f17087c76923
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-04 17:03:44.376333 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- |-
|
19
|
+
1. get user account
|
20
|
+
2. create twowaysql project
|
21
|
+
3. some settings for upload
|
22
|
+
4. any other task?
|
23
|
+
- - 2008-09-04 21:20:14.555151 Z
|
24
|
+
- takuto <takuto.wada@gmail.com>
|
25
|
+
- changed status from unstarted to in_progress
|
26
|
+
- ""
|
@@ -0,0 +1,26 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: rdoc for published classes and methods
|
3
|
+
desc: rdoc for published classes and methods
|
4
|
+
type: :task
|
5
|
+
component: twowaysql
|
6
|
+
release: 0.2 release
|
7
|
+
reporter: takuto <takuto.wada@gmail.com>
|
8
|
+
status: :closed
|
9
|
+
disposition: :fixed
|
10
|
+
creation_time: 2008-09-03 08:43:57.377882 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-03 08:44:14.224213 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- docs needed for published classes and methods
|
19
|
+
- - 2008-09-05 05:54:35.728338 Z
|
20
|
+
- takuto <takuto.wada@gmail.com>
|
21
|
+
- changed status from unstarted to in_progress
|
22
|
+
- start
|
23
|
+
- - 2008-09-05 07:35:16.577247 Z
|
24
|
+
- takuto <takuto.wada@gmail.com>
|
25
|
+
- closed with disposition fixed
|
26
|
+
- docs not completed for forwardable methods. better reorganized?
|
@@ -0,0 +1,18 @@
|
|
1
|
+
--- !ditz.rubyforge.org,2008-03-06/issue
|
2
|
+
title: change line-based scanning to whole string based scanning
|
3
|
+
desc: try whole string based scanning to handle multiline comments and directives
|
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-03 09:04:04.695887 Z
|
11
|
+
references: []
|
12
|
+
|
13
|
+
id: f2b773020b54f839c03d899b38b5113c8fd991df
|
14
|
+
log_events:
|
15
|
+
- - 2008-09-03 09:04:46.759048 Z
|
16
|
+
- takuto <takuto.wada@gmail.com>
|
17
|
+
- created
|
18
|
+
- this is a trial. not necessary for current specs.
|