activerecord-postgresql-extensions 0.0.12 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -2
- data/Rakefile +4 -17
- data/activerecord-postgresql-extensions.gemspec +13 -57
- data/lib/{postgresql_extensions/postgresql_adapter_extensions.rb → active_record/postgresql_extensions/adapter_extensions.rb} +44 -46
- data/lib/{postgresql_extensions/postgresql_constraints.rb → active_record/postgresql_extensions/constraints.rb} +121 -10
- data/lib/{postgresql_extensions/postgresql_extensions.rb → active_record/postgresql_extensions/extensions.rb} +1 -1
- data/lib/{postgresql_extensions → active_record/postgresql_extensions}/foreign_key_associations.rb +9 -1
- data/lib/{postgresql_extensions/postgresql_functions.rb → active_record/postgresql_extensions/functions.rb} +9 -3
- data/lib/{postgresql_extensions/postgresql_geometry.rb → active_record/postgresql_extensions/geometry.rb} +111 -35
- data/lib/{postgresql_extensions/postgresql_indexes.rb → active_record/postgresql_extensions/indexes.rb} +4 -2
- data/lib/{postgresql_extensions/postgresql_languages.rb → active_record/postgresql_extensions/languages.rb} +1 -1
- data/lib/{postgresql_extensions/postgresql_permissions.rb → active_record/postgresql_extensions/permissions.rb} +3 -3
- data/lib/active_record/postgresql_extensions/postgis.rb +53 -0
- data/lib/{postgresql_extensions/postgresql_roles.rb → active_record/postgresql_extensions/roles.rb} +1 -1
- data/lib/{postgresql_extensions/postgresql_rules.rb → active_record/postgresql_extensions/rules.rb} +3 -3
- data/lib/{postgresql_extensions/postgresql_schemas.rb → active_record/postgresql_extensions/schemas.rb} +1 -1
- data/lib/{postgresql_extensions/postgresql_sequences.rb → active_record/postgresql_extensions/sequences.rb} +2 -2
- data/lib/{postgresql_extensions/postgresql_tables.rb → active_record/postgresql_extensions/tables.rb} +18 -4
- data/lib/{postgresql_extensions/postgresql_tablespaces.rb → active_record/postgresql_extensions/tablespaces.rb} +1 -1
- data/lib/{postgresql_extensions/postgresql_text_search.rb → active_record/postgresql_extensions/text_search.rb} +3 -3
- data/lib/{postgresql_extensions/postgresql_triggers.rb → active_record/postgresql_extensions/triggers.rb} +1 -1
- data/lib/{postgresql_extensions/postgresql_types.rb → active_record/postgresql_extensions/types.rb} +1 -1
- data/lib/active_record/postgresql_extensions/utils.rb +23 -0
- data/lib/active_record/postgresql_extensions/version.rb +7 -0
- data/lib/{postgresql_extensions/postgresql_views.rb → active_record/postgresql_extensions/views.rb} +2 -2
- data/lib/activerecord-postgresql-extensions.rb +23 -22
- data/test/adapter_tests.rb +9 -9
- data/test/constraints_tests.rb +155 -0
- data/test/database.yml +17 -0
- data/test/geometry_tests.rb +224 -52
- data/test/index_tests.rb +16 -1
- data/test/rules_tests.rb +4 -4
- data/test/sequences_tests.rb +0 -22
- data/test/tables_tests.rb +28 -31
- data/test/test_helper.rb +70 -23
- data/test/trigger_tests.rb +5 -5
- metadata +112 -25
- data/VERSION +0 -1
data/lib/{postgresql_extensions/postgresql_rules.rb → active_record/postgresql_extensions/rules.rb}
RENAMED
@@ -15,7 +15,7 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module ConnectionAdapters
|
18
|
-
class PostgreSQLAdapter
|
18
|
+
class PostgreSQLAdapter
|
19
19
|
# Creates a PostgreSQL rule.
|
20
20
|
#
|
21
21
|
# +event+ can be one of <tt>:select</tt>, <tt>:insert</tt>,
|
@@ -33,7 +33,7 @@ module ActiveRecord
|
|
33
33
|
# * <tt>:force</tt> - add an <tt>OR REPLACE</tt> clause to the
|
34
34
|
# command.
|
35
35
|
# * <tt>:conditions</tt> - a <tt>WHERE</tt> clause to limit the
|
36
|
-
# rule.
|
36
|
+
# rule. Alternatively, you can also use the <tt>:where</tt> option.
|
37
37
|
#
|
38
38
|
# ==== Examples
|
39
39
|
#
|
@@ -79,7 +79,7 @@ module ActiveRecord
|
|
79
79
|
sql = 'CREATE '
|
80
80
|
sql << ' OR REPLACE ' if options[:force]
|
81
81
|
sql << "RULE #{base.quote_rule(name)} AS ON #{event.to_s.upcase} TO #{base.quote_table_name(table)} "
|
82
|
-
sql << "WHERE #{options[:conditions]} " if options[:conditions]
|
82
|
+
sql << "WHERE #{options[:conditions] || options[:where]} " if options[:conditions] || options[:where]
|
83
83
|
sql << "DO #{action.to_s.upcase} "
|
84
84
|
sql << if commands.to_s.upcase == 'NOTHING'
|
85
85
|
'NOTHING'
|
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/postgresql_adapter'
|
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
|
-
class PostgreSQLAdapter
|
6
|
+
class PostgreSQLAdapter
|
7
7
|
# Creates a new PostgreSQL schema.
|
8
8
|
#
|
9
9
|
# Note that you can grant privileges on schemas using the
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
end
|
13
13
|
|
14
14
|
module ConnectionAdapters
|
15
|
-
class PostgreSQLAdapter
|
15
|
+
class PostgreSQLAdapter
|
16
16
|
# Creates a sequence.
|
17
17
|
#
|
18
18
|
# Note that you can grant privileges on sequences using the
|
@@ -73,7 +73,7 @@ module ActiveRecord
|
|
73
73
|
|
74
74
|
# Renames the sequence.
|
75
75
|
def rename_sequence(name, rename, options = {})
|
76
|
-
execute("ALTER SEQUENCE #{quote_sequence(name)} RENAME TO #{
|
76
|
+
execute("ALTER SEQUENCE #{quote_sequence(name)} RENAME TO #{quote_generic_ignore_scoped_schema(rename)};")
|
77
77
|
end
|
78
78
|
|
79
79
|
# Alters the sequence's schema.
|
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
3
|
+
|
2
4
|
module ActiveRecord
|
3
5
|
class InvalidLikeTypes < ActiveRecordError #:nodoc:
|
4
6
|
def initialize(likes)
|
@@ -10,7 +12,7 @@ module ActiveRecord
|
|
10
12
|
end
|
11
13
|
|
12
14
|
module ConnectionAdapters
|
13
|
-
class PostgreSQLAdapter
|
15
|
+
class PostgreSQLAdapter
|
14
16
|
# Set the schema of a table.
|
15
17
|
def alter_table_schema(table_name, schema, options = {})
|
16
18
|
execute "ALTER TABLE #{quote_schema(table_name)} SET SCHEMA #{quote_schema(schema)};"
|
@@ -142,7 +144,7 @@ module ActiveRecord
|
|
142
144
|
# capabilities. You can still access the original method via
|
143
145
|
# original_rename_table.
|
144
146
|
def rename_table(name, new_name, options = {})
|
145
|
-
execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{
|
147
|
+
execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_generic_ignore_scoped_schema(new_name)};"
|
146
148
|
end
|
147
149
|
|
148
150
|
private
|
@@ -193,7 +195,7 @@ module ActiveRecord
|
|
193
195
|
sql << "(\n "
|
194
196
|
|
195
197
|
ary = @columns.collect(&:to_sql)
|
196
|
-
ary << @like if @like
|
198
|
+
ary << @like if defined?(@like) && @like
|
197
199
|
ary << @table_constraints unless @table_constraints.empty?
|
198
200
|
sql << ary * ",\n "
|
199
201
|
sql << "\n)"
|
@@ -257,6 +259,12 @@ module ActiveRecord
|
|
257
259
|
@table_constraints << PostgreSQLForeignKeyConstraint.new(@base, columns, ref_table, *args)
|
258
260
|
end
|
259
261
|
|
262
|
+
# Add an EXCLUDE constraint to the table. See PostgreSQLExcludeConstraint
|
263
|
+
# for more details.
|
264
|
+
def exclude(excludes, options = {})
|
265
|
+
@table_constraints << PostgreSQLExcludeConstraint.new(@base, table_name, excludes, options)
|
266
|
+
end
|
267
|
+
|
260
268
|
def column_with_constraints(name, type, *args) #:nodoc:
|
261
269
|
options = args.extract_options!
|
262
270
|
check = options.delete(:check)
|
@@ -265,7 +273,13 @@ module ActiveRecord
|
|
265
273
|
column_without_constraints(name, type, options)
|
266
274
|
|
267
275
|
if check
|
268
|
-
|
276
|
+
check = if !check.is_a?(Array)
|
277
|
+
[ check ]
|
278
|
+
else
|
279
|
+
check
|
280
|
+
end
|
281
|
+
|
282
|
+
@table_constraints << check.collect do |c|
|
269
283
|
if c.is_a?(Hash)
|
270
284
|
PostgreSQLCheckConstraint.new(@base, c.delete(:expression), c)
|
271
285
|
else
|
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module ConnectionAdapters
|
12
|
-
class PostgreSQLAdapter
|
12
|
+
class PostgreSQLAdapter
|
13
13
|
# Creates a new PostgreSQL tablespace.
|
14
14
|
def create_tablespace(name, location, options = {})
|
15
15
|
sql = "CREATE TABLESPACE #{quote_tablespace(name)} "
|
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/postgresql_adapter'
|
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
|
-
class PostgreSQLAdapter
|
6
|
+
class PostgreSQLAdapter
|
7
7
|
# Creates a new PostgreSQL text search configuration. You must provide
|
8
8
|
# either a :parser_name or a :source_config option as per the PostgreSQL
|
9
9
|
# text search docs.
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
|
17
17
|
sql = "CREATE TEXT SEARCH CONFIGURATION #{quote_generic_with_schema(name)} ("
|
18
18
|
|
19
|
-
|
19
|
+
ignore_scoped_schema do
|
20
20
|
sql << if options[:parser_name]
|
21
21
|
"PARSER = #{quote_generic_with_schema(options[:parser_name])}"
|
22
22
|
else
|
@@ -110,7 +110,7 @@ module ActiveRecord
|
|
110
110
|
execute("#{sql};")
|
111
111
|
end
|
112
112
|
|
113
|
-
|
113
|
+
def rename_text_search_configuration(old_name, new_name)
|
114
114
|
execute("ALTER TEXT SEARCH CONFIGURATION %s RENAME TO %s;" % [
|
115
115
|
quote_generic_with_schema(old_name),
|
116
116
|
quote_generic_with_schema(new_name)
|
data/lib/{postgresql_extensions/postgresql_types.rb → active_record/postgresql_extensions/types.rb}
RENAMED
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/postgresql_adapter'
|
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
|
-
class PostgreSQLAdapter
|
6
|
+
class PostgreSQLAdapter
|
7
7
|
# Returns an Array of available languages.
|
8
8
|
def types(name = nil)
|
9
9
|
query(%{SELECT typname FROM pg_type;}, name).map { |row| row[0] }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module ActiveRecord
|
3
|
+
module PostgreSQLExtensions
|
4
|
+
module Utils
|
5
|
+
class << self
|
6
|
+
def hash_or_array_of_hashes(arg)
|
7
|
+
case arg
|
8
|
+
when Hash
|
9
|
+
[ arg ]
|
10
|
+
when Array
|
11
|
+
if arg.detect { |e| !e.is_a?(Hash) }
|
12
|
+
raise ArgumentError.new("Expected an Array of Hashes")
|
13
|
+
else
|
14
|
+
arg
|
15
|
+
end
|
16
|
+
else
|
17
|
+
raise ArgumentError.new("Expected either a Hash or an Array of Hashes")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/{postgresql_extensions/postgresql_views.rb → active_record/postgresql_extensions/views.rb}
RENAMED
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/postgresql_adapter'
|
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
|
-
class PostgreSQLAdapter
|
6
|
+
class PostgreSQLAdapter
|
7
7
|
# Creates a new PostgreSQL view.
|
8
8
|
#
|
9
9
|
# +name+ is the name of the view. View quoting works the same as
|
@@ -59,7 +59,7 @@ module ActiveRecord
|
|
59
59
|
|
60
60
|
# Renames a view.
|
61
61
|
def rename_view(name, new_name, options = {})
|
62
|
-
execute "ALTER TABLE #{quote_view_name(name)} RENAME TO #{
|
62
|
+
execute "ALTER TABLE #{quote_view_name(name)} RENAME TO #{quote_generic_ignore_scoped_schema(new_name)};"
|
63
63
|
end
|
64
64
|
|
65
65
|
# Change the ownership of a view.
|
@@ -1,34 +1,35 @@
|
|
1
1
|
|
2
2
|
require 'active_record/connection_adapters/postgresql_adapter'
|
3
3
|
|
4
|
-
module
|
4
|
+
module ActiveRecord
|
5
|
+
module PostgreSQLExtensions
|
6
|
+
end
|
5
7
|
end
|
6
8
|
|
7
|
-
dirname = File.join(File.dirname(__FILE__),
|
9
|
+
dirname = File.join(File.dirname(__FILE__), *%w{ active_record postgresql_extensions })
|
8
10
|
|
9
11
|
%w{
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
adapter_extensions
|
13
|
+
constraints
|
14
|
+
tables
|
15
|
+
tablespaces
|
16
|
+
indexes
|
17
|
+
permissions
|
18
|
+
schemas
|
19
|
+
languages
|
20
|
+
rules
|
21
|
+
functions
|
22
|
+
sequences
|
23
|
+
triggers
|
24
|
+
views
|
25
|
+
geometry
|
26
|
+
types
|
27
|
+
roles
|
28
|
+
text_search
|
29
|
+
extensions
|
28
30
|
foreign_key_associations
|
29
31
|
}.each do |file|
|
30
32
|
require File.join(dirname, file)
|
31
33
|
end
|
32
34
|
|
33
|
-
ActiveRecord::Base.send(:include, PostgreSQLExtensions::
|
34
|
-
|
35
|
+
ActiveRecord::Base.send(:include, ActiveRecord::PostgreSQLExtensions::ForeignKeyAssociations)
|
data/test/adapter_tests.rb
CHANGED
@@ -13,15 +13,15 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
13
13
|
assert_equal(%{"foo"."bar"}, ARBC.quote_table_name(:foo => :bar))
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def test_quote_table_name_with_current_scoped_schema
|
17
17
|
assert_equal(%{"foo"."bar"}, ARBC.with_schema(:foo) {
|
18
18
|
ARBC.quote_table_name(:bar)
|
19
19
|
})
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def test_quote_table_name_with_current_scoped_schema_ignored
|
23
23
|
assert_equal(%{"bar"}, ARBC.with_schema(:foo) {
|
24
|
-
ARBC.
|
24
|
+
ARBC.ignore_scoped_schema {
|
25
25
|
ARBC.quote_table_name(:bar)
|
26
26
|
}
|
27
27
|
})
|
@@ -60,7 +60,7 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
60
60
|
%{SET ROLE "foo";},
|
61
61
|
%{SET LOCAL ROLE "foo";},
|
62
62
|
%{SET SESSION ROLE "foo";}
|
63
|
-
],
|
63
|
+
], statements)
|
64
64
|
|
65
65
|
assert_raise(ArgumentError) do
|
66
66
|
ARBC.set_role('foo', :duration => :nonsense)
|
@@ -69,7 +69,7 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
69
69
|
|
70
70
|
def test_reset_role
|
71
71
|
ARBC.reset_role
|
72
|
-
assert_equal([ 'RESET ROLE;' ],
|
72
|
+
assert_equal([ 'RESET ROLE;' ], statements)
|
73
73
|
end
|
74
74
|
|
75
75
|
def test_current_role
|
@@ -79,7 +79,7 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
79
79
|
assert_equal([
|
80
80
|
'SELECT current_role;',
|
81
81
|
'SELECT current_role;'
|
82
|
-
],
|
82
|
+
], statements)
|
83
83
|
end
|
84
84
|
|
85
85
|
def test_enable_triggers
|
@@ -92,7 +92,7 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
92
92
|
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
93
93
|
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
94
94
|
%{ALTER TABLE "foo" ENABLE TRIGGER "baz";}
|
95
|
-
],
|
95
|
+
], statements)
|
96
96
|
end
|
97
97
|
|
98
98
|
def test_disable_triggers
|
@@ -105,7 +105,7 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
105
105
|
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
106
106
|
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
107
107
|
%{ALTER TABLE "foo" DISABLE TRIGGER "baz";}
|
108
|
-
],
|
108
|
+
], statements)
|
109
109
|
end
|
110
110
|
|
111
111
|
def test_without_triggers
|
@@ -139,6 +139,6 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
139
139
|
%{ALTER TABLE "foo" DISABLE TRIGGER "baz";},
|
140
140
|
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
141
141
|
%{ALTER TABLE "foo" ENABLE TRIGGER "baz";}
|
142
|
-
],
|
142
|
+
], statements)
|
143
143
|
end
|
144
144
|
end
|
data/test/constraints_tests.rb
CHANGED
@@ -60,6 +60,52 @@ EOF
|
|
60
60
|
], statements)
|
61
61
|
end
|
62
62
|
|
63
|
+
def test_foreign_key_in_column_definition
|
64
|
+
Mig.create_table('foo') do |t|
|
65
|
+
t.integer :foo_id, :references => {
|
66
|
+
:table => :foo,
|
67
|
+
:on_delete => :set_null,
|
68
|
+
:on_update => :cascade
|
69
|
+
}
|
70
|
+
|
71
|
+
t.integer :bar_id, :references => :bar
|
72
|
+
|
73
|
+
t.integer :baz_id, :references => [ :baz ]
|
74
|
+
end
|
75
|
+
|
76
|
+
assert_equal([
|
77
|
+
%{CREATE TABLE "foo" (
|
78
|
+
"id" serial primary key,
|
79
|
+
"foo_id" integer,
|
80
|
+
"bar_id" integer,
|
81
|
+
"baz_id" integer,
|
82
|
+
FOREIGN KEY ("foo_id") REFERENCES "foo" ON DELETE SET NULL ON UPDATE CASCADE,
|
83
|
+
FOREIGN KEY ("bar_id") REFERENCES "bar",
|
84
|
+
FOREIGN KEY ("baz_id") REFERENCES "baz"
|
85
|
+
);} ], statements)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_foreign_key_in_table_definition
|
89
|
+
Mig.create_table('foo') do |t|
|
90
|
+
t.integer :schabba_id
|
91
|
+
t.integer :doo_id
|
92
|
+
|
93
|
+
t.foreign_key :schabba_id, :bar
|
94
|
+
t.foreign_key :doo_id, :baz
|
95
|
+
t.foreign_key [ :schabba_id, :doo_id ], :bar, [ :schabba_id, :doo_id ]
|
96
|
+
end
|
97
|
+
|
98
|
+
assert_equal([
|
99
|
+
%{CREATE TABLE "foo" (
|
100
|
+
"id" serial primary key,
|
101
|
+
"schabba_id" integer,
|
102
|
+
"doo_id" integer,
|
103
|
+
FOREIGN KEY ("schabba_id") REFERENCES "bar",
|
104
|
+
FOREIGN KEY ("doo_id") REFERENCES "baz",
|
105
|
+
FOREIGN KEY ("schabba_id", "doo_id") REFERENCES "bar" ("schabba_id", "doo_id")
|
106
|
+
);} ], statements)
|
107
|
+
end
|
108
|
+
|
63
109
|
def test_add_foreign_key
|
64
110
|
Mig.add_foreign_key(:foo, :bar_id, :bar)
|
65
111
|
Mig.add_foreign_key(:foo, :bar_id, :bar, :ogc_fid, :name => 'bar_fk')
|
@@ -86,6 +132,56 @@ EOF
|
|
86
132
|
], statements)
|
87
133
|
end
|
88
134
|
|
135
|
+
def test_check_constraint_in_column_definition
|
136
|
+
Mig.create_table('foo') do |t|
|
137
|
+
t.integer :foo_id, :check => "foo_id != 1"
|
138
|
+
t.integer :bar_id, :check => { :expression => "bar_id != 1", :name => "bar_id_not_1" }
|
139
|
+
t.integer :baz_id, :check => [ "baz_id != 1", {
|
140
|
+
:expression => "baz_id > 10",
|
141
|
+
:name => "baz_id_gt_10"
|
142
|
+
} ]
|
143
|
+
end
|
144
|
+
|
145
|
+
assert_equal([
|
146
|
+
%{CREATE TABLE "foo" (
|
147
|
+
"id" serial primary key,
|
148
|
+
"foo_id" integer,
|
149
|
+
"bar_id" integer,
|
150
|
+
"baz_id" integer,
|
151
|
+
CHECK (foo_id != 1),
|
152
|
+
CONSTRAINT "bar_id_not_1" CHECK (bar_id != 1),
|
153
|
+
CHECK (baz_id != 1),
|
154
|
+
CONSTRAINT "baz_id_gt_10" CHECK (baz_id > 10)
|
155
|
+
);} ], statements)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_check_constraint_in_table_definition
|
159
|
+
Mig.create_table('foo') do |t|
|
160
|
+
t.integer :foo_id
|
161
|
+
t.integer :bar_id
|
162
|
+
t.integer :baz_id
|
163
|
+
|
164
|
+
t.check_constraint "foo_id != 1"
|
165
|
+
t.check_constraint "bar_id != 1", :name => "bar_id_not_1"
|
166
|
+
t.check_constraint "baz_id != 1"
|
167
|
+
t.check_constraint "baz_id > 10", {
|
168
|
+
:name => "baz_id_gt_10"
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
assert_equal([
|
173
|
+
%{CREATE TABLE "foo" (
|
174
|
+
"id" serial primary key,
|
175
|
+
"foo_id" integer,
|
176
|
+
"bar_id" integer,
|
177
|
+
"baz_id" integer,
|
178
|
+
CHECK (foo_id != 1),
|
179
|
+
CONSTRAINT "bar_id_not_1" CHECK (bar_id != 1),
|
180
|
+
CHECK (baz_id != 1),
|
181
|
+
CONSTRAINT "baz_id_gt_10" CHECK (baz_id > 10)
|
182
|
+
);} ], statements)
|
183
|
+
end
|
184
|
+
|
89
185
|
def test_add_check_constraint
|
90
186
|
Mig.add_check_constraint(:foo, 'length(name) < 100')
|
91
187
|
Mig.add_check_constraint(:foo, 'length(name) < 100', :name => 'name_length_check')
|
@@ -95,4 +191,63 @@ EOF
|
|
95
191
|
"ALTER TABLE \"foo\" ADD CONSTRAINT \"name_length_check\" CHECK (length(name) < 100);"
|
96
192
|
], statements)
|
97
193
|
end
|
194
|
+
|
195
|
+
def test_add_exclude_constraint
|
196
|
+
Mig.add_exclude_constraint(:foo, :element => 'length(name)', :with => '=')
|
197
|
+
|
198
|
+
Mig.add_exclude_constraint(:foo, {
|
199
|
+
:element => 'length(name)',
|
200
|
+
:with => '='
|
201
|
+
}, {
|
202
|
+
:name => 'exclude_name_length'
|
203
|
+
})
|
204
|
+
|
205
|
+
Mig.add_exclude_constraint(:foo, {
|
206
|
+
:element => 'length(name)',
|
207
|
+
:with => '='
|
208
|
+
}, {
|
209
|
+
:name => 'exclude_name_length',
|
210
|
+
:using => :gist
|
211
|
+
})
|
212
|
+
|
213
|
+
Mig.add_exclude_constraint(:foo, [{
|
214
|
+
:element => 'length(name)',
|
215
|
+
:with => '='
|
216
|
+
}, {
|
217
|
+
:element => 'length(title)',
|
218
|
+
:with => '='
|
219
|
+
}])
|
220
|
+
|
221
|
+
Mig.add_exclude_constraint(:foo, {
|
222
|
+
:element => 'length(name)',
|
223
|
+
:with => '='
|
224
|
+
}, {
|
225
|
+
:conditions => Foo.send(:sanitize_sql, {
|
226
|
+
:id => [1,2,3,4]
|
227
|
+
})
|
228
|
+
})
|
229
|
+
|
230
|
+
Mig.add_exclude_constraint(:foo, {
|
231
|
+
:element => 'length(name)',
|
232
|
+
:with => '='
|
233
|
+
}, {
|
234
|
+
:tablespace => 'fubar',
|
235
|
+
:index_parameters => 'FILLFACTOR=10'
|
236
|
+
})
|
237
|
+
|
238
|
+
escaped_array = if ActiveRecord::VERSION::STRING >= "3.0"
|
239
|
+
"(1, 2, 3, 4)"
|
240
|
+
else
|
241
|
+
"(1,2,3,4)"
|
242
|
+
end
|
243
|
+
|
244
|
+
assert_equal([
|
245
|
+
%{ALTER TABLE "foo" ADD EXCLUDE (length(name) WITH =);},
|
246
|
+
%{ALTER TABLE "foo" ADD CONSTRAINT "exclude_name_length" EXCLUDE (length(name) WITH =);},
|
247
|
+
%{ALTER TABLE "foo" ADD CONSTRAINT "exclude_name_length" EXCLUDE USING "gist" (length(name) WITH =);},
|
248
|
+
%{ALTER TABLE "foo" ADD EXCLUDE (length(name) WITH =, length(title) WITH =);},
|
249
|
+
%{ALTER TABLE "foo" ADD EXCLUDE (length(name) WITH =) WHERE ("foos"."id" IN #{escaped_array});},
|
250
|
+
%{ALTER TABLE "foo" ADD EXCLUDE (length(name) WITH =) WITH (FILLFACTOR=10) USING INDEX TABLESPACE "fubar";}
|
251
|
+
], statements)
|
252
|
+
end
|
98
253
|
end
|