activerecord-postgresql-extensions 0.0.12 → 0.1.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.
- 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
|