activerecord-postgresql-extensions 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/MIT-LICENSE +23 -0
  2. data/README.rdoc +32 -0
  3. data/Rakefile +42 -0
  4. data/VERSION +1 -0
  5. data/lib/activerecord-postgresql-extensions.rb +30 -0
  6. data/lib/postgresql_extensions/foreign_key_associations.rb +367 -0
  7. data/lib/postgresql_extensions/postgresql_adapter_extensions.rb +646 -0
  8. data/lib/postgresql_extensions/postgresql_constraints.rb +579 -0
  9. data/lib/postgresql_extensions/postgresql_functions.rb +345 -0
  10. data/lib/postgresql_extensions/postgresql_geometry.rb +212 -0
  11. data/lib/postgresql_extensions/postgresql_indexes.rb +219 -0
  12. data/lib/postgresql_extensions/postgresql_languages.rb +80 -0
  13. data/lib/postgresql_extensions/postgresql_permissions.rb +322 -0
  14. data/lib/postgresql_extensions/postgresql_rules.rb +112 -0
  15. data/lib/postgresql_extensions/postgresql_schemas.rb +49 -0
  16. data/lib/postgresql_extensions/postgresql_sequences.rb +222 -0
  17. data/lib/postgresql_extensions/postgresql_tables.rb +308 -0
  18. data/lib/postgresql_extensions/postgresql_triggers.rb +131 -0
  19. data/lib/postgresql_extensions/postgresql_types.rb +17 -0
  20. data/lib/postgresql_extensions/postgresql_views.rb +103 -0
  21. data/postgresql-extensions.gemspec +50 -0
  22. data/test/adapter_test.rb +45 -0
  23. data/test/constraints_test.rb +98 -0
  24. data/test/functions_test.rb +112 -0
  25. data/test/geometry_test.rb +43 -0
  26. data/test/index_test.rb +68 -0
  27. data/test/languages_test.rb +48 -0
  28. data/test/permissions_test.rb +163 -0
  29. data/test/rules_test.rb +32 -0
  30. data/test/schemas_test.rb +43 -0
  31. data/test/sequences_test.rb +90 -0
  32. data/test/tables_test.rb +49 -0
  33. data/test/test_helper.rb +64 -0
  34. metadata +97 -0
@@ -0,0 +1,112 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class FunctionsTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_function
9
+ Mig.create_function(:test, :integer, :integer, :sql) do
10
+ "select 10;"
11
+ end
12
+
13
+ Mig.create_function(:test, :integer, :integer, :sql, {
14
+ :force => true,
15
+ :delimiter => '$__$',
16
+ :behavior => :immutable,
17
+ :on_null_input => :strict,
18
+ :cost => 1,
19
+ :rows => 10,
20
+ :set => {
21
+ 'TIME ZONE' => 'America/Halifax'
22
+ }
23
+ }) do
24
+ "return 10;"
25
+ end
26
+
27
+ assert_equal([
28
+ %{CREATE FUNCTION "test"(integer) RETURNS integer AS $$
29
+ select 10;
30
+ $$
31
+ LANGUAGE "sql"},
32
+
33
+ %{CREATE OR REPLACE FUNCTION "test"(integer) RETURNS integer AS $__$
34
+ return 10;
35
+ $__$
36
+ LANGUAGE "sql"
37
+ IMMUTABLE
38
+ STRICT
39
+ COST 1
40
+ ROWS 10
41
+ SET TIME ZONE "America/Halifax"}
42
+ ], statements)
43
+ end
44
+
45
+ def test_drop_function
46
+ Mig.drop_function(:test, :integer)
47
+ Mig.drop_function(:test, :integer, :if_exists => true, :cascade => true)
48
+
49
+ assert_equal([
50
+ "DROP FUNCTION \"test\"(integer)",
51
+ "DROP FUNCTION IF EXISTS \"test\"(integer) CASCADE"
52
+ ], statements)
53
+ end
54
+
55
+ def test_rename_function
56
+ Mig.rename_function(:test, 'integer, text', :foo)
57
+
58
+ assert_equal([
59
+ "ALTER FUNCTION \"test\"(integer, text) RENAME TO \"foo\""
60
+ ], statements)
61
+ end
62
+
63
+ def test_alter_function_owner
64
+ Mig.alter_function_owner(:test, 'integer, text', :admin)
65
+
66
+ assert_equal([
67
+ "ALTER FUNCTION \"test\"(integer, text) OWNER TO \"admin\""
68
+ ], statements)
69
+ end
70
+
71
+ def test_alter_function_schema
72
+ Mig.alter_function_schema(:test, 'integer, text', :geospatial)
73
+
74
+ assert_equal([
75
+ "ALTER FUNCTION \"test\"(integer, text) SET SCHEMA \"geospatial\""
76
+ ], statements)
77
+ end
78
+
79
+ def test_alter_function
80
+ Mig.alter_function('my_function', 'integer', :rename_to => 'another_function')
81
+ Mig.alter_function('another_function', 'integer', :owner_to => 'jdoe')
82
+ Mig.alter_function('my_function', 'integer') do |f|
83
+ f.rename_to 'another_function'
84
+ f.owner_to 'jdoe'
85
+ f.set_schema 'foo'
86
+ f.behavior 'immutable'
87
+ f.security 'invoker'
88
+ f.cost 10
89
+ f.rows 10
90
+ f.set({
91
+ :log_duration => 0.4
92
+ })
93
+ f.reset :all
94
+ f.reset %w{ debug_assertions trace_notify }
95
+ end
96
+
97
+ assert_equal([
98
+ %{ALTER FUNCTION "my_function"(integer) RENAME TO "another_function"},
99
+ %{ALTER FUNCTION "another_function"(integer) OWNER TO "jdoe"},
100
+ %{ALTER FUNCTION "my_function"(integer) RENAME TO "another_function";
101
+ ALTER FUNCTION "another_function"(integer) OWNER TO "jdoe";
102
+ ALTER FUNCTION "another_function"(integer) SET SCHEMA "foo";
103
+ ALTER FUNCTION "another_function"(integer) IMMUTABLE;
104
+ ALTER FUNCTION "another_function"(integer) SECURITY INVOKER;
105
+ ALTER FUNCTION "another_function"(integer) COST 10;
106
+ ALTER FUNCTION "another_function"(integer) ROWS 10;
107
+ ALTER FUNCTION "another_function"(integer) SET "log_duration" TO "0.4";
108
+ ALTER FUNCTION "another_function"(integer) RESET ALL;
109
+ ALTER FUNCTION "another_function"(integer) RESET "debug_assertions" RESET "trace_notify"}
110
+ ], statements)
111
+ end
112
+ end
@@ -0,0 +1,43 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class GeometryTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_geometry
9
+ Mig.create_table(:foo) do |t|
10
+ t.geometry :the_geom, :srid => 4326
11
+ end
12
+
13
+ assert_equal([
14
+ %{CREATE TABLE "foo" (
15
+ "id" serial primary key,
16
+ "the_geom" geometry,
17
+ CONSTRAINT "enforce_srid_the_geom" CHECK (srid("the_geom") = (4326)),
18
+ CONSTRAINT "enforce_dims_the_geom" CHECK (ndims("the_geom") = 2)
19
+ )},
20
+ %{DELETE FROM "geometry_columns" WHERE f_table_catalog = '' AND f_table_schema = 'public' AND f_table_name = 'foo' AND f_geometry_column = 'the_geom'},
21
+ %{INSERT INTO "geometry_columns" VALUES ('', 'public', 'foo', 'the_geom', 2, 4326, 'geometry')},
22
+ %{CREATE INDEX "foo_the_geom_gist_index" ON "foo" USING "gist"("the_geom")}
23
+ ], statements)
24
+ end
25
+
26
+ def test_create_geometry_with_schema
27
+ Mig.create_table('public.foo') do |t|
28
+ t.geometry :the_geom, :srid => 4326
29
+ end
30
+
31
+ assert_equal([
32
+ %{CREATE TABLE "public"."foo" (
33
+ "id" serial primary key,
34
+ "the_geom" geometry,
35
+ CONSTRAINT "enforce_srid_the_geom" CHECK (srid("the_geom") = (4326)),
36
+ CONSTRAINT "enforce_dims_the_geom" CHECK (ndims("the_geom") = 2)
37
+ )},
38
+ %{DELETE FROM "geometry_columns" WHERE f_table_catalog = '' AND f_table_schema = 'public' AND f_table_name = 'foo' AND f_geometry_column = 'the_geom'},
39
+ %{INSERT INTO "geometry_columns" VALUES ('', 'public', 'foo', 'the_geom', 2, 4326, 'geometry')},
40
+ %{CREATE INDEX "foo_the_geom_gist_index" ON "foo" USING "gist"("the_geom")}
41
+ ], statements)
42
+ end
43
+ end
@@ -0,0 +1,68 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class IndexTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_index
9
+ Mig.create_index(:foo_names_idx, :foo, [ :first_name, :last_name ])
10
+ Mig.create_index(:foo_bar_id_idx, :foo, :column => :bar_id)
11
+ Mig.create_index(:foo_coalesce_bar_id_idx, :foo, :expression => 'COALESCE(bar_id, 0)')
12
+ Mig.create_index(:foo_search_idx, :foo, :search, :using => :gin)
13
+
14
+ Mig.create_index(:foo_names_idx, :foo, {
15
+ :column => :name,
16
+ :opclass => 'text_pattern_ops'
17
+ })
18
+
19
+ Mig.create_index(:foo_bar_id_idx, :foo, {
20
+ :column => :bar_id,
21
+ :order => :asc,
22
+ :nulls => :last
23
+ }, {
24
+ :fill_factor => 10,
25
+ :unique => true,
26
+ :concurrently => true,
27
+ :tablespace => 'fubar',
28
+ :conditions => 'bar_id IS NOT NULL'
29
+ })
30
+
31
+ assert_equal([
32
+ "CREATE INDEX \"foo_names_idx\" ON \"foo\"(\"first_name\", \"last_name\")",
33
+ "CREATE INDEX \"foo_bar_id_idx\" ON \"foo\"(\"bar_id\")",
34
+ "CREATE INDEX \"foo_coalesce_bar_id_idx\" ON \"foo\"((COALESCE(bar_id, 0)))",
35
+ "CREATE INDEX \"foo_search_idx\" ON \"foo\" USING \"gin\"(\"search\")",
36
+ "CREATE INDEX \"foo_names_idx\" ON \"foo\"(\"name\" \"text_pattern_ops\")",
37
+ "CREATE UNIQUE INDEX CONCURRENTLY \"foo_bar_id_idx\" ON \"foo\"(\"bar_id\" ASC NULLS LAST) WITH (FILLFACTOR = 10) TABLESPACE \"fubar\" WHERE bar_id IS NOT NULL"
38
+ ], statements)
39
+ end
40
+
41
+ def test_drop_index
42
+ Mig.drop_index(:foo_names_idx)
43
+ Mig.drop_index(:foo_names_idx, :if_exists => true)
44
+ Mig.drop_index(:foo_names_idx, :cascade => true)
45
+
46
+ assert_equal([
47
+ "DROP INDEX \"foo_names_idx\"",
48
+ "DROP INDEX IF EXISTS \"foo_names_idx\"",
49
+ "DROP INDEX \"foo_names_idx\" CASCADE"
50
+ ], statements)
51
+ end
52
+
53
+ def test_rename_index
54
+ Mig.rename_index(:foo_names_idx, :foo_renamed_idx)
55
+
56
+ assert_equal([
57
+ "ALTER INDEX \"foo_names_idx\" RENAME TO \"foo_renamed_idx\""
58
+ ], statements)
59
+ end
60
+
61
+ def test_alter_index_tablespace
62
+ Mig.alter_index_tablespace(:foo_names_idx, :fubar)
63
+
64
+ assert_equal([
65
+ "ALTER INDEX \"foo_names_idx\" SET TABLESPACE \"fubar\""
66
+ ], statements)
67
+ end
68
+ end
@@ -0,0 +1,48 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class LanguagesTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_language
9
+ Mig.create_language(:foo)
10
+ Mig.create_language(
11
+ :foo,
12
+ :trusted => true,
13
+ :call_handler => 'plpgsql',
14
+ :validator => 'test()'
15
+ )
16
+
17
+ assert_equal([
18
+ "CREATE PROCEDURAL LANGUAGE \"foo\"",
19
+ "CREATE TRUSTED PROCEDURAL LANGUAGE \"foo\" HANDLER \"plpgsql\" VALIDATOR test()"
20
+ ], statements)
21
+ end
22
+
23
+ def test_drop_language
24
+ Mig.drop_language(:foo)
25
+ Mig.drop_language(:foo, :if_exists => true, :cascade => true)
26
+
27
+ assert_equal([
28
+ "DROP PROCEDURAL LANGUAGE \"foo\"",
29
+ "DROP PROCEDURAL LANGUAGE IF EXISTS \"foo\" CASCADE"
30
+ ], statements)
31
+ end
32
+
33
+ def test_alter_language_name
34
+ Mig.alter_language_name(:foo, :bar)
35
+
36
+ assert_equal([
37
+ "ALTER PROCEDURAL LANGUAGE \"foo\" RENAME TO \"bar\""
38
+ ], statements)
39
+ end
40
+
41
+ def test_alter_language_owner
42
+ Mig.alter_language_owner(:foo, :bar)
43
+
44
+ assert_equal([
45
+ "ALTER PROCEDURAL LANGUAGE \"foo\" OWNER TO \"bar\""
46
+ ], statements)
47
+ end
48
+ end
@@ -0,0 +1,163 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class PermissionsTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_grant_table_privileges
9
+ Mig.grant_table_privileges(:foo, :select, :nobody)
10
+ Mig.grant_table_privileges(:foo, [ :select, :update, :delete, :insert ], [ :nobody, :somebody ])
11
+ Mig.grant_table_privileges(:foo, :select, :nobody, :with_grant_option => true)
12
+ Mig.grant_table_privileges(:foo, :select, :nobody, :cascade => true)
13
+ Mig.grant_table_privileges(:foo, :select, :public, :cascade => true)
14
+
15
+ assert_equal([
16
+ "GRANT SELECT ON TABLE \"foo\" TO \"nobody\"",
17
+ "GRANT SELECT, UPDATE, DELETE, INSERT ON TABLE \"foo\" TO \"nobody\", \"somebody\"",
18
+ "GRANT SELECT ON TABLE \"foo\" TO \"nobody\" WITH GRANT OPTION",
19
+ "GRANT SELECT ON TABLE \"foo\" TO \"nobody\"",
20
+ "GRANT SELECT ON TABLE \"foo\" TO PUBLIC"
21
+ ], statements)
22
+ end
23
+
24
+ def test_revoke_table_privileges
25
+ Mig.revoke_table_privileges(:foo, :select, :nobody)
26
+ Mig.revoke_table_privileges(:foo, [ :select, :update, :delete, :insert ], [ :nobody, :somebody ])
27
+ Mig.revoke_table_privileges(:foo, :select, :nobody, :with_grant_option => true)
28
+ Mig.revoke_table_privileges(:foo, :select, :nobody, :cascade => true)
29
+ Mig.revoke_table_privileges(:foo, :select, :public, :cascade => true)
30
+
31
+ assert_equal([
32
+ "REVOKE SELECT ON TABLE \"foo\" FROM \"nobody\"",
33
+ "REVOKE SELECT, UPDATE, DELETE, INSERT ON TABLE \"foo\" FROM \"nobody\", \"somebody\"",
34
+ "REVOKE SELECT ON TABLE \"foo\" FROM \"nobody\"",
35
+ "REVOKE SELECT ON TABLE \"foo\" FROM \"nobody\" CASCADE",
36
+ "REVOKE SELECT ON TABLE \"foo\" FROM PUBLIC CASCADE"
37
+ ], statements)
38
+ end
39
+
40
+ def test_grant_sequence_privileges
41
+ Mig.grant_sequence_privileges(:foo, :select, :nobody)
42
+ Mig.grant_sequence_privileges(:foo, [ :select, :update ], [ :nobody, :somebody ])
43
+
44
+ assert_equal([
45
+ "GRANT SELECT ON SEQUENCE \"foo\" TO \"nobody\"",
46
+ "GRANT SELECT, UPDATE ON SEQUENCE \"foo\" TO \"nobody\", \"somebody\""
47
+ ], statements)
48
+ end
49
+
50
+ def test_revoke_sequence_privileges
51
+ Mig.revoke_sequence_privileges(:foo, :select, :nobody)
52
+ Mig.revoke_sequence_privileges(:foo, [ :select, :update ], [ :nobody, :somebody ])
53
+
54
+ assert_equal([
55
+ "REVOKE SELECT ON SEQUENCE \"foo\" FROM \"nobody\"",
56
+ "REVOKE SELECT, UPDATE ON SEQUENCE \"foo\" FROM \"nobody\", \"somebody\""
57
+ ], statements)
58
+ end
59
+
60
+ def test_grant_function_privileges
61
+ Mig.grant_function_privileges('test(text, integer)', :execute, :nobody)
62
+ Mig.grant_function_privileges('test(text, integer)', :all, [ :nobody, :somebody ])
63
+
64
+ assert_equal([
65
+ "GRANT EXECUTE ON FUNCTION test(text, integer) TO \"nobody\"",
66
+ "GRANT ALL ON FUNCTION test(text, integer) TO \"nobody\", \"somebody\""
67
+ ], statements)
68
+ end
69
+
70
+ def test_revoke_function_privileges
71
+ Mig.revoke_function_privileges('test(text, integer)', :execute, :nobody)
72
+ Mig.revoke_function_privileges('test(text, integer)', :all, [ :nobody, :somebody ])
73
+
74
+ assert_equal([
75
+ "REVOKE EXECUTE ON FUNCTION test(text, integer) FROM \"nobody\"",
76
+ "REVOKE ALL ON FUNCTION test(text, integer) FROM \"nobody\", \"somebody\""
77
+ ], statements)
78
+ end
79
+
80
+ def test_grant_language_privileges
81
+ Mig.grant_language_privileges('plpgsql', :usage, :nobody)
82
+ Mig.grant_language_privileges('plpgsql', :all, [ :nobody, :somebody ])
83
+
84
+ assert_equal([
85
+ "GRANT USAGE ON LANGUAGE \"plpgsql\" TO \"nobody\"",
86
+ "GRANT ALL ON LANGUAGE \"plpgsql\" TO \"nobody\", \"somebody\""
87
+ ], statements)
88
+ end
89
+
90
+ def test_revoke_language_privileges
91
+ Mig.revoke_language_privileges('plpgsql', :usage, :nobody)
92
+ Mig.revoke_language_privileges('plpgsql', :all, [ :nobody, :somebody ])
93
+
94
+ assert_equal([
95
+ "REVOKE USAGE ON LANGUAGE \"plpgsql\" FROM \"nobody\"",
96
+ "REVOKE ALL ON LANGUAGE \"plpgsql\" FROM \"nobody\", \"somebody\""
97
+ ], statements)
98
+ end
99
+
100
+ def test_grant_schema_privileges
101
+ Mig.grant_schema_privileges(:foo, :usage, :nobody)
102
+ Mig.grant_schema_privileges(:foo, :all, [ :nobody, :somebody ])
103
+
104
+ assert_equal([
105
+ "GRANT USAGE ON SCHEMA \"foo\" TO \"nobody\"",
106
+ "GRANT ALL ON SCHEMA \"foo\" TO \"nobody\", \"somebody\""
107
+ ], statements)
108
+ end
109
+
110
+ def test_revoke_schema_privileges
111
+ Mig.revoke_schema_privileges(:foo, :usage, :nobody)
112
+ Mig.revoke_schema_privileges(:foo, :all, [ :nobody, :somebody ])
113
+
114
+ assert_equal([
115
+ "REVOKE USAGE ON SCHEMA \"foo\" FROM \"nobody\"",
116
+ "REVOKE ALL ON SCHEMA \"foo\" FROM \"nobody\", \"somebody\""
117
+ ], statements)
118
+ end
119
+
120
+ def test_grant_tablespace_privileges
121
+ Mig.grant_tablespace_privileges(:foo, :create, :nobody)
122
+ Mig.grant_tablespace_privileges(:foo, :all, [ :nobody, :somebody ])
123
+
124
+ assert_equal([
125
+ "GRANT CREATE ON TABLESPACE \"foo\" TO \"nobody\"",
126
+ "GRANT ALL ON TABLESPACE \"foo\" TO \"nobody\", \"somebody\""
127
+ ], statements)
128
+ end
129
+
130
+ def test_revoke_tablespace_privileges
131
+ Mig.revoke_tablespace_privileges(:foo, :create, :nobody)
132
+ Mig.revoke_tablespace_privileges(:foo, :all, [ :nobody, :somebody ])
133
+
134
+ assert_equal([
135
+ "REVOKE CREATE ON TABLESPACE \"foo\" FROM \"nobody\"",
136
+ "REVOKE ALL ON TABLESPACE \"foo\" FROM \"nobody\", \"somebody\""
137
+ ], statements)
138
+ end
139
+
140
+ def test_grant_role_membership
141
+ Mig.grant_role_membership(:foo, :nobody)
142
+ Mig.grant_role_membership(:foo, [ :nobody, :somebody ])
143
+ Mig.grant_role_membership(:foo, [ :nobody, :somebody ], :with_admin_option => true)
144
+
145
+ assert_equal([
146
+ "GRANT \"foo\" TO \"nobody\"",
147
+ "GRANT \"foo\" TO \"nobody\", \"somebody\"",
148
+ "GRANT \"foo\" TO \"nobody\", \"somebody\" WITH ADMIN OPTION"
149
+ ], statements)
150
+ end
151
+
152
+ def test_revoke_role_membership
153
+ Mig.revoke_role_membership(:foo, :nobody)
154
+ Mig.revoke_role_membership(:foo, [ :nobody, :somebody ])
155
+ Mig.revoke_role_membership(:foo, [ :nobody, :somebody ], :with_admin_option => true)
156
+
157
+ assert_equal([
158
+ "REVOKE \"foo\" FROM \"nobody\"",
159
+ "REVOKE \"foo\" FROM \"nobody\", \"somebody\"",
160
+ "REVOKE \"foo\" FROM \"nobody\", \"somebody\""
161
+ ], statements)
162
+ end
163
+ end
@@ -0,0 +1,32 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class RulesTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_rule
9
+ Mig.create_rule(
10
+ :ignore_root, :update, :users, :instead, :nothing, :conditions => 'user_id = 0'
11
+ )
12
+ Mig.create_rule(
13
+ :ignore_root, :update, :users, :instead, 'SELECT * FROM non_admins', {
14
+ :force => true,
15
+ :conditions => 'user_id > 0'
16
+ }
17
+ )
18
+
19
+ assert_equal([
20
+ "CREATE RULE \"ignore_root\" AS ON UPDATE TO \"users\" WHERE user_id = 0 DO INSTEAD NOTHING",
21
+ "CREATE OR REPLACE RULE \"ignore_root\" AS ON UPDATE TO \"users\" WHERE user_id > 0 DO INSTEAD SELECT * FROM non_admins"
22
+ ], statements)
23
+ end
24
+
25
+ def test_drop_rule
26
+ Mig.drop_rule(:foo, :bar)
27
+
28
+ assert_equal([
29
+ "DROP RULE \"foo\" ON \"bar\"",
30
+ ], statements)
31
+ end
32
+ end