activetokyocabinet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,305 @@
1
+ class SQLParser
2
+ options no_result_var
3
+ rule
4
+ sql : create_statement
5
+ | read_statemant
6
+ | update_statemant
7
+ | delete_statemant
8
+
9
+ create_statement : INSERT INTO id '(' id_list ')' VALUES '(' value_list ')'
10
+ {
11
+ {:command => :insert, :table => val[2], :column_list => val[4], :value_list => val[8]}
12
+ }
13
+
14
+ read_statemant : SELECT select_list FROM id where_clause order_by_clause limit_clause offset_clause
15
+ {
16
+ {:command => :select, :table => val[3], :select_list => val[1], :condition => val[4], :order => val[5], :limit => val[6], :offset => val[7]}
17
+ }
18
+ | SELECT count_clause FROM id where_clause order_by_clause limit_clause offset_clause
19
+ {
20
+ {:command => :select, :table => val[3], :count => val[1], :condition => val[4]}
21
+ }
22
+
23
+ count_clause : COUNT '(' count_arg ')'
24
+ {
25
+ "count_all"
26
+ }
27
+ | COUNT '(' count_arg ')' AS id
28
+ {
29
+ val[5]
30
+ }
31
+
32
+ count_arg : '*'
33
+ | id
34
+
35
+ select_list : '*'
36
+ {
37
+ []
38
+ }
39
+ | id_list
40
+
41
+ where_clause :
42
+ {
43
+ []
44
+ }
45
+ | WHERE id_search_condition
46
+ {
47
+ val[1]
48
+ }
49
+ | WHERE search_condition
50
+ {
51
+ val[1]
52
+ }
53
+
54
+ id_search_condition : id_predicate
55
+ | '(' id_predicate ')'
56
+ {
57
+ val[1]
58
+ }
59
+
60
+ id_predicate : ID '=' value
61
+ {
62
+ val[2]
63
+ }
64
+ | ID IN '(' value_list ')'
65
+ {
66
+ val[3]
67
+ }
68
+
69
+ search_condition : boolean_primary
70
+ {
71
+ [val[0]].flatten
72
+ }
73
+ | search_condition AND boolean_primary
74
+ {
75
+ (val[0] << val[2]).flatten
76
+ }
77
+
78
+ boolean_primary : predicate
79
+ | '(' search_condition ')'
80
+ {
81
+ val[1]
82
+ }
83
+
84
+ predicate : id op value
85
+ {
86
+ {:name => val[0], :op => tccond(val[1], val[2]), :expr => val[2]}
87
+ }
88
+ | id op '(' value_list ')'
89
+ {
90
+ {:name => val[0], :op => tccond(val[1], val[3]), :expr => val[3]}
91
+ }
92
+ order_by_clause :
93
+ {
94
+ nil
95
+ }
96
+ | ORDER BY id ordering_spec
97
+ {
98
+ {:name => val[2], :type => val[3]}
99
+ }
100
+
101
+ ordering_spec :
102
+ {
103
+ :QOSTRASC
104
+ }
105
+ | ORDER
106
+
107
+ limit_clause :
108
+ {
109
+ nil
110
+ }
111
+ | LIMIT NUMBER
112
+ {
113
+ val[1]
114
+ }
115
+
116
+ offset_clause :
117
+ {
118
+ nil
119
+ }
120
+ | OFFSET NUMBER
121
+ {
122
+ val[1]
123
+ }
124
+
125
+ update_statemant : UPDATE id SET set_clause_list where_clause
126
+ {
127
+ {:command => :update, :table => val[1], :set_clause_list => val[3], :condition => val[4]}
128
+ }
129
+
130
+ set_clause_list : set_clause
131
+ | set_clause_list ',' set_clause
132
+ {
133
+ val[0].merge val[2]
134
+ }
135
+
136
+ set_clause : id '=' value
137
+ {
138
+ {val[0] => val[2]}
139
+ }
140
+
141
+ delete_statemant : DELETE FROM id where_clause
142
+ {
143
+ {:command => :delete, :table => val[2], :condition => val[3]}
144
+ }
145
+
146
+ id : IDENTIFIER
147
+
148
+ id_list : id
149
+ {
150
+ [val[0]]
151
+ }
152
+ | id_list ',' id
153
+ {
154
+ val[0] << val[2]
155
+ }
156
+
157
+ value : STRING
158
+ | NUMBER
159
+ | NULL
160
+
161
+ value_list : value
162
+ {
163
+ [val[0]]
164
+ }
165
+ | value_list ',' value
166
+ {
167
+ val[0] << val[2]
168
+ }
169
+
170
+ op : BW
171
+ | EW
172
+ | INCALL
173
+ | INCANY
174
+ | INC
175
+ | IN
176
+ | EQANY
177
+ | REGEXP
178
+ | BETWEEN
179
+ | FTS
180
+ | FTSALL
181
+ | FTSANY
182
+ | FTSEX
183
+ | '>='
184
+ | '<='
185
+ | '>'
186
+ | '<'
187
+ | '='
188
+
189
+ end
190
+
191
+ ---- header
192
+
193
+ require 'strscan'
194
+
195
+ module ActiveTokyoCabinet
196
+
197
+ ---- inner
198
+
199
+ def initialize(obj)
200
+ src = obj.is_a?(IO) ? obj.read : obj.to_s
201
+ @ss = StringScanner.new(src)
202
+ end
203
+
204
+ def scan
205
+ piece = nil
206
+
207
+ until @ss.eos?
208
+ if (tok = @ss.scan /\s+/)
209
+ # nothing to do
210
+ elsif (tok = @ss.scan /(?:BW|EW|INCALL|INCANY|INC|IN|EQANY|REGEXP|BETWEEN|FTS|FTSALL|FTSANY|FTSEX)\b/i)
211
+ yield tok.upcase.to_sym, tok
212
+ elsif (tok = @ss.scan /(?:>=|<=|>|<|=)/)
213
+ yield tok, tok
214
+ elsif (tok = @ss.scan /(?:INSERT|INTO|VALUES|SELECT|FROM|WHERE|AND|UPDATE|SET|DELETE|COUNT|ORDER|BY|LIMIT|OFFSET|AS)\b/i)
215
+ yield tok.upcase.to_sym, tok
216
+ elsif (tok = @ss.scan /(?:ASC|DESC|STRASC|STRDESC|NUMASC|NUMDESC)\b/i)
217
+ yield :ORDER, tcordertype(tok)
218
+ elsif (tok = @ss.scan /NULL\b/i)
219
+ yield :NULL, nil
220
+ elsif (tok = @ss.scan /'(?:[^']|'')*'/) #'
221
+ yield :STRING, tok.slice(1...-1).gsub(/''/, "'")
222
+ elsif (tok = @ss.scan /-?(?:0|[1-9]\d*)(?:\.\d+)/)
223
+ yield :NUMBER, tok.to_f
224
+ elsif (tok = @ss.scan /-?(?:0|[1-9]\d*)/)
225
+ yield :NUMBER, tok.to_i
226
+ elsif (tok = @ss.scan /[,\(\)\*]/)
227
+ yield tok, tok
228
+ elsif (tok = @ss.scan /(?:[a-z_][\w]+\.)*ID\b/i)
229
+ yield :ID, tok
230
+ elsif (tok = @ss.scan /(?:[a-z_][\w]+\.)*[a-z_][\w]+/i)
231
+ yield :IDENTIFIER, tok
232
+ else
233
+ raise Racc::ParseError, ('parse error on value "%s"' % @ss.rest.inspect)
234
+ end
235
+ end
236
+
237
+ yield false, '$'
238
+ end
239
+ private :scan
240
+
241
+ def parse
242
+ yyparse self, :scan
243
+ end
244
+
245
+ def tccond(op, expr)
246
+ case op.upcase
247
+ when '='
248
+ expr.kind_of?(Numeric) ? :QCNUMEQ : :QCSTREQ
249
+ when 'INC'
250
+ :QCSTRINC
251
+ when 'BW'
252
+ :QCSTRBW
253
+ when 'EW'
254
+ :QCSTREW
255
+ when 'INCALL'
256
+ :QCSTRAND
257
+ when 'INCANY'
258
+ :QCSTROR
259
+ when 'IN', 'EQANY'
260
+ expr.all? {|i| i.kind_of?(Numeric) } ? :QCNUMOREQ : :QCSTROREQ
261
+ when 'REGEXP'
262
+ :QCSTRRX
263
+ when '>'
264
+ :QCNUMGT
265
+ when '>='
266
+ :QCNUMGE
267
+ when '<'
268
+ :QCNUMLT
269
+ when '<='
270
+ :QCNUMLE
271
+ when 'BETWEEN'
272
+ :QCNUMBT
273
+ when 'FTS'
274
+ :QCFTSPH
275
+ when 'FTSALL'
276
+ :QCFTSAND
277
+ when 'FTSANY'
278
+ :QCFTSOR
279
+ when 'FTSEX'
280
+ :QCFTSEX
281
+ else
282
+ raise 'must not happen'
283
+ end
284
+ end
285
+ private :tccond
286
+
287
+ def tcordertype(type)
288
+ case type.upcase
289
+ when 'ASC', 'STRASC'
290
+ :QOSTRASC
291
+ when 'DESC', 'STRASC'
292
+ :QOSTRASC
293
+ when 'NUMASC'
294
+ :QONUMASC
295
+ when 'NUMDESC'
296
+ :QONUMDESC
297
+ else
298
+ raise 'must not happen'
299
+ end
300
+ end
301
+ private :tcordertype
302
+
303
+ ---- footer
304
+
305
+ end # module ActiveTokyoCabinet
@@ -0,0 +1,20 @@
1
+ module ActiveTokyoCabinet
2
+ module TDB
3
+ def self.included(mod)
4
+ {:string => :to_s, :int => :to_i, :float => :to_s}.each do |type, conv|
5
+ mod.instance_eval %{
6
+ def #{type}(name)
7
+ unless @columns
8
+ primary_key = ActiveRecord::ConnectionAdapters::Column.new('id', nil)
9
+ primary_key.primary = true
10
+ @columns = [primary_key]
11
+ end
12
+
13
+ @columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, nil)
14
+ class_eval "def \#{name}; v = self[:\#{name}]; v && v.#{conv}; end"
15
+ end
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activetokyocabinet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - winebarrel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-06 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: tokyocabinet
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description:
36
+ email: sgwr_dts@yahoo.co.jp
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ files:
44
+ - lib/active_record/connection_adapters/tokyocabinet_adapter.rb
45
+ - lib/active_tokyocabinet/tdb.rb
46
+ - lib/active_tokyocabinet/sqlparser.y
47
+ - lib/active_tokyocabinet/sqlparser.tab.rb
48
+ - README
49
+ has_rdoc: true
50
+ homepage: http://activetokyocabi.rubyforge.org/
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --title
56
+ - ActiveTokyoCabinet - a library for using TokyoCabinet under ActiveRecord.
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: activetokyocabinet
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: ActiveTokyoCabinet is a library for using TokyoCabinet under ActiveRecord.
78
+ test_files: []
79
+