arel 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/History.txt +8 -0
  2. data/README.markdown +0 -2
  3. data/Rakefile +2 -2
  4. data/arel.gemspec +13 -3
  5. data/lib/arel.rb +2 -2
  6. data/lib/arel/algebra/relations/relation.rb +3 -2
  7. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +62 -0
  8. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
  9. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
  10. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
  11. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
  12. data/lib/arel/engines/sql/engine.rb +17 -3
  13. data/lib/arel/engines/sql/formatters.rb +3 -3
  14. data/lib/arel/engines/sql/relations.rb +1 -0
  15. data/lib/arel/engines/sql/relations/compiler.rb +118 -0
  16. data/lib/arel/engines/sql/relations/relation.rb +38 -63
  17. data/lib/arel/engines/sql/relations/table.rb +23 -3
  18. data/lib/arel/engines/sql/relations/utilities/externalization.rb +1 -1
  19. data/lib/arel/engines/sql/relations/writes.rb +4 -71
  20. data/spec/arel/algebra/unit/relations/relation_spec.rb +1 -2
  21. data/spec/arel/algebra/unit/relations/table_spec.rb +0 -1
  22. data/spec/arel/engines/memory/integration/joins/cross_engine_spec.rb +9 -4
  23. data/spec/arel/engines/sql/integration/joins/with_adjacency_spec.rb +68 -19
  24. data/spec/arel/engines/sql/integration/joins/with_aggregations_spec.rb +74 -20
  25. data/spec/arel/engines/sql/integration/joins/with_compounds_spec.rb +33 -3
  26. data/spec/arel/engines/sql/unit/predicates/binary_spec.rb +22 -2
  27. data/spec/arel/engines/sql/unit/predicates/equality_spec.rb +15 -3
  28. data/spec/arel/engines/sql/unit/predicates/in_spec.rb +59 -5
  29. data/spec/arel/engines/sql/unit/predicates/predicates_spec.rb +12 -0
  30. data/spec/arel/engines/sql/unit/primitives/attribute_spec.rb +24 -1
  31. data/spec/arel/engines/sql/unit/primitives/expression_spec.rb +5 -1
  32. data/spec/arel/engines/sql/unit/primitives/literal_spec.rb +10 -2
  33. data/spec/arel/engines/sql/unit/relations/alias_spec.rb +11 -1
  34. data/spec/arel/engines/sql/unit/relations/delete_spec.rb +23 -3
  35. data/spec/arel/engines/sql/unit/relations/from_spec.rb +16 -2
  36. data/spec/arel/engines/sql/unit/relations/group_spec.rb +18 -2
  37. data/spec/arel/engines/sql/unit/relations/having_spec.rb +12 -3
  38. data/spec/arel/engines/sql/unit/relations/insert_spec.rb +37 -1
  39. data/spec/arel/engines/sql/unit/relations/join_spec.rb +53 -11
  40. data/spec/arel/engines/sql/unit/relations/lock_spec.rb +25 -0
  41. data/spec/arel/engines/sql/unit/relations/order_spec.rb +52 -4
  42. data/spec/arel/engines/sql/unit/relations/project_spec.rb +38 -5
  43. data/spec/arel/engines/sql/unit/relations/skip_spec.rb +10 -1
  44. data/spec/arel/engines/sql/unit/relations/table_spec.rb +26 -5
  45. data/spec/arel/engines/sql/unit/relations/take_spec.rb +18 -1
  46. data/spec/arel/engines/sql/unit/relations/update_spec.rb +47 -1
  47. data/spec/arel/engines/sql/unit/relations/where_spec.rb +18 -2
  48. data/spec/connections/oracle_connection.rb +19 -0
  49. data/spec/schemas/mysql_schema.rb +2 -1
  50. data/spec/schemas/oracle_schema.rb +20 -0
  51. data/spec/schemas/postgresql_schema.rb +2 -1
  52. data/spec/schemas/sqlite3_schema.rb +2 -1
  53. data/spec/spec_helper.rb +16 -7
  54. metadata +31 -9
@@ -30,6 +30,24 @@ module Arel
30
30
  FROM "users"
31
31
  })
32
32
  end
33
+
34
+ adapter_is :oracle do
35
+ sql.should be_like(%Q{
36
+ SELECT "USERS"."ID", "USERS"."NAME"
37
+ FROM "USERS" FOR UPDATE
38
+ })
39
+
40
+ sql_with_order_by = @relation.order(@relation[:id]).take(1).lock.to_sql
41
+ sql_with_order_by.should be_like(%Q{
42
+ SELECT "USERS"."ID", "USERS"."NAME"
43
+ FROM "USERS"
44
+ WHERE "ID" IN (select * from
45
+ (SELECT "ID" FROM "USERS" ORDER BY "USERS"."ID" ASC)
46
+ where rownum <= 1)
47
+ FOR UPDATE
48
+ })
49
+
50
+ end
33
51
  end
34
52
 
35
53
  it "manufactures a select query locking with a given lock" do
@@ -55,6 +73,13 @@ module Arel
55
73
  FROM "users"
56
74
  })
57
75
  end
76
+
77
+ adapter_is :oracle do
78
+ sql.should be_like(%Q{
79
+ SELECT "USERS"."ID", "USERS"."NAME"
80
+ FROM "USERS" LOCK IN SHARE MODE
81
+ })
82
+ end
58
83
  end
59
84
  end
60
85
  end
@@ -20,7 +20,31 @@ module Arel
20
20
  })
21
21
  end
22
22
 
23
- adapter_is_not :mysql do
23
+ adapter_is :oracle do
24
+ sql.should be_like(%Q{
25
+ SELECT "USERS"."ID", "USERS"."NAME"
26
+ FROM "USERS"
27
+ ORDER BY "USERS"."ID" ASC
28
+ })
29
+
30
+ distinct_attributes = ActiveRecord::Base.connection.distinct('"USERS"."NAME"', '"USERS"."ID"')
31
+ @relation.project(distinct_attributes).order(@relation[:id]).to_sql.should be_like(%Q{
32
+ SELECT DISTINCT "USERS"."NAME",
33
+ FIRST_VALUE("USERS"."ID") OVER (PARTITION BY "USERS"."NAME" ORDER BY "USERS"."ID") AS alias_0__
34
+ FROM "USERS"
35
+ ORDER BY alias_0__
36
+ })
37
+
38
+ distinct_attributes = ActiveRecord::Base.connection.distinct('"USERS"."NAME"', '"USERS"."ID" DESC')
39
+ @relation.project(distinct_attributes).order('"USERS"."ID" DESC').to_sql.should be_like(%Q{
40
+ SELECT DISTINCT "USERS"."NAME",
41
+ FIRST_VALUE("USERS"."ID") OVER (PARTITION BY "USERS"."NAME" ORDER BY "USERS"."ID" DESC) AS alias_0__
42
+ FROM "USERS"
43
+ ORDER BY alias_0__ DESC
44
+ })
45
+ end
46
+
47
+ adapter_is_not :mysql, :oracle do
24
48
  sql.should be_like(%Q{
25
49
  SELECT "users"."id", "users"."name"
26
50
  FROM "users"
@@ -46,7 +70,15 @@ module Arel
46
70
  })
47
71
  end
48
72
 
49
- adapter_is_not :mysql do
73
+ adapter_is :oracle do
74
+ sql.should be_like(%Q{
75
+ SELECT "USERS"."ID", "USERS"."NAME"
76
+ FROM "USERS"
77
+ ORDER BY "USERS"."ID" ASC, "USERS"."NAME" ASC
78
+ })
79
+ end
80
+
81
+ adapter_is_not :mysql, :oracle do
50
82
  sql.should be_like(%Q{
51
83
  SELECT "users"."id", "users"."name"
52
84
  FROM "users"
@@ -72,7 +104,15 @@ module Arel
72
104
  })
73
105
  end
74
106
 
75
- adapter_is_not :mysql do
107
+ adapter_is :oracle do
108
+ sql.should be_like(%Q{
109
+ SELECT "USERS"."ID", "USERS"."NAME"
110
+ FROM "USERS"
111
+ ORDER BY asdf
112
+ })
113
+ end
114
+
115
+ adapter_is_not :mysql, :oracle do
76
116
  sql.should be_like(%Q{
77
117
  SELECT "users"."id", "users"."name"
78
118
  FROM "users"
@@ -99,7 +139,15 @@ module Arel
99
139
  })
100
140
  end
101
141
 
102
- adapter_is_not :mysql do
142
+ adapter_is :oracle do
143
+ sql.should be_like(%Q{
144
+ SELECT "USERS"."ID", "USERS"."NAME"
145
+ FROM "USERS"
146
+ ORDER BY "USERS"."NAME" ASC, "USERS"."ID" ASC
147
+ })
148
+ end
149
+
150
+ adapter_is_not :mysql, :oracle do
103
151
  sql.should be_like(%Q{
104
152
  SELECT "users"."id", "users"."name"
105
153
  FROM "users"
@@ -19,7 +19,14 @@ module Arel
19
19
  })
20
20
  end
21
21
 
22
- adapter_is_not :mysql do
22
+ adapter_is :oracle do
23
+ sql.should be_like(%Q{
24
+ SELECT "USERS"."ID"
25
+ FROM "USERS"
26
+ })
27
+ end
28
+
29
+ adapter_is_not :mysql, :oracle do
23
30
  sql.should be_like(%Q{
24
31
  SELECT "users"."id"
25
32
  FROM "users"
@@ -42,7 +49,13 @@ module Arel
42
49
  })
43
50
  end
44
51
 
45
- adapter_is_not :mysql do
52
+ adapter_is :oracle do
53
+ sql.should be_like(%Q{
54
+ SELECT (SELECT "USERS"."NAME" FROM "USERS") AS "USERS" FROM "USERS"
55
+ })
56
+ end
57
+
58
+ adapter_is_not :mysql, :oracle do
46
59
  sql.should be_like(%Q{
47
60
  SELECT (SELECT "users"."name" FROM "users") AS "users" FROM "users"
48
61
  })
@@ -60,7 +73,13 @@ module Arel
60
73
  })
61
74
  end
62
75
 
63
- adapter_is_not :mysql do
76
+ adapter_is :oracle do
77
+ sql.should be_like(%Q{
78
+ SELECT asdf FROM "USERS"
79
+ })
80
+ end
81
+
82
+ adapter_is_not :mysql, :oracle do
64
83
  sql.should be_like(%Q{
65
84
  SELECT asdf FROM "users"
66
85
  })
@@ -79,7 +98,14 @@ module Arel
79
98
  })
80
99
  end
81
100
 
82
- adapter_is_not :mysql do
101
+ adapter_is :oracle do
102
+ sql.should be_like(%Q{
103
+ SELECT COUNT("USERS"."ID") AS count_id
104
+ FROM "USERS"
105
+ })
106
+ end
107
+
108
+ adapter_is_not :mysql, :oracle do
83
109
  sql.should be_like(%Q{
84
110
  SELECT COUNT("users"."id") AS count_id
85
111
  FROM "users"
@@ -97,7 +123,14 @@ module Arel
97
123
  })
98
124
  end
99
125
 
100
- adapter_is_not :mysql do
126
+ adapter_is :oracle do
127
+ sql.should be_like(%Q{
128
+ SELECT COUNT(DISTINCT "USERS"."ID") AS count_id
129
+ FROM "USERS"
130
+ })
131
+ end
132
+
133
+ adapter_is_not :mysql, :oracle do
101
134
  sql.should be_like(%Q{
102
135
  SELECT COUNT(DISTINCT "users"."id") AS count_id
103
136
  FROM "users"
@@ -19,7 +19,16 @@ module Arel
19
19
  })
20
20
  end
21
21
 
22
- adapter_is_not :mysql do
22
+ adapter_is :oracle do
23
+ sql.should be_like(%Q{
24
+ select * from (select raw_sql_.*, rownum raw_rnum_ from
25
+ (SELECT "USERS"."ID", "USERS"."NAME"
26
+ FROM "USERS") raw_sql_)
27
+ where raw_rnum_ > 4
28
+ })
29
+ end
30
+
31
+ adapter_is_not :mysql, :oracle do
23
32
  sql.should be_like(%Q{
24
33
  SELECT "users"."id", "users"."name"
25
34
  FROM "users"
@@ -17,7 +17,14 @@ module Arel
17
17
  })
18
18
  end
19
19
 
20
- adapter_is_not :mysql do
20
+ adapter_is :oracle do
21
+ sql.should be_like(%Q{
22
+ SELECT "USERS"."ID", "USERS"."NAME"
23
+ FROM "USERS"
24
+ })
25
+ end
26
+
27
+ adapter_is_not :mysql, :oracle do
21
28
  sql.should be_like(%Q{
22
29
  SELECT "users"."id", "users"."name"
23
30
  FROM "users"
@@ -33,14 +40,21 @@ module Arel
33
40
  adapter_is :mysql do
34
41
  sql.should be_like(%Q{
35
42
  SELECT `super_users`.`id`, `super_users`.`name`
36
- FROM `users` AS `super_users`
43
+ FROM `users` `super_users`
44
+ })
45
+ end
46
+
47
+ adapter_is :oracle do
48
+ sql.should be_like(%Q{
49
+ SELECT "SUPER_USERS"."ID", "SUPER_USERS"."NAME"
50
+ FROM "USERS" "SUPER_USERS"
37
51
  })
38
52
  end
39
53
 
40
- adapter_is_not :mysql do
54
+ adapter_is_not :mysql, :oracle do
41
55
  sql.should be_like(%Q{
42
56
  SELECT "super_users"."id", "super_users"."name"
43
- FROM "users" AS "super_users"
57
+ FROM "users" "super_users"
44
58
  })
45
59
  end
46
60
  end
@@ -55,7 +69,14 @@ module Arel
55
69
  })
56
70
  end
57
71
 
58
- adapter_is_not :mysql do
72
+ adapter_is :oracle do
73
+ sql.should be_like(%Q{
74
+ SELECT "USERS"."ID", "USERS"."NAME"
75
+ FROM "USERS"
76
+ })
77
+ end
78
+
79
+ adapter_is_not :mysql, :oracle do
59
80
  sql.should be_like(%Q{
60
81
  SELECT "users"."id", "users"."name"
61
82
  FROM "users"
@@ -19,7 +19,24 @@ module Arel
19
19
  })
20
20
  end
21
21
 
22
- adapter_is_not :mysql do
22
+ adapter_is :oracle do
23
+ sql.should be_like(%Q{
24
+ SELECT "USERS"."ID", "USERS"."NAME"
25
+ FROM "USERS"
26
+ WHERE ROWNUM <= 4
27
+ })
28
+
29
+ sql_with_order_by = Take.new(@relation.order(@relation[:id]), @taken).to_sql
30
+ sql_with_order_by.should be_like(%Q{
31
+ select * from
32
+ (SELECT "USERS"."ID", "USERS"."NAME"
33
+ FROM "USERS"
34
+ ORDER BY "USERS"."ID" ASC)
35
+ where rownum <= 4
36
+ })
37
+ end
38
+
39
+ adapter_is_not :mysql, :oracle do
23
40
  sql.should be_like(%Q{
24
41
  SELECT "users"."id", "users"."name"
25
42
  FROM "users"
@@ -36,6 +36,13 @@ module Arel
36
36
  SET "id" = 1, "name" = E'nick'
37
37
  })
38
38
  end
39
+
40
+ adapter_is :oracle do
41
+ sql.should be_like(%Q{
42
+ UPDATE "USERS"
43
+ SET "ID" = 1, "NAME" = 'nick'
44
+ })
45
+ end
39
46
  end
40
47
 
41
48
  it "manufactures sql updating attributes when given a ranged relation" do
@@ -64,6 +71,23 @@ module Arel
64
71
  WHERE "id" IN (SELECT "id" FROM "users" LIMIT 1)
65
72
  })
66
73
  end
74
+
75
+ adapter_is :oracle do
76
+ sql.should be_like(%Q{
77
+ UPDATE "USERS" SET
78
+ "NAME" = 'nick'
79
+ WHERE "ID" IN (SELECT "ID" FROM "USERS" WHERE ROWNUM <= 1)
80
+ })
81
+
82
+ sql_with_order_by = Update.new(@relation.order(@relation[:id]).take(1), @relation[:name] => "nick").to_sql
83
+ sql_with_order_by.should be_like(%Q{
84
+ UPDATE "USERS" SET
85
+ "NAME" = 'nick'
86
+ WHERE "ID" IN (select * from
87
+ (SELECT "ID" FROM "USERS" ORDER BY "USERS"."ID" ASC)
88
+ where rownum <= 1)
89
+ })
90
+ end
67
91
  end
68
92
 
69
93
  describe 'when given values whose types correspond to the types of the attributes' do
@@ -92,6 +116,13 @@ module Arel
92
116
  SET "name" = E'nick'
93
117
  })
94
118
  end
119
+
120
+ adapter_is :oracle do
121
+ @update.to_sql.should be_like(%Q{
122
+ UPDATE "USERS"
123
+ SET "NAME" = 'nick'
124
+ })
125
+ end
95
126
  end
96
127
  end
97
128
 
@@ -108,7 +139,14 @@ module Arel
108
139
  })
109
140
  end
110
141
 
111
- adapter_is_not :mysql do
142
+ adapter_is :oracle do
143
+ @update.to_sql.should be_like(%Q{
144
+ UPDATE "USERS"
145
+ SET "ID" = 1
146
+ })
147
+ end
148
+
149
+ adapter_is_not :mysql, :oracle do
112
150
  @update.to_sql.should be_like(%Q{
113
151
  UPDATE "users"
114
152
  SET "id" = 1
@@ -149,6 +187,14 @@ module Arel
149
187
  WHERE "users"."id" = 1
150
188
  })
151
189
  end
190
+
191
+ adapter_is :oracle do
192
+ @update.to_sql.should be_like(%Q{
193
+ UPDATE "USERS"
194
+ SET "NAME" = 'nick'
195
+ WHERE "USERS"."ID" = 1
196
+ })
197
+ end
152
198
  end
153
199
  end
154
200
  end
@@ -20,7 +20,15 @@ module Arel
20
20
  })
21
21
  end
22
22
 
23
- adapter_is_not :mysql do
23
+ adapter_is :oracle do
24
+ sql.should be_like(%Q{
25
+ SELECT "USERS"."ID", "USERS"."NAME"
26
+ FROM "USERS"
27
+ WHERE "USERS"."ID" = 1
28
+ })
29
+ end
30
+
31
+ adapter_is_not :mysql, :oracle do
24
32
  sql.should be_like(%Q{
25
33
  SELECT "users"."id", "users"."name"
26
34
  FROM "users"
@@ -42,7 +50,15 @@ module Arel
42
50
  })
43
51
  end
44
52
 
45
- adapter_is_not :mysql do
53
+ adapter_is :oracle do
54
+ sql.should be_like(%Q{
55
+ SELECT "USERS"."ID", "USERS"."NAME"
56
+ FROM "USERS"
57
+ WHERE asdf
58
+ })
59
+ end
60
+
61
+ adapter_is_not :mysql, :oracle do
46
62
  sql.should be_like(%Q{
47
63
  SELECT "users"."id", "users"."name"
48
64
  FROM "users"
@@ -0,0 +1,19 @@
1
+ puts "Using native Oracle"
2
+ require "active_record"
3
+ require 'logger'
4
+
5
+ # Prepend oracle_enhanced local development directory in front of load path
6
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../../oracle-enhanced/lib"
7
+
8
+ ActiveRecord::Base.logger = Logger.new("debug.log")
9
+
10
+ ActiveRecord::Base.configurations = {
11
+ 'unit' => {
12
+ :adapter => 'oracle_enhanced',
13
+ :username => 'arel_unit',
14
+ :password => 'arel_unit',
15
+ :database => 'orcl',
16
+ }
17
+ }
18
+
19
+ ActiveRecord::Base.establish_connection 'unit'
@@ -16,7 +16,8 @@ sql = <<-SQL
16
16
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
17
17
  name VARCHAR(255) NOT NULL,
18
18
  salary INTEGER NOT NULL,
19
- department VARCHAR(255) NOT NULL
19
+ department VARCHAR(255) NOT NULL,
20
+ created_at TIMESTAMP NOT NULL
20
21
  );
21
22
  SQL
22
23