torque-postgresql 2.4.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +0 -17
  3. data/lib/torque/postgresql/adapter/database_statements.rb +32 -74
  4. data/lib/torque/postgresql/adapter/oid/enum_set.rb +1 -1
  5. data/lib/torque/postgresql/adapter/oid.rb +0 -3
  6. data/lib/torque/postgresql/adapter/quoting.rb +12 -20
  7. data/lib/torque/postgresql/adapter/schema_creation.rb +1 -2
  8. data/lib/torque/postgresql/adapter/schema_definitions.rb +0 -37
  9. data/lib/torque/postgresql/adapter/schema_dumper.rb +2 -60
  10. data/lib/torque/postgresql/adapter/schema_statements.rb +2 -74
  11. data/lib/torque/postgresql/adapter.rb +2 -11
  12. data/lib/torque/postgresql/associations/belongs_to_many_association.rb +5 -4
  13. data/lib/torque/postgresql/associations/{association.rb → foreign_association.rb} +1 -4
  14. data/lib/torque/postgresql/associations/preloader/association.rb +53 -26
  15. data/lib/torque/postgresql/associations/preloader/loader_query.rb +36 -0
  16. data/lib/torque/postgresql/associations/preloader.rb +1 -0
  17. data/lib/torque/postgresql/associations.rb +6 -1
  18. data/lib/torque/postgresql/attributes/builder/period.rb +6 -2
  19. data/lib/torque/postgresql/auxiliary_statement/settings.rb +22 -75
  20. data/lib/torque/postgresql/auxiliary_statement.rb +40 -39
  21. data/lib/torque/postgresql/base.rb +13 -33
  22. data/lib/torque/postgresql/config.rb +3 -30
  23. data/lib/torque/postgresql/inheritance.rb +1 -3
  24. data/lib/torque/postgresql/migration/command_recorder.rb +2 -12
  25. data/lib/torque/postgresql/railtie.rb +1 -5
  26. data/lib/torque/postgresql/reflection/abstract_reflection.rb +44 -20
  27. data/lib/torque/postgresql/relation/auxiliary_statement.rb +15 -28
  28. data/lib/torque/postgresql/relation.rb +10 -12
  29. data/lib/torque/postgresql/schema_cache.rb +2 -7
  30. data/lib/torque/postgresql/version.rb +1 -1
  31. data/lib/torque/postgresql.rb +1 -2
  32. data/lib/torque-postgresql.rb +0 -1
  33. data/spec/schema.rb +5 -21
  34. data/spec/spec_helper.rb +1 -2
  35. data/spec/tests/arel_spec.rb +2 -4
  36. data/spec/tests/auxiliary_statement_spec.rb +35 -374
  37. data/spec/tests/belongs_to_many_spec.rb +2 -50
  38. data/spec/tests/enum_set_spec.rb +10 -10
  39. data/spec/tests/enum_spec.rb +0 -90
  40. data/spec/tests/has_many_spec.rb +0 -46
  41. data/spec/tests/table_inheritance_spec.rb +15 -11
  42. metadata +8 -28
  43. data/lib/torque/postgresql/auxiliary_statement/recursive.rb +0 -149
  44. data/lib/torque/postgresql/table_name.rb +0 -41
  45. data/lib/torque/range.rb +0 -22
  46. data/spec/models/category.rb +0 -2
  47. data/spec/models/internal/user.rb +0 -5
  48. data/spec/tests/range_spec.rb +0 -36
  49. data/spec/tests/schema_spec.rb +0 -134
@@ -21,7 +21,7 @@ RSpec.describe 'AuxiliaryStatement' do
21
21
  end
22
22
 
23
23
  result = 'WITH "comments" AS'
24
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
24
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments")'
25
25
  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
26
26
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
27
27
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -34,7 +34,7 @@ RSpec.describe 'AuxiliaryStatement' do
34
34
  end
35
35
 
36
36
  result = 'WITH "comments" AS (SELECT DISTINCT ON ( "comments"."user_id" )'
37
- result << ' "comments"."content" AS last_comment, "comments"."user_id"'
37
+ result << ' "comments"."user_id", "comments"."content" AS last_comment'
38
38
  result << ' FROM "comments" ORDER BY "comments"."user_id" ASC,'
39
39
  result << ' "comments"."id" DESC) SELECT "users".*,'
40
40
  result << ' "comments"."last_comment" FROM "users" INNER JOIN "comments"'
@@ -49,7 +49,7 @@ RSpec.describe 'AuxiliaryStatement' do
49
49
  end
50
50
 
51
51
  result = 'WITH "comments" AS'
52
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."slug" AS comment_slug, "comments"."user_id" FROM "comments")'
52
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content, "comments"."slug" AS comment_slug FROM "comments")'
53
53
  result << ' SELECT "users".*, "comments"."comment_content", "comments"."comment_slug" FROM "users"'
54
54
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
55
55
  expect(subject.with(:comments, select: {slug: :comment_slug}).arel.to_sql).to eql(result)
@@ -62,7 +62,7 @@ RSpec.describe 'AuxiliaryStatement' do
62
62
  end
63
63
 
64
64
  result = 'WITH "comments" AS'
65
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id", "comments"."active" FROM "comments")'
65
+ result << ' (SELECT "comments"."user_id", "comments"."active", "comments"."content" AS comment_content FROM "comments")'
66
66
  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
67
67
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id" AND "comments"."active" = "users"."active"'
68
68
  expect(subject.with(:comments, join: {active: :active}).arel.to_sql).to eql(result)
@@ -75,7 +75,7 @@ RSpec.describe 'AuxiliaryStatement' do
75
75
  end
76
76
 
77
77
  result = 'WITH "comments" AS'
78
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id"'
78
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content'
79
79
  result << ' FROM "comments" WHERE "comments"."active" = $1)'
80
80
  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
81
81
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
@@ -91,7 +91,7 @@ RSpec.describe 'AuxiliaryStatement' do
91
91
  query = subject.where(id: 2).with(:comments)
92
92
 
93
93
  result = 'WITH "comments" AS'
94
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments"'
94
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments"'
95
95
  result << ' WHERE "comments"."id" = $1)'
96
96
  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
97
97
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
@@ -108,7 +108,7 @@ RSpec.describe 'AuxiliaryStatement' do
108
108
  end
109
109
 
110
110
  result = 'WITH "comments" AS'
111
- result << ' (SELECT MAX(id) AS comment_id, "comments"."user_id" FROM "comments")'
111
+ result << ' (SELECT "comments"."user_id", MAX(id) AS comment_id FROM "comments")'
112
112
  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
113
113
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
114
114
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -121,7 +121,7 @@ RSpec.describe 'AuxiliaryStatement' do
121
121
  end
122
122
 
123
123
  result = 'WITH "comments" AS'
124
- result << ' (SELECT ROW_NUMBER() OVER (PARTITION BY ORDER BY "comments"."id") AS comment_id, "comments"."user_id" FROM "comments")'
124
+ result << ' (SELECT "comments"."user_id", ROW_NUMBER() OVER (PARTITION BY ORDER BY "comments"."id") AS comment_id FROM "comments")'
125
125
  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
126
126
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
127
127
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -134,7 +134,7 @@ RSpec.describe 'AuxiliaryStatement' do
134
134
  end
135
135
 
136
136
  result = 'WITH "comments" AS'
137
- result << ' (SELECT MIN("comments"."id") AS comment_id, "comments"."user_id" FROM "comments")'
137
+ result << ' (SELECT "comments"."user_id", MIN("comments"."id") AS comment_id FROM "comments")'
138
138
  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
139
139
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
140
140
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -147,8 +147,8 @@ RSpec.describe 'AuxiliaryStatement' do
147
147
  cte.join name: :id, 'a.col' => :col
148
148
  end
149
149
 
150
- result = 'WITH "comments" AS (SELECT "comments"."content" AS comment_content,'
151
- result << ' "comments"."id", "comments"."col" FROM "comments") SELECT "users".*,'
150
+ result = 'WITH "comments" AS (SELECT "comments"."id", "comments"."col",'
151
+ result << ' "comments"."content" AS comment_content FROM "comments") SELECT "users".*,'
152
152
  result << ' "comments"."comment_content" FROM "users" INNER JOIN "comments"'
153
153
  result << ' ON "comments"."id" = "users"."name" AND "comments"."col" = "a"."col"'
154
154
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -161,8 +161,8 @@ RSpec.describe 'AuxiliaryStatement' do
161
161
  cte.join_type :left
162
162
  end
163
163
 
164
- result = 'WITH "comments" AS (SELECT "comments"."content" AS comment_content,'
165
- result << ' "comments"."user_id" FROM "comments") SELECT "users".*,'
164
+ result = 'WITH "comments" AS (SELECT "comments"."user_id",'
165
+ result << ' "comments"."content" AS comment_content FROM "comments") SELECT "users".*,'
166
166
  result << ' "comments"."comment_content" FROM "users" LEFT OUTER JOIN "comments"'
167
167
  result << ' ON "comments"."user_id" = "users"."id"'
168
168
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -177,7 +177,7 @@ RSpec.describe 'AuxiliaryStatement' do
177
177
  end
178
178
 
179
179
  result = 'WITH "comments" AS'
180
- result << ' (SELECT "comments"."content" AS sample_content, "comments"."a_user_id" FROM "comments")'
180
+ result << ' (SELECT "comments"."a_user_id", "comments"."content" AS sample_content FROM "comments")'
181
181
  result << ' SELECT "users".*, "comments"."sample_content" FROM "users"'
182
182
  result << ' INNER JOIN "comments" ON "comments"."a_user_id" = "users"."id"'
183
183
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -198,8 +198,8 @@ RSpec.describe 'AuxiliaryStatement' do
198
198
  query = subject.where(id: 3).with(:comments2)
199
199
 
200
200
  result = 'WITH '
201
- result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments" WHERE "comments"."id" = $1), '
202
- result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments" WHERE "comments"."id" = $2)'
201
+ result << '"comments1" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content1 FROM "comments" WHERE "comments"."id" = $1), '
202
+ result << '"comments2" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content2 FROM "comments" WHERE "comments"."id" = $2)'
203
203
  result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
204
204
  result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
205
205
  result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
@@ -225,8 +225,8 @@ RSpec.describe 'AuxiliaryStatement' do
225
225
 
226
226
  it 'can requires another statement as dependency' do
227
227
  result = 'WITH '
228
- result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments"), '
229
- result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments")'
228
+ result << '"comments1" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content1 FROM "comments"), '
229
+ result << '"comments2" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content2 FROM "comments")'
230
230
  result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
231
231
  result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
232
232
  result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
@@ -235,8 +235,8 @@ RSpec.describe 'AuxiliaryStatement' do
235
235
 
236
236
  it 'can uses already already set dependent' do
237
237
  result = 'WITH '
238
- result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments"), '
239
- result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments")'
238
+ result << '"comments1" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content1 FROM "comments"), '
239
+ result << '"comments2" AS (SELECT "comments"."user_id", "comments"."content" AS comment_content2 FROM "comments")'
240
240
  result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
241
241
  result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
242
242
  result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
@@ -289,14 +289,14 @@ RSpec.describe 'AuxiliaryStatement' do
289
289
  expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /join columns/)
290
290
  end
291
291
 
292
- it 'not raises an error when not given the table name as first argument' do
292
+ it 'raises an error when not given the table name as first argument' do
293
293
  klass.send(:auxiliary_statement, :comments) do |cte|
294
294
  cte.query 'SELECT * FROM comments'
295
295
  cte.attributes content: :comment
296
296
  cte.join id: :user_id
297
297
  end
298
298
 
299
- expect{ subject.with(:comments).arel.to_sql }.not_to raise_error
299
+ expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /table name/)
300
300
  end
301
301
  end
302
302
 
@@ -309,7 +309,7 @@ RSpec.describe 'AuxiliaryStatement' do
309
309
  end
310
310
 
311
311
  result = 'WITH "comments" AS'
312
- result << ' (SELECT "comments"."content" AS comment, "comments"."user_id" FROM "comments")'
312
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment FROM "comments")'
313
313
  result << ' SELECT "users".*, "comments"."comment" FROM "users"'
314
314
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
315
315
  expect(subject.with(:comments).arel.to_sql).to eql(result)
@@ -352,7 +352,7 @@ RSpec.describe 'AuxiliaryStatement' do
352
352
  query = subject.with(:comments, args: {id: 1})
353
353
 
354
354
  result = 'WITH "comments" AS'
355
- result << ' (SELECT "comments"."content" AS comment, "comments"."user_id"'
355
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment'
356
356
  result << ' FROM "comments" WHERE "comments"."id" = $1)'
357
357
  result << ' SELECT "users".*, "comments"."comment" FROM "users"'
358
358
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
@@ -370,14 +370,14 @@ RSpec.describe 'AuxiliaryStatement' do
370
370
  expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /join columns/)
371
371
  end
372
372
 
373
- it 'not raises an error when not given the table name as first argument' do
373
+ it 'raises an error when not given the table name as first argument' do
374
374
  klass.send(:auxiliary_statement, :comments) do |cte|
375
375
  cte.query -> { Comment.all }
376
376
  cte.attributes content: :comment
377
377
  cte.join id: :user_id
378
378
  end
379
379
 
380
- expect{ subject.with(:comments).arel.to_sql }.not_to raise_error
380
+ expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /table name/)
381
381
  end
382
382
 
383
383
  it 'raises an error when the result of the proc is an invalid type' do
@@ -403,7 +403,7 @@ RSpec.describe 'AuxiliaryStatement' do
403
403
  end
404
404
 
405
405
  result = 'WITH "authors" AS'
406
- result << ' (SELECT "authors"."name" AS author_name, "authors"."id" FROM "authors")'
406
+ result << ' (SELECT "authors"."id", "authors"."name" AS author_name FROM "authors")'
407
407
  result << ' SELECT "activity_books".*, "authors"."author_name" FROM "activity_books"'
408
408
  result << ' INNER JOIN "authors" ON "authors"."id" = "activity_books"."author_id"'
409
409
  expect(subject.with(:authors).arel.to_sql).to eql(result)
@@ -423,7 +423,7 @@ RSpec.describe 'AuxiliaryStatement' do
423
423
  end
424
424
 
425
425
  result = 'WITH "authors" AS'
426
- result << ' (SELECT "authors"."type" AS author_type, "authors"."id" FROM "authors")'
426
+ result << ' (SELECT "authors"."id", "authors"."type" AS author_type FROM "authors")'
427
427
  result << ' SELECT "activity_books".*, "authors"."author_type" FROM "activity_books"'
428
428
  result << ' INNER JOIN "authors" ON "authors"."id" = "activity_books"."author_id"'
429
429
  expect(subject.with(:authors).arel.to_sql).to eql(result)
@@ -434,233 +434,6 @@ RSpec.describe 'AuxiliaryStatement' do
434
434
  end
435
435
  end
436
436
 
437
- context 'recursive' do
438
- let(:klass) { Course }
439
-
440
- it 'correctly build a recursive cte' do
441
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
442
- cte.query Category.all
443
- cte.join id: :parent_id
444
- end
445
-
446
- result = 'WITH RECURSIVE "all_categories" AS ('
447
- result << ' SELECT "categories"."id", "categories"."parent_id"'
448
- result << ' FROM "categories"'
449
- result << ' WHERE "categories"."parent_id" IS NULL'
450
- result << ' UNION'
451
- result << ' SELECT "categories"."id", "categories"."parent_id"'
452
- result << ' FROM "categories", "all_categories"'
453
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
454
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
455
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
456
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
457
- end
458
-
459
- it 'allows connect to be set to something different using a single value' do
460
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
461
- cte.query Category.all
462
- cte.join id: :parent_id
463
- cte.connect :name
464
- end
465
-
466
- result = 'WITH RECURSIVE "all_categories" AS ('
467
- result << ' SELECT "categories"."name", "categories"."parent_id"'
468
- result << ' FROM "categories"'
469
- result << ' WHERE "categories"."parent_name" IS NULL'
470
- result << ' UNION'
471
- result << ' SELECT "categories"."name", "categories"."parent_id"'
472
- result << ' FROM "categories", "all_categories"'
473
- result << ' WHERE "categories"."parent_name" = "all_categories"."name"'
474
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
475
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
476
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
477
- end
478
-
479
- it 'allows a complete different set of connect' do
480
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
481
- cte.query Category.all
482
- cte.join id: :parent_id
483
- cte.connect left: :right
484
- end
485
-
486
- result = 'WITH RECURSIVE "all_categories" AS ('
487
- result << ' SELECT "categories"."left", "categories"."parent_id"'
488
- result << ' FROM "categories"'
489
- result << ' WHERE "categories"."right" IS NULL'
490
- result << ' UNION'
491
- result << ' SELECT "categories"."left", "categories"."parent_id"'
492
- result << ' FROM "categories", "all_categories"'
493
- result << ' WHERE "categories"."right" = "all_categories"."left"'
494
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
495
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
496
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
497
- end
498
-
499
- it 'allows using an union all' do
500
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
501
- cte.query Category.all
502
- cte.join id: :parent_id
503
- cte.union_all!
504
- end
505
-
506
- result = 'WITH RECURSIVE "all_categories" AS ('
507
- result << ' SELECT "categories"."id", "categories"."parent_id"'
508
- result << ' FROM "categories"'
509
- result << ' WHERE "categories"."parent_id" IS NULL'
510
- result << ' UNION ALL'
511
- result << ' SELECT "categories"."id", "categories"."parent_id"'
512
- result << ' FROM "categories", "all_categories"'
513
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
514
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
515
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
516
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
517
- end
518
-
519
- it 'allows having a complete different initiator' do
520
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
521
- cte.query Category.where(parent_id: 5)
522
- cte.join id: :parent_id
523
- end
524
-
525
- result = 'WITH RECURSIVE "all_categories" AS ('
526
- result << ' SELECT "categories"."id", "categories"."parent_id"'
527
- result << ' FROM "categories"'
528
- result << ' WHERE "categories"."parent_id" = $1'
529
- result << ' UNION'
530
- result << ' SELECT "categories"."id", "categories"."parent_id"'
531
- result << ' FROM "categories", "all_categories"'
532
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
533
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
534
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
535
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
536
- end
537
-
538
- it 'can process the depth of the query' do
539
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
540
- cte.query Category.all
541
- cte.join id: :parent_id
542
- cte.with_depth
543
- end
544
-
545
- result = 'WITH RECURSIVE "all_categories" AS ('
546
- result << ' SELECT "categories"."id", "categories"."parent_id", 0 AS depth'
547
- result << ' FROM "categories"'
548
- result << ' WHERE "categories"."parent_id" IS NULL'
549
- result << ' UNION'
550
- result << ' SELECT "categories"."id", "categories"."parent_id", ("all_categories"."depth" + 1) AS depth'
551
- result << ' FROM "categories", "all_categories"'
552
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
553
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
554
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
555
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
556
- end
557
-
558
- it 'can process and expose the depth of the query' do
559
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
560
- cte.query Category.all
561
- cte.join id: :parent_id
562
- cte.with_depth 'd', start: 10, as: :category_depth
563
- end
564
-
565
- result = 'WITH RECURSIVE "all_categories" AS ('
566
- result << ' SELECT "categories"."id", "categories"."parent_id", 10 AS d'
567
- result << ' FROM "categories"'
568
- result << ' WHERE "categories"."parent_id" IS NULL'
569
- result << ' UNION'
570
- result << ' SELECT "categories"."id", "categories"."parent_id", ("all_categories"."d" + 1) AS d'
571
- result << ' FROM "categories", "all_categories"'
572
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
573
- result << ' ) SELECT "courses".*, "all_categories"."d" AS category_depth FROM "courses" INNER JOIN "all_categories"'
574
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
575
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
576
- end
577
-
578
- it 'can process the path of the query' do
579
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
580
- cte.query Category.all
581
- cte.join id: :parent_id
582
- cte.with_path
583
- end
584
-
585
- result = 'WITH RECURSIVE "all_categories" AS ('
586
- result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."id"]::varchar[] AS path'
587
- result << ' FROM "categories"'
588
- result << ' WHERE "categories"."parent_id" IS NULL'
589
- result << ' UNION'
590
- result << ' SELECT "categories"."id", "categories"."parent_id", array_append("all_categories"."path", "categories"."id"::varchar) AS path'
591
- result << ' FROM "categories", "all_categories"'
592
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
593
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
594
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
595
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
596
- end
597
-
598
- it 'can process and expose the path of the query' do
599
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
600
- cte.query Category.all
601
- cte.join id: :parent_id
602
- cte.with_path 'p', source: :name, as: :category_path
603
- end
604
-
605
- result = 'WITH RECURSIVE "all_categories" AS ('
606
- result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."name"]::varchar[] AS p'
607
- result << ' FROM "categories"'
608
- result << ' WHERE "categories"."parent_id" IS NULL'
609
- result << ' UNION'
610
- result << ' SELECT "categories"."id", "categories"."parent_id", array_append("all_categories"."p", "categories"."name"::varchar) AS p'
611
- result << ' FROM "categories", "all_categories"'
612
- result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
613
- result << ' ) SELECT "courses".*, "all_categories"."p" AS category_path FROM "courses" INNER JOIN "all_categories"'
614
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
615
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
616
- end
617
-
618
- it 'works with string queries' do
619
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
620
- cte.query 'SELECT * FROM categories WHERE a IS NULL'
621
- cte.sub_query 'SELECT * FROM categories, all_categories WHERE all_categories.a = b'
622
- cte.join id: :parent_id
623
- end
624
-
625
- result = 'WITH RECURSIVE "all_categories" AS ('
626
- result << 'SELECT * FROM categories WHERE a IS NULL'
627
- result << ' UNION '
628
- result << ' SELECT * FROM categories, all_categories WHERE all_categories.a = b'
629
- result << ') SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
630
- result << ' ON "all_categories"."parent_id" = "courses"."id"'
631
- expect(subject.with(:all_categories).arel.to_sql).to eql(result)
632
- end
633
-
634
- it 'raises an error when query is a string and there is no sub query' do
635
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
636
- cte.query 'SELECT * FROM categories WHERE a IS NULL'
637
- cte.join id: :parent_id
638
- end
639
-
640
- expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /generate sub query/)
641
- end
642
-
643
- it 'raises an error when sub query has an invalid type' do
644
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
645
- cte.query 'SELECT * FROM categories WHERE a IS NULL'
646
- cte.sub_query -> { 1 }
647
- cte.join id: :parent_id
648
- end
649
-
650
- expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /query and sub query objects/)
651
- end
652
-
653
- it 'raises an error when connect can be resolved automatically' do
654
- allow(klass).to receive(:primary_key).and_return(nil)
655
- klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
656
- cte.query Category.all
657
- cte.join id: :parent_id
658
- end
659
-
660
- expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /setting up a proper way to connect/)
661
- end
662
- end
663
-
664
437
  it 'works with count and does not add extra columns' do
665
438
  klass.send(:auxiliary_statement, :comments) do |cte|
666
439
  cte.query Comment.all
@@ -668,7 +441,7 @@ RSpec.describe 'AuxiliaryStatement' do
668
441
  end
669
442
 
670
443
  result = 'WITH "comments" AS'
671
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
444
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments")'
672
445
  result << ' SELECT COUNT(*) FROM "users"'
673
446
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
674
447
 
@@ -683,7 +456,7 @@ RSpec.describe 'AuxiliaryStatement' do
683
456
  end
684
457
 
685
458
  result = 'WITH "comments" AS'
686
- result << ' (SELECT "comments"."id" AS value, "comments"."user_id" FROM "comments")'
459
+ result << ' (SELECT "comments"."user_id", "comments"."id" AS value FROM "comments")'
687
460
  result << ' SELECT SUM("comments"."value") FROM "users"'
688
461
  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
689
462
 
@@ -699,7 +472,7 @@ RSpec.describe 'AuxiliaryStatement' do
699
472
  expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /object types/)
700
473
  end
701
474
 
702
- it 'raises an error when trying to use a statement that is not defined' do
475
+ it 'raises an error when traying to use a statement that is not defined' do
703
476
  expect{ subject.with(:does_not_exist).arel.to_sql }.to raise_error(ArgumentError)
704
477
  end
705
478
 
@@ -722,12 +495,7 @@ RSpec.describe 'AuxiliaryStatement' do
722
495
  expect(subject.protected_methods).to include(:auxiliary_statement)
723
496
  end
724
497
 
725
- it 'has the recursive configuration' do
726
- expect(subject.protected_methods).to include(:recursive_cte)
727
- expect(subject.protected_methods).to include(:recursive_auxiliary_statement)
728
- end
729
-
730
- it 'allows configure new auxiliary statements' do
498
+ it 'allows configurate new auxiliary statements' do
731
499
  subject.send(:auxiliary_statement, :cte1)
732
500
  expect(subject.auxiliary_statements_list).to include(:cte1)
733
501
  expect(subject.const_defined?('Cte1_AuxiliaryStatement')).to be_truthy
@@ -759,7 +527,7 @@ RSpec.describe 'AuxiliaryStatement' do
759
527
  query = subject.with(sample, select: {content: :comment_content}).arel.to_sql
760
528
 
761
529
  result = 'WITH "comment" AS'
762
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
530
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments")'
763
531
  result << ' SELECT "users".*, "comment"."comment_content" FROM "users"'
764
532
  result << ' INNER JOIN "comment" ON "comment"."user_id" = "users"."id"'
765
533
  expect(query).to eql(result)
@@ -770,7 +538,7 @@ RSpec.describe 'AuxiliaryStatement' do
770
538
  query = subject.with(sample).arel.to_sql
771
539
 
772
540
  result = 'WITH "comment" AS'
773
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
541
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments")'
774
542
  result << ' SELECT "users".*, "comment"."comment_content" FROM "users"'
775
543
  result << ' INNER JOIN "comment" ON "comment"."user_id" = "users"."id"'
776
544
  expect(query).to eql(result)
@@ -783,120 +551,13 @@ RSpec.describe 'AuxiliaryStatement' do
783
551
  end
784
552
 
785
553
  result = 'WITH "all_comments" AS'
786
- result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
554
+ result << ' (SELECT "comments"."user_id", "comments"."content" AS comment_content FROM "comments")'
787
555
  result << ' SELECT "users".*, "all_comments"."comment_content" FROM "users"'
788
556
  result << ' INNER JOIN "all_comments" ON "all_comments"."user_id" = "users"."id"'
789
557
 
790
558
  query = subject.with(sample).arel.to_sql
791
559
  expect(query).to eql(result)
792
560
  end
793
-
794
- context 'recursive' do
795
- let(:klass) { Torque::PostgreSQL::AuxiliaryStatement::Recursive }
796
- subject { Course }
797
-
798
- it 'has the external method available' do
799
- expect(klass).to respond_to(:create)
800
- end
801
-
802
- it 'accepts simple recursive auxiliary statement definition' do
803
- settings = { join: { id: :parent_id } }
804
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
805
-
806
- result = 'WITH RECURSIVE "category" AS ('
807
- result << ' SELECT "categories"."id", "categories"."parent_id"'
808
- result << ' FROM "categories"'
809
- result << ' WHERE "categories"."parent_id" IS NULL'
810
- result << ' UNION'
811
- result << ' SELECT "categories"."id", "categories"."parent_id"'
812
- result << ' FROM "categories", "category"'
813
- result << ' WHERE "categories"."parent_id" = "category"."id"'
814
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
815
- result << ' ON "category"."parent_id" = "courses"."id"'
816
- expect(query).to eql(result)
817
- end
818
-
819
- it 'accepts a connect option' do
820
- settings = { join: { id: :parent_id }, connect: { a: :b } }
821
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
822
-
823
- result = 'WITH RECURSIVE "category" AS ('
824
- result << ' SELECT "categories"."a", "categories"."parent_id"'
825
- result << ' FROM "categories"'
826
- result << ' WHERE "categories"."b" IS NULL'
827
- result << ' UNION'
828
- result << ' SELECT "categories"."a", "categories"."parent_id"'
829
- result << ' FROM "categories", "category"'
830
- result << ' WHERE "categories"."b" = "category"."a"'
831
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
832
- result << ' ON "category"."parent_id" = "courses"."id"'
833
- expect(query).to eql(result)
834
- end
835
-
836
- it 'accepts an union all option' do
837
- settings = { join: { id: :parent_id }, union_all: true }
838
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
839
-
840
- result = 'WITH RECURSIVE "category" AS ('
841
- result << ' SELECT "categories"."id", "categories"."parent_id"'
842
- result << ' FROM "categories"'
843
- result << ' WHERE "categories"."parent_id" IS NULL'
844
- result << ' UNION ALL'
845
- result << ' SELECT "categories"."id", "categories"."parent_id"'
846
- result << ' FROM "categories", "category"'
847
- result << ' WHERE "categories"."parent_id" = "category"."id"'
848
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
849
- result << ' ON "category"."parent_id" = "courses"."id"'
850
- expect(query).to eql(result)
851
- end
852
-
853
- it 'accepts a sub query option' do
854
- settings = { join: { id: :parent_id }, sub_query: Category.where(active: true) }
855
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
856
-
857
- result = 'WITH RECURSIVE "category" AS ('
858
- result << ' SELECT "categories"."id", "categories"."parent_id" FROM "categories"'
859
- result << ' UNION'
860
- result << ' SELECT "categories"."id", "categories"."parent_id" FROM "categories", "category" WHERE "categories"."active" = $1'
861
- result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
862
- result << ' ON "category"."parent_id" = "courses"."id"'
863
- expect(query).to eql(result)
864
- end
865
-
866
- it 'accepts a depth option' do
867
- settings = { join: { id: :parent_id }, with_depth: { name: 'a', start: 5, as: 'b' } }
868
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
869
-
870
- result = 'WITH RECURSIVE "category" AS ('
871
- result << ' SELECT "categories"."id", "categories"."parent_id", 5 AS a'
872
- result << ' FROM "categories"'
873
- result << ' WHERE "categories"."parent_id" IS NULL'
874
- result << ' UNION'
875
- result << ' SELECT "categories"."id", "categories"."parent_id", ("category"."a" + 1) AS a'
876
- result << ' FROM "categories", "category"'
877
- result << ' WHERE "categories"."parent_id" = "category"."id"'
878
- result << ' ) SELECT "courses".*, "category"."a" AS b FROM "courses" INNER JOIN "category"'
879
- result << ' ON "category"."parent_id" = "courses"."id"'
880
- expect(query).to eql(result)
881
- end
882
-
883
- it 'accepts a path option' do
884
- settings = { join: { id: :parent_id }, with_path: { name: 'a', source: 'b', as: 'c' } }
885
- query = subject.with(klass.create(Category.all), **settings).arel.to_sql
886
-
887
- result = 'WITH RECURSIVE "category" AS ('
888
- result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."b"]::varchar[] AS a'
889
- result << ' FROM "categories"'
890
- result << ' WHERE "categories"."parent_id" IS NULL'
891
- result << ' UNION'
892
- result << ' SELECT "categories"."id", "categories"."parent_id", array_append("category"."a", "categories"."b"::varchar) AS a'
893
- result << ' FROM "categories", "category"'
894
- result << ' WHERE "categories"."parent_id" = "category"."id"'
895
- result << ' ) SELECT "courses".*, "category"."a" AS c FROM "courses" INNER JOIN "category"'
896
- result << ' ON "category"."parent_id" = "courses"."id"'
897
- expect(query).to eql(result)
898
- end
899
- end
900
561
  end
901
562
 
902
563
  context 'on settings' do