torque-postgresql 2.4.4 → 3.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 (52) 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 +7 -6
  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/reflection/belongs_to_many_reflection.rb +2 -2
  28. data/lib/torque/postgresql/relation/auxiliary_statement.rb +15 -28
  29. data/lib/torque/postgresql/relation.rb +10 -12
  30. data/lib/torque/postgresql/schema_cache.rb +2 -7
  31. data/lib/torque/postgresql/version.rb +1 -1
  32. data/lib/torque/postgresql.rb +1 -2
  33. data/lib/torque-postgresql.rb +0 -1
  34. data/spec/schema.rb +14 -30
  35. data/spec/spec_helper.rb +1 -2
  36. data/spec/tests/arel_spec.rb +2 -4
  37. data/spec/tests/auxiliary_statement_spec.rb +35 -374
  38. data/spec/tests/belongs_to_many_spec.rb +2 -99
  39. data/spec/tests/distinct_on_spec.rb +1 -1
  40. data/spec/tests/enum_set_spec.rb +10 -10
  41. data/spec/tests/enum_spec.rb +0 -90
  42. data/spec/tests/has_many_spec.rb +0 -46
  43. data/spec/tests/relation_spec.rb +1 -1
  44. data/spec/tests/table_inheritance_spec.rb +15 -11
  45. metadata +11 -37
  46. data/lib/torque/postgresql/auxiliary_statement/recursive.rb +0 -149
  47. data/lib/torque/postgresql/table_name.rb +0 -41
  48. data/lib/torque/range.rb +0 -22
  49. data/spec/models/category.rb +0 -2
  50. data/spec/models/internal/user.rb +0 -5
  51. data/spec/tests/range_spec.rb +0 -36
  52. 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