sunstone 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_record/connection_adapters/sunstone/column.rb +19 -0
  3. data/lib/active_record/connection_adapters/sunstone/database_statements.rb +40 -0
  4. data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +95 -0
  5. data/lib/active_record/connection_adapters/sunstone/type/date_time.rb +22 -0
  6. data/lib/active_record/connection_adapters/sunstone_adapter.rb +177 -0
  7. data/lib/arel/collectors/sunstone.rb +75 -0
  8. data/lib/arel/visitors/sunstone.rb +769 -0
  9. data/lib/ext/active_record/associations/builder/has_and_belongs_to_many.rb +48 -0
  10. data/lib/ext/active_record/relation.rb +26 -0
  11. data/lib/ext/active_record/statement_cache.rb +24 -0
  12. data/lib/sunstone.rb +37 -347
  13. data/lib/sunstone/connection.rb +337 -0
  14. data/sunstone.gemspec +3 -2
  15. data/test/sunstone/connection_test.rb +319 -0
  16. data/test/sunstone/parser_test.rb +21 -21
  17. metadata +30 -36
  18. data/lib/sunstone/model.rb +0 -23
  19. data/lib/sunstone/model/attributes.rb +0 -99
  20. data/lib/sunstone/model/persistence.rb +0 -168
  21. data/lib/sunstone/schema.rb +0 -38
  22. data/lib/sunstone/type/boolean.rb +0 -19
  23. data/lib/sunstone/type/date_time.rb +0 -20
  24. data/lib/sunstone/type/decimal.rb +0 -19
  25. data/lib/sunstone/type/integer.rb +0 -17
  26. data/lib/sunstone/type/mutable.rb +0 -16
  27. data/lib/sunstone/type/string.rb +0 -18
  28. data/lib/sunstone/type/value.rb +0 -97
  29. data/test/sunstone/model/associations_test.rb +0 -55
  30. data/test/sunstone/model/attributes_test.rb +0 -60
  31. data/test/sunstone/model/persistence_test.rb +0 -173
  32. data/test/sunstone/model_test.rb +0 -11
  33. data/test/sunstone/schema_test.rb +0 -25
  34. data/test/sunstone/type/boolean_test.rb +0 -24
  35. data/test/sunstone/type/date_time_test.rb +0 -31
  36. data/test/sunstone/type/decimal_test.rb +0 -27
  37. data/test/sunstone/type/integer_test.rb +0 -29
  38. data/test/sunstone/type/string_test.rb +0 -54
  39. data/test/sunstone/type/value_test.rb +0 -27
@@ -0,0 +1,769 @@
1
+ require 'arel/visitors/visitor'
2
+ class Arel::Visitors::Dot
3
+ def visit_Arel_Nodes_Casted o
4
+ # collector << quoted(o.val, o.attribute).to_s
5
+ visit_String o.val
6
+ end
7
+ end
8
+
9
+ module Arel
10
+ module Visitors
11
+ class Sunstone < Arel::Visitors::Reduce
12
+
13
+ def initialize connection
14
+ @connection = connection
15
+ @schema_cache = connection.schema_cache
16
+
17
+ @nodes = []
18
+ @edges = []
19
+ @node_stack = []
20
+ @edge_stack = []
21
+ @seen = {}
22
+ end
23
+
24
+ def compile node, &block
25
+ accept(node, Arel::Collectors::SQLString.new, &block).value
26
+ end
27
+
28
+ private
29
+
30
+ def visit_Arel_Nodes_SelectStatement o, collector
31
+ collector = o.cores.inject(collector) { |c,x|
32
+ visit_Arel_Nodes_SelectCore(x, c)
33
+ }
34
+
35
+ if !o.orders.empty?
36
+ collector.order = o.orders.map { |x| visit(x, collector) }
37
+ end
38
+
39
+ collector = maybe_visit o.limit, collector
40
+ collector = maybe_visit o.offset, collector
41
+ # collector = maybe_visit o.lock, collector
42
+
43
+ collector
44
+ end
45
+
46
+ def visit_Arel_Nodes_SelectCore o, collector
47
+ collector.request_type = Net::HTTP::Get
48
+
49
+ unless o.projections.empty?
50
+ visit(o.projections.first, collector)
51
+ else
52
+ collector.operation = :select
53
+ end
54
+
55
+ if o.source && !o.source.empty?
56
+ collector.table = o.source.left.name
57
+ end
58
+
59
+ if !o.wheres.empty?
60
+ collector.where = o.wheres.map { |x| visit(x, collector) }.inject([]) { |c, w|
61
+ w.is_a?(Array) ? c += w : c << w
62
+ }
63
+ end
64
+
65
+ collector
66
+ end
67
+
68
+
69
+ #
70
+ # private
71
+ #
72
+ # def visit_Arel_Nodes_DeleteStatement o, collector
73
+ # collector << "DELETE FROM "
74
+ # collector = visit o.relation, collector
75
+ # if o.wheres.any?
76
+ # collector << " WHERE "
77
+ # inject_join o.wheres, collector, AND
78
+ # else
79
+ # collector
80
+ # end
81
+ # end
82
+ #
83
+ # # FIXME: we should probably have a 2-pass visitor for this
84
+ # def build_subselect key, o
85
+ # stmt = Nodes::SelectStatement.new
86
+ # core = stmt.cores.first
87
+ # core.froms = o.relation
88
+ # core.wheres = o.wheres
89
+ # core.projections = [key]
90
+ # stmt.limit = o.limit
91
+ # stmt.orders = o.orders
92
+ # stmt
93
+ # end
94
+ #
95
+ # def visit_Arel_Nodes_UpdateStatement o, collector
96
+ # if o.orders.empty? && o.limit.nil?
97
+ # wheres = o.wheres
98
+ # else
99
+ # wheres = [Nodes::In.new(o.key, [build_subselect(o.key, o)])]
100
+ # end
101
+ #
102
+ # collector << "UPDATE "
103
+ # collector = visit o.relation, collector
104
+ # unless o.values.empty?
105
+ # collector << " SET "
106
+ # collector = inject_join o.values, collector, ", "
107
+ # end
108
+ #
109
+ # unless wheres.empty?
110
+ # collector << " WHERE "
111
+ # collector = inject_join wheres, collector, " AND "
112
+ # end
113
+ #
114
+ # collector
115
+ # end
116
+ #
117
+ # def visit_Arel_Nodes_InsertStatement o, collector
118
+ # collector << "INSERT INTO "
119
+ # collector = visit o.relation, collector
120
+ # if o.columns.any?
121
+ # collector << " (#{o.columns.map { |x|
122
+ # quote_column_name x.name
123
+ # }.join ', '})"
124
+ # end
125
+ #
126
+ # if o.values
127
+ # maybe_visit o.values, collector
128
+ # elsif o.select
129
+ # maybe_visit o.select, collector
130
+ # else
131
+ # collector
132
+ # end
133
+ # end
134
+ #
135
+ # def visit_Arel_Nodes_Exists o, collector
136
+ # collector << "EXISTS ("
137
+ # collector = visit(o.expressions, collector) << ")"
138
+ # if o.alias
139
+ # collector << " AS "
140
+ # visit o.alias, collector
141
+ # else
142
+ # collector
143
+ # end
144
+ # end
145
+ #
146
+ def visit_Arel_Nodes_Casted o, collector
147
+ # collector << quoted(o.val, o.attribute).to_s
148
+ o.val
149
+ end
150
+
151
+ def visit_Arel_Nodes_Quoted o, collector
152
+ o.expr
153
+ end
154
+ #
155
+ # def visit_Arel_Nodes_True o, collector
156
+ # collector << "TRUE"
157
+ # end
158
+ #
159
+ # def visit_Arel_Nodes_False o, collector
160
+ # collector << "FALSE"
161
+ # end
162
+ #
163
+ # def table_exists? name
164
+ # @schema_cache.table_exists? name
165
+ # end
166
+ #
167
+ # def column_for attr
168
+ # return unless attr
169
+ # name = attr.name.to_s
170
+ # table = attr.relation.table_name
171
+ #
172
+ # return nil unless table_exists? table
173
+ #
174
+ # column_cache(table)[name]
175
+ # end
176
+ #
177
+ # def column_cache(table)
178
+ # @schema_cache.columns_hash(table)
179
+ # end
180
+ #
181
+ # def visit_Arel_Nodes_Values o, collector
182
+ # collector << "VALUES ("
183
+ #
184
+ # len = o.expressions.length - 1
185
+ # o.expressions.zip(o.columns).each_with_index { |(value, attr), i|
186
+ # if Nodes::SqlLiteral === value
187
+ # collector = visit value, collector
188
+ # else
189
+ # collector << quote(value, attr && column_for(attr)).to_s
190
+ # end
191
+ # unless i == len
192
+ # collector << ', '
193
+ # end
194
+ # }
195
+ #
196
+ # collector << ")"
197
+ # end
198
+ #
199
+
200
+
201
+ #
202
+ # def visit_Arel_Nodes_Bin o, collector
203
+ # visit o.expr, collector
204
+ # end
205
+ #
206
+ # def visit_Arel_Nodes_Distinct o, collector
207
+ # collector << DISTINCT
208
+ # end
209
+ #
210
+ # def visit_Arel_Nodes_DistinctOn o, collector
211
+ # raise NotImplementedError, 'DISTINCT ON not implemented for this db'
212
+ # end
213
+ #
214
+ # def visit_Arel_Nodes_With o, collector
215
+ # collector << "WITH "
216
+ # inject_join o.children, collector, ', '
217
+ # end
218
+ #
219
+ # def visit_Arel_Nodes_WithRecursive o, collector
220
+ # collector << "WITH RECURSIVE "
221
+ # inject_join o.children, collector, ', '
222
+ # end
223
+ #
224
+ # def visit_Arel_Nodes_Union o, collector
225
+ # collector << "( "
226
+ # infix_value(o, collector, " UNION ") << " )"
227
+ # end
228
+ #
229
+ # def visit_Arel_Nodes_UnionAll o, collector
230
+ # collector << "( "
231
+ # infix_value(o, collector, " UNION ALL ") << " )"
232
+ # end
233
+ #
234
+ # def visit_Arel_Nodes_Intersect o, collector
235
+ # collector << "( "
236
+ # infix_value(o, collector, " INTERSECT ") << " )"
237
+ # end
238
+ #
239
+ # def visit_Arel_Nodes_Except o, collector
240
+ # collector << "( "
241
+ # infix_value(o, collector, " EXCEPT ") << " )"
242
+ # end
243
+ #
244
+ # def visit_Arel_Nodes_NamedWindow o, collector
245
+ # collector << quote_column_name(o.name)
246
+ # collector << " AS "
247
+ # visit_Arel_Nodes_Window o, collector
248
+ # end
249
+ #
250
+ # def visit_Arel_Nodes_Window o, collector
251
+ # collector << "("
252
+ #
253
+ # if o.partitions.any?
254
+ # collector << "PARTITION BY "
255
+ # collector = inject_join o.partitions, collector, ", "
256
+ # end
257
+ #
258
+ # if o.orders.any?
259
+ # collector << ' ' if o.partitions.any?
260
+ # collector << "ORDER BY "
261
+ # collector = inject_join o.orders, collector, ", "
262
+ # end
263
+ #
264
+ # if o.framing
265
+ # collector << ' ' if o.partitions.any? or o.orders.any?
266
+ # collector = visit o.framing, collector
267
+ # end
268
+ #
269
+ # collector << ")"
270
+ # end
271
+ #
272
+ # def visit_Arel_Nodes_Rows o, collector
273
+ # if o.expr
274
+ # collector << "ROWS "
275
+ # visit o.expr, collector
276
+ # else
277
+ # collector << "ROWS"
278
+ # end
279
+ # end
280
+ #
281
+ # def visit_Arel_Nodes_Range o, collector
282
+ # if o.expr
283
+ # collector << "RANGE "
284
+ # visit o.expr, collector
285
+ # else
286
+ # collector << "RANGE"
287
+ # end
288
+ # end
289
+ #
290
+ # def visit_Arel_Nodes_Preceding o, collector
291
+ # collector = if o.expr
292
+ # visit o.expr, collector
293
+ # else
294
+ # collector << "UNBOUNDED"
295
+ # end
296
+ #
297
+ # collector << " PRECEDING"
298
+ # end
299
+ #
300
+ # def visit_Arel_Nodes_Following o, collector
301
+ # collector = if o.expr
302
+ # visit o.expr, collector
303
+ # else
304
+ # collector << "UNBOUNDED"
305
+ # end
306
+ #
307
+ # collector << " FOLLOWING"
308
+ # end
309
+ #
310
+ # def visit_Arel_Nodes_CurrentRow o, collector
311
+ # collector << "CURRENT ROW"
312
+ # end
313
+ #
314
+ # def visit_Arel_Nodes_Over o, collector
315
+ # case o.right
316
+ # when nil
317
+ # visit(o.left, collector) << " OVER ()"
318
+ # when Arel::Nodes::SqlLiteral
319
+ # infix_value o, collector, " OVER "
320
+ # when String, Symbol
321
+ # visit(o.left, collector) << " OVER #{quote_column_name o.right.to_s}"
322
+ # else
323
+ # infix_value o, collector, " OVER "
324
+ # end
325
+ # end
326
+ #
327
+ # def visit_Arel_Nodes_Having o, collector
328
+ # collector << "HAVING "
329
+ # visit o.expr, collector
330
+ # end
331
+ #
332
+ def visit_Arel_Nodes_Offset o, collector
333
+ collector.offset = visit(o.expr, collector)
334
+ collector
335
+ end
336
+
337
+ def visit_Arel_Nodes_Limit o, collector
338
+ collector.limit = visit(o.expr, collector)
339
+ collector
340
+ end
341
+
342
+ # FIXME: this does nothing on most databases, but does on MSSQL
343
+ def visit_Arel_Nodes_Top o, collector
344
+ collector
345
+ end
346
+ #
347
+ # def visit_Arel_Nodes_Lock o, collector
348
+ # visit o.expr, collector
349
+ # end
350
+ #
351
+ def visit_Arel_Nodes_Grouping o, collector
352
+ visit(o.expr, collector)
353
+ end
354
+ #
355
+ # def visit_Arel_SelectManager o, collector
356
+ # collector << "(#{o.to_sql.rstrip})"
357
+ # end
358
+ #
359
+ def visit_Arel_Nodes_Ascending o, collector
360
+ { visit(o.expr, collector) => :asc }
361
+ end
362
+
363
+ def visit_Arel_Nodes_Descending o, collector
364
+ { visit(o.expr, collector) => :desc }
365
+ end
366
+ #
367
+ # def visit_Arel_Nodes_Group o, collector
368
+ # visit o.expr, collector
369
+ # end
370
+ #
371
+ # def visit_Arel_Nodes_NamedFunction o, collector
372
+ # collector << o.name
373
+ # collector << "("
374
+ # collector << "DISTINCT " if o.distinct
375
+ # collector = inject_join(o.expressions, collector, ", ") << ")"
376
+ # if o.alias
377
+ # collector << " AS "
378
+ # visit o.alias, collector
379
+ # else
380
+ # collector
381
+ # end
382
+ # end
383
+ #
384
+ # def visit_Arel_Nodes_Extract o, collector
385
+ # collector << "EXTRACT(#{o.field.to_s.upcase} FROM "
386
+ # collector = visit o.expr, collector
387
+ # collector << ")"
388
+ # if o.alias
389
+ # collector << " AS "
390
+ # visit o.alias, collector
391
+ # else
392
+ # collector
393
+ # end
394
+ # end
395
+ #
396
+ def visit_Arel_Nodes_Count o, collector
397
+ collector.operation = :count
398
+ collector.columns = o.expressions.first
399
+ end
400
+ #
401
+ # def visit_Arel_Nodes_Sum o, collector
402
+ # aggregate "SUM", o, collector
403
+ # end
404
+ #
405
+ def visit_Arel_Nodes_Max o, collector
406
+ collector.operation = :max
407
+ if o.expressions.first.is_a?(Arel::Attributes::Attribute)
408
+ relation = o.expressions.first.relation
409
+ join_name = relation.table_alias || relation.name
410
+ collector.columns = join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"
411
+ else
412
+ collector.columns = o.expressions.first
413
+ end
414
+ end
415
+
416
+ def visit_Arel_Nodes_Min o, collector
417
+ collector.operation = :min
418
+ if o.expressions.first.is_a?(Arel::Attributes::Attribute)
419
+ relation = o.expressions.first.relation
420
+ join_name = relation.table_alias || relation.name
421
+ collector.columns = join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"
422
+ else
423
+ collector.columns = o.expressions.first
424
+ end
425
+ end
426
+
427
+ def visit_Arel_Nodes_Avg o, collector
428
+ # puts o.inspect
429
+ # #<Arel::Nodes::Avg:0x007fd863f55df0 @expressions=["rate_per_sqft_per_year"], @alias="avg_id", @distinct=false>
430
+
431
+ collector.operation = :average
432
+ if o.expressions.first.is_a?(Arel::Attributes::Attribute)
433
+ relation = o.expressions.first.relation
434
+ join_name = relation.table_alias || relation.name
435
+ collector.columns = join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"
436
+ else
437
+ collector.columns = o.expressions.first
438
+ end
439
+ end
440
+ #
441
+ # def visit_Arel_Nodes_TableAlias o, collector
442
+ # collector = visit o.relation, collector
443
+ # collector << " "
444
+ # collector << quote_table_name(o.name)
445
+ # end
446
+ #
447
+ # def visit_Arel_Nodes_Between o, collector
448
+ # collector = visit o.left, collector
449
+ # collector << " BETWEEN "
450
+ # visit o.right, collector
451
+ # end
452
+ #
453
+ # def visit_Arel_Nodes_GreaterThanOrEqual o, collector
454
+ # collector = visit o.left, collector
455
+ # collector << " >= "
456
+ # visit o.right, collector
457
+ # end
458
+ #
459
+ # def visit_Arel_Nodes_GreaterThan o, collector
460
+ # collector = visit o.left, collector
461
+ # collector << " > "
462
+ # visit o.right, collector
463
+ # end
464
+ #
465
+ # def visit_Arel_Nodes_LessThanOrEqual o, collector
466
+ # collector = visit o.left, collector
467
+ # collector << " <= "
468
+ # visit o.right, collector
469
+ # end
470
+ #
471
+ # def visit_Arel_Nodes_LessThan o, collector
472
+ # collector = visit o.left, collector
473
+ # collector << " < "
474
+ # visit o.right, collector
475
+ # end
476
+ #
477
+ # def visit_Arel_Nodes_Matches o, collector
478
+ # collector = visit o.left, collector
479
+ # collector << " LIKE "
480
+ # visit o.right, collector
481
+ # end
482
+ #
483
+ # def visit_Arel_Nodes_DoesNotMatch o, collector
484
+ # collector = visit o.left, collector
485
+ # collector << " NOT LIKE "
486
+ # visit o.right, collector
487
+ # end
488
+ #
489
+ def visit_Arel_Nodes_JoinSource o, collector
490
+ if o.left
491
+ collector = visit o.left, collector
492
+ end
493
+ if o.right.any?
494
+ collector << " " if o.left
495
+ collector = inject_join o.right, collector, ' '
496
+ end
497
+ collector
498
+ end
499
+ #
500
+ # def visit_Arel_Nodes_Regexp o, collector
501
+ # raise NotImplementedError, '~ not implemented for this db'
502
+ # end
503
+ #
504
+ # def visit_Arel_Nodes_NotRegexp o, collector
505
+ # raise NotImplementedError, '!~ not implemented for this db'
506
+ # end
507
+ #
508
+ # def visit_Arel_Nodes_StringJoin o, collector
509
+ # visit o.left, collector
510
+ # end
511
+ #
512
+ # def visit_Arel_Nodes_FullOuterJoin o
513
+ # "FULL OUTER JOIN #{visit o.left} #{visit o.right}"
514
+ # end
515
+ #
516
+ # def visit_Arel_Nodes_OuterJoin o, collector
517
+ # collector << "LEFT OUTER JOIN "
518
+ # collector = visit o.left, collector
519
+ # collector << " "
520
+ # visit o.right, collector
521
+ # end
522
+ #
523
+ # def visit_Arel_Nodes_RightOuterJoin o
524
+ # "RIGHT OUTER JOIN #{visit o.left} #{visit o.right}"
525
+ # end
526
+ #
527
+ # def visit_Arel_Nodes_InnerJoin o, collector
528
+ # collector << "INNER JOIN "
529
+ # collector = visit o.left, collector
530
+ # if o.right
531
+ # collector << SPACE
532
+ # visit(o.right, collector)
533
+ # else
534
+ # collector
535
+ # end
536
+ # end
537
+ #
538
+ # def visit_Arel_Nodes_On o, collector
539
+ # collector << "ON "
540
+ # visit o.expr, collector
541
+ # end
542
+ #
543
+ # def visit_Arel_Nodes_Not o, collector
544
+ # collector << "NOT ("
545
+ # visit(o.expr, collector) << ")"
546
+ # end
547
+ #
548
+ def visit_Arel_Table o, collector
549
+ if o.table_alias
550
+ collector << "#{o.name} #{o.table_alias}"
551
+ else
552
+ collector << o.name
553
+ end
554
+ end
555
+
556
+ # def visit_Arel_Nodes_In o, collector
557
+ # if Array === o.right && o.right.empty?
558
+ # collector << '1=0'
559
+ # else
560
+ # collector = visit o.left, collector
561
+ # collector << " IN ("
562
+ # visit(o.right, collector) << ")"
563
+ # end
564
+ # end
565
+ #
566
+ # def visit_Arel_Nodes_NotIn o, collector
567
+ # if Array === o.right && o.right.empty?
568
+ # collector << '1=1'
569
+ # else
570
+ # collector = visit o.left, collector
571
+ # collector << " NOT IN ("
572
+ # collector = visit o.right, collector
573
+ # collector << ")"
574
+ # end
575
+ # end
576
+ #
577
+ def visit_Arel_Nodes_And o, collector
578
+ ors = []
579
+ ors << o.children.inject({}) do |c, x|
580
+ value = visit(x, collector)
581
+ if value.is_a?(Hash)
582
+ c.deep_merge(value)
583
+ elsif value.is_a?(Array)
584
+ value.size == 1 ? ors << value : ors += value
585
+ end
586
+ end
587
+ ors
588
+ end
589
+
590
+ def visit_Arel_Nodes_Or o, collector
591
+ ors = []
592
+ [o.left, o.right].each do |x|
593
+ value = visit(x, collector)
594
+ value.is_a?(Array) ? ors += value : ors << value
595
+ end
596
+ ors
597
+ end
598
+
599
+ # def visit_Arel_Nodes_Assignment o, collector
600
+ # case o.right
601
+ # when Arel::Nodes::UnqualifiedColumn, Arel::Attributes::Attribute, Arel::Nodes::BindParam
602
+ # collector = visit o.left, collector
603
+ # collector << " = "
604
+ # visit o.right, collector
605
+ # else
606
+ # collector = visit o.left, collector
607
+ # collector << " = "
608
+ # collector << quote(o.right, column_for(o.left)).to_s
609
+ # end
610
+ # end
611
+
612
+ def visit_Arel_Nodes_Equality o, collector
613
+ key = visit(o.left, collector).split('.')
614
+ value = (o.right.nil? ? nil : visit(o.right, collector))
615
+
616
+ hash = {
617
+ key.pop => value
618
+ }
619
+
620
+ while key.size > 0
621
+ hash = { key.pop => hash }
622
+ end
623
+ hash
624
+ end
625
+
626
+ # def visit_Arel_Nodes_NotEqual o, collector
627
+ # right = o.right
628
+ #
629
+ # collector = visit o.left, collector
630
+ #
631
+ # if right.nil?
632
+ # collector << " IS NOT NULL"
633
+ # else
634
+ # collector << " != "
635
+ # visit right, collector
636
+ # end
637
+ # end
638
+ #
639
+ # def visit_Arel_Nodes_As o, collector
640
+ # collector = visit o.left, collector
641
+ # collector << " AS "
642
+ # visit o.right, collector
643
+ # end
644
+ #
645
+ # def visit_Arel_Nodes_UnqualifiedColumn o, collector
646
+ # collector << "#{quote_column_name o.name}"
647
+ # collector
648
+ # end
649
+ #
650
+ def visit_Arel_Attributes_Attribute o, collector
651
+ join_name = o.relation.table_alias || o.relation.name
652
+ # collector <<
653
+ collector.table == join_name ? o.name : "#{join_name}.#{o.name}"
654
+ end
655
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
656
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
657
+ alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
658
+ alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
659
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
660
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
661
+
662
+ def visit_Arel_Nodes_BindParam o, collector
663
+ o
664
+ end
665
+
666
+ def literal(o, collector)
667
+ o.to_s;
668
+ end
669
+ alias :visit_Arel_Nodes_SqlLiteral :literal
670
+ alias :visit_Bignum :literal
671
+ alias :visit_Fixnum :literal
672
+ #
673
+ # def quoted o, a
674
+ # quote(o, column_for(a))
675
+ # end
676
+ #
677
+ # def unsupported o, collector
678
+ # raise "unsupported: #{o.class.name}"
679
+ # end
680
+ #
681
+ # alias :visit_ActiveSupport_Multibyte_Chars :unsupported
682
+ # alias :visit_ActiveSupport_StringInquirer :unsupported
683
+ # alias :visit_BigDecimal :unsupported
684
+ # alias :visit_Class :unsupported
685
+ # alias :visit_Date :unsupported
686
+ # alias :visit_DateTime :unsupported
687
+ # alias :visit_FalseClass :unsupported
688
+ # alias :visit_Float :unsupported
689
+ # alias :visit_Hash :unsupported
690
+ # alias :visit_NilClass :unsupported
691
+ # alias :visit_String :unsupported
692
+ # alias :visit_Symbol :unsupported
693
+ # alias :visit_Time :unsupported
694
+ # alias :visit_TrueClass :unsupported
695
+ #
696
+ # def visit_Arel_Nodes_InfixOperation o, collector
697
+ # collector = visit o.left, collector
698
+ # collector << " #{o.operator} "
699
+ # visit o.right, collector
700
+ # end
701
+ #
702
+ # alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation
703
+ # alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation
704
+ # alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
705
+ # alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
706
+
707
+ def visit_Array o, collector
708
+ o.map { |x| visit(x, collector) }
709
+ end
710
+
711
+ # def quote value, column = nil
712
+ # return value if Arel::Nodes::SqlLiteral === value
713
+ # @connection.quote value, column
714
+ # end
715
+ #
716
+ # def quote_table_name name
717
+ # return name if Arel::Nodes::SqlLiteral === name
718
+ # @quoted_tables[name] ||= @connection.quote_table_name(name)
719
+ # end
720
+ #
721
+ # def quote_column_name name
722
+ # @quoted_columns[name] ||= Arel::Nodes::SqlLiteral === name ? name : @connection.quote_column_name(name)
723
+ # end
724
+ #
725
+ # def maybe_visit thing, collector
726
+ # return collector unless thing
727
+ # collector << " "
728
+ # visit thing, collector
729
+ # end
730
+ #
731
+ def inject_join list, collector, join_str
732
+ len = list.length - 1
733
+ list.each_with_index.inject(collector) { |c, (x,i)|
734
+ if i == len
735
+ visit x, c
736
+ else
737
+ visit(x, c) << join_str
738
+ end
739
+ }
740
+ end
741
+ #
742
+ # def infix_value o, collector, value
743
+ # collector = visit o.left, collector
744
+ # collector << value
745
+ # visit o.right, collector
746
+ # end
747
+ #
748
+ def aggregate name, o, collector
749
+ collector << "#{name}("
750
+ if o.distinct
751
+ collector << "DISTINCT "
752
+ end
753
+ collector = inject_join(o.expressions, collector, ", ") << ")"
754
+ if o.alias
755
+ collector << " AS "
756
+ visit o.alias, collector
757
+ else
758
+ collector
759
+ end
760
+ end
761
+
762
+ def maybe_visit thing, collector
763
+ return collector unless thing
764
+ collector << " "
765
+ visit thing, collector
766
+ end
767
+ end
768
+ end
769
+ end