sunstone 0.1.0 → 1.0.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. 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