veritas-sql-generator 0.0.3

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 (103) hide show
  1. data/Gemfile +33 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +27 -0
  4. data/Rakefile +25 -0
  5. data/TODO +17 -0
  6. data/config/flay.yml +3 -0
  7. data/config/flog.yml +2 -0
  8. data/config/roodi.yml +16 -0
  9. data/config/site.reek +124 -0
  10. data/config/yardstick.yml +2 -0
  11. data/lib/veritas-sql-generator.rb +3 -0
  12. data/lib/veritas/base_relation.rb +36 -0
  13. data/lib/veritas/sql/generator.rb +35 -0
  14. data/lib/veritas/sql/generator/attribute.rb +25 -0
  15. data/lib/veritas/sql/generator/direction.rb +36 -0
  16. data/lib/veritas/sql/generator/identifier.rb +27 -0
  17. data/lib/veritas/sql/generator/literal.rb +160 -0
  18. data/lib/veritas/sql/generator/logic.rb +349 -0
  19. data/lib/veritas/sql/generator/relation.rb +111 -0
  20. data/lib/veritas/sql/generator/relation/base.rb +14 -0
  21. data/lib/veritas/sql/generator/relation/binary.rb +184 -0
  22. data/lib/veritas/sql/generator/relation/set.rb +99 -0
  23. data/lib/veritas/sql/generator/relation/unary.rb +326 -0
  24. data/lib/veritas/sql/generator/version.rb +9 -0
  25. data/lib/veritas/sql/generator/visitor.rb +121 -0
  26. data/spec/rcov.opts +6 -0
  27. data/spec/shared/command_method_behavior.rb +7 -0
  28. data/spec/shared/generated_sql_behavior.rb +15 -0
  29. data/spec/shared/idempotent_method_behavior.rb +7 -0
  30. data/spec/spec.opts +3 -0
  31. data/spec/spec_helper.rb +15 -0
  32. data/spec/unit/veritas/base_relation/name_spec.rb +45 -0
  33. data/spec/unit/veritas/sql/generator/attribute/visit_veritas_attribute_spec.rb +15 -0
  34. data/spec/unit/veritas/sql/generator/direction/visit_veritas_relation_operation_order_ascending_spec.rb +15 -0
  35. data/spec/unit/veritas/sql/generator/direction/visit_veritas_relation_operation_order_descending_spec.rb +15 -0
  36. data/spec/unit/veritas/sql/generator/identifier/visit_identifier_spec.rb +26 -0
  37. data/spec/unit/veritas/sql/generator/literal/class_methods/dup_frozen_spec.rb +23 -0
  38. data/spec/unit/veritas/sql/generator/literal/visit_class_spec.rb +31 -0
  39. data/spec/unit/veritas/sql/generator/literal/visit_date_spec.rb +15 -0
  40. data/spec/unit/veritas/sql/generator/literal/visit_date_time_spec.rb +61 -0
  41. data/spec/unit/veritas/sql/generator/literal/visit_enumerable_spec.rb +15 -0
  42. data/spec/unit/veritas/sql/generator/literal/visit_false_class_spec.rb +14 -0
  43. data/spec/unit/veritas/sql/generator/literal/visit_nil_class_spec.rb +14 -0
  44. data/spec/unit/veritas/sql/generator/literal/visit_numeric_spec.rb +34 -0
  45. data/spec/unit/veritas/sql/generator/literal/visit_string_spec.rb +26 -0
  46. data/spec/unit/veritas/sql/generator/literal/visit_time_spec.rb +97 -0
  47. data/spec/unit/veritas/sql/generator/literal/visit_true_class_spec.rb +14 -0
  48. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_conjunction_spec.rb +16 -0
  49. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_disjunction_spec.rb +16 -0
  50. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_negation_spec.rb +16 -0
  51. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_equality_spec.rb +27 -0
  52. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_exclusion_spec.rb +43 -0
  53. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_or_equal_to_spec.rb +15 -0
  54. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_spec.rb +15 -0
  55. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_inclusion_spec.rb +43 -0
  56. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_inequality_spec.rb +55 -0
  57. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_or_equal_to_spec.rb +15 -0
  58. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_spec.rb +15 -0
  59. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_contradiction_spec.rb +15 -0
  60. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_tautology_spec.rb +15 -0
  61. data/spec/unit/veritas/sql/generator/relation/binary/base/to_subquery_spec.rb +35 -0
  62. data/spec/unit/veritas/sql/generator/relation/binary/base/visit_veritas_base_relation_spec.rb +22 -0
  63. data/spec/unit/veritas/sql/generator/relation/binary/class_methods/subquery_spec.rb +42 -0
  64. data/spec/unit/veritas/sql/generator/relation/binary/to_s_spec.rb +35 -0
  65. data/spec/unit/veritas/sql/generator/relation/binary/to_subquery_spec.rb +35 -0
  66. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_join_spec.rb +138 -0
  67. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_product_spec.rb +139 -0
  68. data/spec/unit/veritas/sql/generator/relation/class_methods/subquery_spec.rb +33 -0
  69. data/spec/unit/veritas/sql/generator/relation/class_methods/visit_spec.rb +61 -0
  70. data/spec/unit/veritas/sql/generator/relation/name_spec.rb +30 -0
  71. data/spec/unit/veritas/sql/generator/relation/set/to_s_spec.rb +55 -0
  72. data/spec/unit/veritas/sql/generator/relation/set/to_subquery_spec.rb +55 -0
  73. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_difference_spec.rb +138 -0
  74. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_intersection_spec.rb +138 -0
  75. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_union_spec.rb +138 -0
  76. data/spec/unit/veritas/sql/generator/relation/to_sql_spec.rb +52 -0
  77. data/spec/unit/veritas/sql/generator/relation/unary/to_s_spec.rb +55 -0
  78. data/spec/unit/veritas/sql/generator/relation/unary/to_subquery_spec.rb +75 -0
  79. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_projection_spec.rb +138 -0
  80. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_rename_spec.rb +136 -0
  81. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_restriction_spec.rb +157 -0
  82. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_base_relation_spec.rb +21 -0
  83. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_limit_spec.rb +125 -0
  84. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_offset_spec.rb +125 -0
  85. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_order_spec.rb +136 -0
  86. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_reverse_spec.rb +125 -0
  87. data/spec/unit/veritas/sql/generator/relation/visit_spec.rb +54 -0
  88. data/spec/unit/veritas/sql/generator/relation/visited_spec.rb +35 -0
  89. data/spec/unit/veritas/sql/generator/visitor/class_methods/handler_for_spec.rb +71 -0
  90. data/spec/unit/veritas/sql/generator/visitor/visit_spec.rb +12 -0
  91. data/spec/unit/veritas/sql/generator/visitor/visited_spec.rb +11 -0
  92. data/tasks/quality/ci.rake +2 -0
  93. data/tasks/quality/flay.rake +41 -0
  94. data/tasks/quality/flog.rake +45 -0
  95. data/tasks/quality/heckle.rake +203 -0
  96. data/tasks/quality/metric_fu.rake +26 -0
  97. data/tasks/quality/reek.rake +9 -0
  98. data/tasks/quality/roodi.rake +15 -0
  99. data/tasks/quality/yardstick.rake +23 -0
  100. data/tasks/spec.rake +38 -0
  101. data/tasks/yard.rake +9 -0
  102. data/veritas-sql-generator.gemspec +222 -0
  103. metadata +285 -0
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SQL::Generator::Relation::Unary, '#visit_veritas_algebra_rename' do
6
+ subject { object.visit_veritas_algebra_rename(rename) }
7
+
8
+ let(:relation_name) { 'users' }
9
+ let(:id) { Attribute::Integer.new(:id) }
10
+ let(:name) { Attribute::String.new(:name) }
11
+ let(:age) { Attribute::Integer.new(:age, :required => false) }
12
+ let(:header) { [ id, name, age ] }
13
+ let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
14
+ let(:base_relation) { BaseRelation.new(relation_name, header, body) }
15
+ let(:rename) { operand.rename(:id => :user_id) }
16
+ let(:object) { described_class.new }
17
+
18
+ context 'when the operand is a base relation' do
19
+ let(:operand) { base_relation }
20
+
21
+ it_should_behave_like 'a generated SQL SELECT query'
22
+
23
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users"') }
24
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users"') }
25
+ end
26
+
27
+ context 'when the operand is a projection' do
28
+ let(:operand) { base_relation.project([ :id, :name ]) }
29
+
30
+ it_should_behave_like 'a generated SQL SELECT query'
31
+
32
+ its(:to_s) { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') }
33
+ its(:to_subquery) { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') }
34
+ end
35
+
36
+ context 'when the operand is a rename' do
37
+ let(:operand) { base_relation.rename(:name => :other_name) }
38
+
39
+ context 'when the relation is not optimized' do
40
+ it_should_behave_like 'a generated SQL SELECT query'
41
+
42
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "other_name", "age" FROM (SELECT "id", "name" AS "other_name", "age" FROM "users") AS "users"') }
43
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "other_name", "age" FROM (SELECT "id", "name" AS "other_name", "age" FROM "users") AS "users"') }
44
+ end
45
+
46
+ context 'when the operand is empty' do
47
+ let(:operand) { base_relation.rename({}) }
48
+
49
+ it_should_behave_like 'a generated SQL SELECT query'
50
+
51
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM (SELECT "id", "name", "age" FROM "users") AS "users"') }
52
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM (SELECT "id", "name", "age" FROM "users") AS "users"') }
53
+ end
54
+ end
55
+
56
+ context 'when the operand is a restriction' do
57
+ let(:operand) { base_relation.restrict { |r| r[:id].eq(1) } }
58
+
59
+ it_should_behave_like 'a generated SQL SELECT query'
60
+
61
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" WHERE "id" = 1') }
62
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" WHERE "id" = 1') }
63
+ end
64
+
65
+ context 'when the operand is ordered' do
66
+ let(:operand) { base_relation.order }
67
+
68
+ it_should_behave_like 'a generated SQL SELECT query'
69
+
70
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age"') }
71
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age"') }
72
+ end
73
+
74
+ context 'when the operand is reversed' do
75
+ let(:operand) { base_relation.order.reverse }
76
+
77
+ it_should_behave_like 'a generated SQL SELECT query'
78
+
79
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC') }
80
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC') }
81
+ end
82
+
83
+ context 'when the operand is limited' do
84
+ let(:operand) { base_relation.order.take(1) }
85
+
86
+ it_should_behave_like 'a generated SQL SELECT query'
87
+
88
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
89
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
90
+ end
91
+
92
+ context 'when the operand is an offset' do
93
+ let(:operand) { base_relation.order.drop(1) }
94
+
95
+ it_should_behave_like 'a generated SQL SELECT query'
96
+
97
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
98
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
99
+ end
100
+
101
+ context 'when the operand is a difference' do
102
+ let(:operand) { base_relation.difference(base_relation) }
103
+
104
+ it_should_behave_like 'a generated SQL SELECT query'
105
+
106
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users"') }
107
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users"') }
108
+ end
109
+
110
+ context 'when the operand is an intersection' do
111
+ let(:operand) { base_relation.intersect(base_relation) }
112
+
113
+ it_should_behave_like 'a generated SQL SELECT query'
114
+
115
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users"') }
116
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users"') }
117
+ end
118
+
119
+ context 'when the operand is a union' do
120
+ let(:operand) { base_relation.union(base_relation) }
121
+
122
+ it_should_behave_like 'a generated SQL SELECT query'
123
+
124
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users"') }
125
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users"') }
126
+ end
127
+
128
+ context 'when the operand is a join' do
129
+ let(:operand) { base_relation.join(base_relation) }
130
+
131
+ it_should_behave_like 'a generated SQL SELECT query'
132
+
133
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users"') }
134
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users"') }
135
+ end
136
+ end
@@ -0,0 +1,157 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SQL::Generator::Relation::Unary, '#visit_veritas_algebra_restriction' do
6
+ subject { object.visit_veritas_algebra_restriction(restriction) }
7
+
8
+ let(:relation_name) { 'users' }
9
+ let(:id) { Attribute::Integer.new(:id) }
10
+ let(:name) { Attribute::String.new(:name) }
11
+ let(:age) { Attribute::Integer.new(:age, :required => false) }
12
+ let(:header) { [ id, name, age ] }
13
+ let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
14
+ let(:base_relation) { BaseRelation.new(relation_name, header, body) }
15
+ let(:restriction) { operand.restrict { |r| r[:id].eq(1) } }
16
+ let(:object) { described_class.new }
17
+
18
+ context 'when the operand is a base relation' do
19
+ let(:operand) { base_relation }
20
+
21
+ it_should_behave_like 'a generated SQL SELECT query'
22
+
23
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" WHERE "id" = 1') }
24
+ its(:to_subquery) { should eql('SELECT * FROM "users" WHERE "id" = 1') }
25
+ end
26
+
27
+ context 'when the operand is a projection' do
28
+ let(:operand) { base_relation.project([ :id, :name ]) }
29
+
30
+ it_should_behave_like 'a generated SQL SELECT query'
31
+
32
+ its(:to_s) { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
33
+ its(:to_subquery) { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
34
+ end
35
+
36
+ context 'when the operand is a projection then a restriction' do
37
+ let(:operand) { base_relation.project([ :id, :name ]).restrict { |r| r[:id].ne(2) } }
38
+
39
+ it_should_behave_like 'a generated SQL SELECT query'
40
+
41
+ its(:to_s) { should eql('SELECT "id", "name" FROM (SELECT DISTINCT "id", "name" FROM "users" WHERE "id" <> 2) AS "users" WHERE "id" = 1') }
42
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT DISTINCT "id", "name" FROM "users" WHERE "id" <> 2) AS "users" WHERE "id" = 1') }
43
+ end
44
+
45
+ context 'when the operand is a projection then a restriction, followed by another restriction' do
46
+ let(:tautology) { Logic::Proposition::Tautology.instance }
47
+ let(:operand) { base_relation.project([ :id, :name ]).restrict(tautology).restrict(tautology) }
48
+
49
+ it_should_behave_like 'a generated SQL SELECT query'
50
+
51
+ its(:to_s) { should eql('SELECT "id", "name" FROM (SELECT * FROM (SELECT DISTINCT "id", "name" FROM "users" WHERE 1 = 1) AS "users" WHERE 1 = 1) AS "users" WHERE "id" = 1') }
52
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM (SELECT DISTINCT "id", "name" FROM "users" WHERE 1 = 1) AS "users" WHERE 1 = 1) AS "users" WHERE "id" = 1') }
53
+ end
54
+
55
+ context 'when the operand is a rename' do
56
+ context 'when the restriction includes the renamed column' do
57
+ let(:operand) { base_relation.rename(:id => :user_id) }
58
+ let(:restriction) { operand.restrict { |r| r[:user_id].eq(1) } }
59
+
60
+ it_should_behave_like 'a generated SQL SELECT query'
61
+
62
+ its(:to_s) { pending { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" WHERE "id" = 1') } }
63
+ its(:to_subquery) { pending { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" WHERE "id" = 1') } }
64
+ end
65
+
66
+ context 'when the restriction does not include the renamed column' do
67
+ let(:operand) { base_relation.rename(:name => :other_name) }
68
+ let(:restriction) { operand.restrict { |r| r[:id].eq(1) } }
69
+
70
+ it_should_behave_like 'a generated SQL SELECT query'
71
+
72
+ its(:to_s) { pending { should eql('SELECT "id", "name" AS "other_name", "age" FROM "users" WHERE "id" = 1') } }
73
+ its(:to_subquery) { pending { should eql('SELECT "id", "name" AS "other_name", "age" FROM "users" WHERE "id" = 1') } }
74
+ end
75
+ end
76
+
77
+ context 'when the operand is a restriction' do
78
+ let(:operand) { base_relation.restrict { |r| r[:id].eq(1) } }
79
+
80
+ it_should_behave_like 'a generated SQL SELECT query'
81
+
82
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" WHERE "id" = 1) AS "users" WHERE "id" = 1') }
83
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" WHERE "id" = 1) AS "users" WHERE "id" = 1') }
84
+ end
85
+
86
+ context 'when the operand is ordered' do
87
+ let(:operand) { base_relation.order }
88
+
89
+ it_should_behave_like 'a generated SQL SELECT query'
90
+
91
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age"') }
92
+ its(:to_subquery) { should eql('SELECT * FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age"') }
93
+ end
94
+
95
+ context 'when the operand is reversed' do
96
+ let(:operand) { base_relation.order.reverse }
97
+
98
+ it_should_behave_like 'a generated SQL SELECT query'
99
+
100
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" WHERE "id" = 1 ORDER BY "id" DESC, "name" DESC, "age" DESC') }
101
+ its(:to_subquery) { should eql('SELECT * FROM "users" WHERE "id" = 1 ORDER BY "id" DESC, "name" DESC, "age" DESC') }
102
+ end
103
+
104
+ context 'when the operand is limited' do
105
+ let(:operand) { base_relation.order.take(1) }
106
+
107
+ it_should_behave_like 'a generated SQL SELECT query'
108
+
109
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" WHERE "id" = 1') }
110
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" WHERE "id" = 1') }
111
+ end
112
+
113
+ context 'when the operand is an offset' do
114
+ let(:operand) { base_relation.order.drop(1) }
115
+
116
+ it_should_behave_like 'a generated SQL SELECT query'
117
+
118
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "users" WHERE "id" = 1') }
119
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "users" WHERE "id" = 1') }
120
+ end
121
+
122
+ context 'when the operand is a difference' do
123
+ let(:operand) { base_relation.difference(base_relation) }
124
+
125
+ it_should_behave_like 'a generated SQL SELECT query'
126
+
127
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
128
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
129
+ end
130
+
131
+ context 'when the operand is an intersection' do
132
+ let(:operand) { base_relation.intersect(base_relation) }
133
+
134
+ it_should_behave_like 'a generated SQL SELECT query'
135
+
136
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
137
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
138
+ end
139
+
140
+ context 'when the operand is a union' do
141
+ let(:operand) { base_relation.union(base_relation) }
142
+
143
+ it_should_behave_like 'a generated SQL SELECT query'
144
+
145
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
146
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" WHERE "id" = 1') }
147
+ end
148
+
149
+ context 'when the operand is a join' do
150
+ let(:operand) { base_relation.join(base_relation) }
151
+
152
+ it_should_behave_like 'a generated SQL SELECT query'
153
+
154
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" WHERE "id" = 1') }
155
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" WHERE "id" = 1') }
156
+ end
157
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SQL::Generator::Relation::Unary, '#visit_veritas_base_relation' do
6
+ subject { object.visit_veritas_base_relation(base_relation) }
7
+
8
+ let(:relation_name) { 'users' }
9
+ let(:id) { Attribute::Integer.new(:id) }
10
+ let(:name) { Attribute::String.new(:name) }
11
+ let(:age) { Attribute::Integer.new(:age, :required => false) }
12
+ let(:header) { [ id, name, age ] }
13
+ let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
14
+ let(:base_relation) { BaseRelation.new(relation_name, header, body) }
15
+ let(:object) { described_class.new }
16
+
17
+ it_should_behave_like 'a generated SQL SELECT query'
18
+
19
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users"') }
20
+ its(:to_subquery) { should eql('SELECT * FROM "users"') }
21
+ end
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SQL::Generator::Relation::Unary, '#visit_veritas_relation_operation_limit' do
6
+ subject { object.visit_veritas_relation_operation_limit(limit) }
7
+
8
+ let(:relation_name) { 'users' }
9
+ let(:id) { Attribute::Integer.new(:id) }
10
+ let(:name) { Attribute::String.new(:name) }
11
+ let(:age) { Attribute::Integer.new(:age, :required => false) }
12
+ let(:header) { [ id, name, age ] }
13
+ let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
14
+ let(:base_relation) { BaseRelation.new(relation_name, header, body) }
15
+ let(:limit) { operand.take(1) }
16
+ let(:object) { described_class.new }
17
+
18
+ context 'when the operand is a base relation' do
19
+ let(:operand) { base_relation.order }
20
+
21
+ it_should_behave_like 'a generated SQL SELECT query'
22
+
23
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
24
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
25
+ end
26
+
27
+ context 'when the operand is a projection' do
28
+ let(:operand) { base_relation.project([ :id, :name ]).order }
29
+
30
+ it_should_behave_like 'a generated SQL SELECT query'
31
+
32
+ its(:to_s) { should eql('SELECT DISTINCT "id", "name" FROM "users" ORDER BY "id", "name" LIMIT 1') }
33
+ its(:to_subquery) { should eql('SELECT DISTINCT "id", "name" FROM "users" ORDER BY "id", "name" LIMIT 1') }
34
+ end
35
+
36
+ context 'when the operand is a rename' do
37
+ let(:operand) { base_relation.order.rename(:id => :user_id) }
38
+
39
+ it_should_behave_like 'a generated SQL SELECT query'
40
+
41
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
42
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
43
+ end
44
+
45
+ context 'when the operand is a restriction' do
46
+ let(:operand) { base_relation.order.restrict { |r| r[:id].eq(1) } }
47
+
48
+ it_should_behave_like 'a generated SQL SELECT query'
49
+
50
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age" LIMIT 1') }
51
+ its(:to_subquery) { should eql('SELECT * FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age" LIMIT 1') }
52
+ end
53
+
54
+ context 'when the operand is ordered' do
55
+ let(:operand) { base_relation.order }
56
+
57
+ it_should_behave_like 'a generated SQL SELECT query'
58
+
59
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
60
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1') }
61
+ end
62
+
63
+ context 'when the operand is reversed' do
64
+ let(:operand) { base_relation.order.reverse }
65
+
66
+ it_should_behave_like 'a generated SQL SELECT query'
67
+
68
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC LIMIT 1') }
69
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC LIMIT 1') }
70
+ end
71
+
72
+ context 'when the operand is limited' do
73
+ let(:operand) { base_relation.order.take(1) }
74
+
75
+ it_should_behave_like 'a generated SQL SELECT query'
76
+
77
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" LIMIT 1') }
78
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" LIMIT 1') }
79
+ end
80
+
81
+ context 'when the operand is an offset' do
82
+ let(:operand) { base_relation.order.drop(1) }
83
+
84
+ it_should_behave_like 'a generated SQL SELECT query'
85
+
86
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1 OFFSET 1') }
87
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1 OFFSET 1') }
88
+ end
89
+
90
+ context 'when the operand is a difference' do
91
+ let(:operand) { base_relation.difference(base_relation).order }
92
+
93
+ it_should_behave_like 'a generated SQL SELECT query'
94
+
95
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
96
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
97
+ end
98
+
99
+ context 'when the operand is an intersection' do
100
+ let(:operand) { base_relation.intersect(base_relation).order }
101
+
102
+ it_should_behave_like 'a generated SQL SELECT query'
103
+
104
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
105
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
106
+ end
107
+
108
+ context 'when the operand is a union' do
109
+ let(:operand) { base_relation.union(base_relation).order }
110
+
111
+ it_should_behave_like 'a generated SQL SELECT query'
112
+
113
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
114
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
115
+ end
116
+
117
+ context 'when the operand is a join' do
118
+ let(:operand) { base_relation.join(base_relation).order }
119
+
120
+ it_should_behave_like 'a generated SQL SELECT query'
121
+
122
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
123
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" ORDER BY "id", "name", "age" LIMIT 1') }
124
+ end
125
+ end
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SQL::Generator::Relation::Unary, '#visit_veritas_relation_operation_offset' do
6
+ subject { object.visit_veritas_relation_operation_offset(offset) }
7
+
8
+ let(:relation_name) { 'users' }
9
+ let(:id) { Attribute::Integer.new(:id) }
10
+ let(:name) { Attribute::String.new(:name) }
11
+ let(:age) { Attribute::Integer.new(:age, :required => false) }
12
+ let(:header) { [ id, name, age ] }
13
+ let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
14
+ let(:base_relation) { BaseRelation.new(relation_name, header, body) }
15
+ let(:offset) { operand.drop(1) }
16
+ let(:object) { described_class.new }
17
+
18
+ context 'when the operand is a base relation' do
19
+ let(:operand) { base_relation.order }
20
+
21
+ it_should_behave_like 'a generated SQL SELECT query'
22
+
23
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
24
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
25
+ end
26
+
27
+ context 'when the operand is a projection' do
28
+ let(:operand) { base_relation.project([ :id, :name ]).order }
29
+
30
+ it_should_behave_like 'a generated SQL SELECT query'
31
+
32
+ its(:to_s) { should eql('SELECT DISTINCT "id", "name" FROM "users" ORDER BY "id", "name" OFFSET 1') }
33
+ its(:to_subquery) { should eql('SELECT DISTINCT "id", "name" FROM "users" ORDER BY "id", "name" OFFSET 1') }
34
+ end
35
+
36
+ context 'when the operand is a rename' do
37
+ let(:operand) { base_relation.order.rename(:id => :user_id) }
38
+
39
+ it_should_behave_like 'a generated SQL SELECT query'
40
+
41
+ its(:to_s) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
42
+ its(:to_subquery) { should eql('SELECT "id" AS "user_id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
43
+ end
44
+
45
+ context 'when the operand is a restriction' do
46
+ let(:operand) { base_relation.order.restrict { |r| r[:id].eq(1) } }
47
+
48
+ it_should_behave_like 'a generated SQL SELECT query'
49
+
50
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age" OFFSET 1') }
51
+ its(:to_subquery) { should eql('SELECT * FROM "users" WHERE "id" = 1 ORDER BY "id", "name", "age" OFFSET 1') }
52
+ end
53
+
54
+ context 'when the operand is ordered' do
55
+ let(:operand) { base_relation.order }
56
+
57
+ it_should_behave_like 'a generated SQL SELECT query'
58
+
59
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
60
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1') }
61
+ end
62
+
63
+ context 'when the operand is reversed' do
64
+ let(:operand) { base_relation.order.reverse }
65
+
66
+ it_should_behave_like 'a generated SQL SELECT query'
67
+
68
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC OFFSET 1') }
69
+ its(:to_subquery) { should eql('SELECT * FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC OFFSET 1') }
70
+ end
71
+
72
+ context 'when the operand is limited' do
73
+ let(:operand) { base_relation.order.take(1) }
74
+
75
+ it_should_behave_like 'a generated SQL SELECT query'
76
+
77
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" OFFSET 1') }
78
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "users" OFFSET 1') }
79
+ end
80
+
81
+ context 'when the operand is an offset' do
82
+ let(:operand) { base_relation.order.drop(1) }
83
+
84
+ it_should_behave_like 'a generated SQL SELECT query'
85
+
86
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "users" OFFSET 1') }
87
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "users" OFFSET 1') }
88
+ end
89
+
90
+ context 'when the operand is a difference' do
91
+ let(:operand) { base_relation.difference(base_relation).order }
92
+
93
+ it_should_behave_like 'a generated SQL SELECT query'
94
+
95
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
96
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") EXCEPT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
97
+ end
98
+
99
+ context 'when the operand is an intersection' do
100
+ let(:operand) { base_relation.intersect(base_relation).order }
101
+
102
+ it_should_behave_like 'a generated SQL SELECT query'
103
+
104
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
105
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") INTERSECT (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
106
+ end
107
+
108
+ context 'when the operand is a union' do
109
+ let(:operand) { base_relation.union(base_relation).order }
110
+
111
+ it_should_behave_like 'a generated SQL SELECT query'
112
+
113
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
114
+ its(:to_subquery) { should eql('SELECT * FROM ((SELECT * FROM "users") UNION (SELECT * FROM "users")) AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
115
+ end
116
+
117
+ context 'when the operand is a join' do
118
+ let(:operand) { base_relation.join(base_relation).order }
119
+
120
+ it_should_behave_like 'a generated SQL SELECT query'
121
+
122
+ its(:to_s) { should eql('SELECT "id", "name", "age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
123
+ its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "users" ORDER BY "id", "name", "age" OFFSET 1') }
124
+ end
125
+ end