activerecord-postgresql-extensions 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/activerecord-postgresql-extensions.gemspec +7 -4
- data/lib/activerecord-postgresql-extensions.rb +1 -0
- data/lib/postgresql_extensions/postgresql_adapter_extensions.rb +52 -5
- data/lib/postgresql_extensions/postgresql_constraints.rb +3 -3
- data/lib/postgresql_extensions/postgresql_extensions.rb +1 -1
- data/lib/postgresql_extensions/postgresql_functions.rb +3 -3
- data/lib/postgresql_extensions/postgresql_languages.rb +5 -5
- data/lib/postgresql_extensions/postgresql_schemas.rb +6 -6
- data/lib/postgresql_extensions/postgresql_sequences.rb +3 -3
- data/lib/postgresql_extensions/postgresql_tables.rb +16 -8
- data/lib/postgresql_extensions/postgresql_tablespaces.rb +84 -0
- data/lib/postgresql_extensions/postgresql_triggers.rb +24 -0
- data/test/adapter_tests.rb +60 -0
- data/test/tables_tests.rb +75 -0
- data/test/tablespace_tests.rb +63 -0
- data/test/test_helper.rb +3 -0
- data/test/trigger_tests.rb +85 -0
- metadata +6 -3
data/Rakefile
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
|
+
|
6
|
+
gem 'rdoc', '~> 3.12'
|
7
|
+
|
5
8
|
require 'rubygems/package_task'
|
6
9
|
require 'rake/testtask'
|
7
10
|
require 'rdoc/task'
|
@@ -41,7 +44,6 @@ end
|
|
41
44
|
|
42
45
|
desc 'Build docs'
|
43
46
|
Rake::RDocTask.new do |t|
|
44
|
-
require 'rdoc'
|
45
47
|
t.title = "ActiveRecord PostgreSQL Extensions #{version}"
|
46
48
|
t.main = 'README.rdoc'
|
47
49
|
t.rdoc_dir = 'doc'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.12
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "activerecord-postgresql-extensions"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.12"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["J Smith"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2012-03-22"
|
13
13
|
s.description = "A whole bunch of extensions the ActiveRecord PostgreSQL adapter."
|
14
14
|
s.email = "code@zoocasa.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
"lib/postgresql_extensions/postgresql_schemas.rb",
|
37
37
|
"lib/postgresql_extensions/postgresql_sequences.rb",
|
38
38
|
"lib/postgresql_extensions/postgresql_tables.rb",
|
39
|
+
"lib/postgresql_extensions/postgresql_tablespaces.rb",
|
39
40
|
"lib/postgresql_extensions/postgresql_text_search.rb",
|
40
41
|
"lib/postgresql_extensions/postgresql_triggers.rb",
|
41
42
|
"lib/postgresql_extensions/postgresql_types.rb",
|
@@ -53,12 +54,14 @@ Gem::Specification.new do |s|
|
|
53
54
|
"test/schemas_tests.rb",
|
54
55
|
"test/sequences_tests.rb",
|
55
56
|
"test/tables_tests.rb",
|
57
|
+
"test/tablespace_tests.rb",
|
56
58
|
"test/test_helper.rb",
|
57
|
-
"test/text_search_tests.rb"
|
59
|
+
"test/text_search_tests.rb",
|
60
|
+
"test/trigger_tests.rb"
|
58
61
|
]
|
59
62
|
s.homepage = "http://github.com/zoocasa/activerecord-postgresql-extensions"
|
60
63
|
s.require_paths = ["lib"]
|
61
|
-
s.rubygems_version = "1.8.
|
64
|
+
s.rubygems_version = "1.8.15"
|
62
65
|
s.summary = "A whole bunch of extensions the ActiveRecord PostgreSQL adapter."
|
63
66
|
|
64
67
|
if s.respond_to? :specification_version then
|
@@ -66,7 +66,7 @@ module ActiveRecord
|
|
66
66
|
# with_schema :geospatial do
|
67
67
|
# Model.find(:all)
|
68
68
|
# end
|
69
|
-
def with_schema
|
69
|
+
def with_schema(schema)
|
70
70
|
scoped_schemas << schema
|
71
71
|
begin
|
72
72
|
yield
|
@@ -483,17 +483,64 @@ module ActiveRecord
|
|
483
483
|
alias_method_chain :schema_search_path, :csv_fix
|
484
484
|
|
485
485
|
def disable_referential_integrity_with_views #:nodoc:
|
486
|
-
if supports_disable_referential_integrity?
|
487
|
-
execute(
|
486
|
+
if supports_disable_referential_integrity? then
|
487
|
+
execute(tables_without_views.collect { |name|
|
488
|
+
"ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL"
|
489
|
+
}.join(";"))
|
488
490
|
end
|
489
491
|
yield
|
490
492
|
ensure
|
491
|
-
if supports_disable_referential_integrity?
|
492
|
-
execute(
|
493
|
+
if supports_disable_referential_integrity? then
|
494
|
+
execute(tables_without_views.collect { |name|
|
495
|
+
"ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL"
|
496
|
+
}.join(";"))
|
493
497
|
end
|
494
498
|
end
|
495
499
|
alias_method_chain :disable_referential_integrity, :views
|
496
500
|
|
501
|
+
# Enable triggers. If no triggers are specified, all triggers will
|
502
|
+
# be enabled.
|
503
|
+
def enable_triggers(table, *triggers)
|
504
|
+
quoted_table_name = quote_table_name(table)
|
505
|
+
triggers = if triggers.present?
|
506
|
+
triggers.collect { |trigger|
|
507
|
+
quote_generic(trigger)
|
508
|
+
}
|
509
|
+
else
|
510
|
+
'ALL'
|
511
|
+
end
|
512
|
+
|
513
|
+
Array(triggers).each do |trigger|
|
514
|
+
execute("ALTER TABLE #{quoted_table_name} ENABLE TRIGGER #{trigger};")
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
# Disable triggers. If no triggers are specified, all triggers will
|
519
|
+
# be disabled.
|
520
|
+
def disable_triggers(table, *triggers)
|
521
|
+
quoted_table_name = quote_table_name(table)
|
522
|
+
triggers = if triggers.present?
|
523
|
+
triggers.collect { |trigger|
|
524
|
+
quote_generic(trigger)
|
525
|
+
}
|
526
|
+
else
|
527
|
+
'ALL'
|
528
|
+
end
|
529
|
+
|
530
|
+
Array(triggers).each do |trigger|
|
531
|
+
execute("ALTER TABLE #{quoted_table_name} DISABLE TRIGGER #{trigger};")
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
# Temporarily disable triggers. If no triggers are specified, all
|
536
|
+
# triggers will be disabled.
|
537
|
+
def without_triggers(table, *triggers)
|
538
|
+
disable_triggers(table, *triggers)
|
539
|
+
yield
|
540
|
+
ensure
|
541
|
+
enable_triggers(table, *triggers)
|
542
|
+
end
|
543
|
+
|
497
544
|
# Returns an Array of foreign keys for a particular table. The
|
498
545
|
# Array itself is an Array of Arrays, where each particular Array
|
499
546
|
# contains the table being referenced, the foreign key and the
|
@@ -76,7 +76,7 @@ module ActiveRecord
|
|
76
76
|
private
|
77
77
|
DEFERRABLE_TYPES = [ 'true', 'false', 'immediate', 'deferred' ].freeze
|
78
78
|
def assert_valid_deferrable_option option
|
79
|
-
if !DEFERRABLE_TYPES.include?
|
79
|
+
if !DEFERRABLE_TYPES.include?(option.to_s.downcase)
|
80
80
|
raise ActiveRecord::InvalidDeferrableOption.new(option)
|
81
81
|
end unless option.nil?
|
82
82
|
end
|
@@ -553,13 +553,13 @@ module ActiveRecord
|
|
553
553
|
ACTION_TYPES = %w{ no_action restrict cascade set_null set_default }.freeze
|
554
554
|
|
555
555
|
def assert_valid_match_type(type) #:nodoc:
|
556
|
-
if !MATCH_TYPES.include?
|
556
|
+
if !MATCH_TYPES.include?(type.to_s)
|
557
557
|
raise ActiveRecord::InvalidMatchType.new(type)
|
558
558
|
end
|
559
559
|
end
|
560
560
|
|
561
561
|
def assert_valid_action(type) #:nodoc:
|
562
|
-
if !ACTION_TYPES.include?
|
562
|
+
if !ACTION_TYPES.include?(type.to_s)
|
563
563
|
raise ActiveRecord::InvalidForeignKeyAction.new(type)
|
564
564
|
end
|
565
565
|
end
|
@@ -221,7 +221,7 @@ module ActiveRecord
|
|
221
221
|
end
|
222
222
|
|
223
223
|
def assert_valid_action(option) #:nodoc:
|
224
|
-
if !ACTIONS.include?
|
224
|
+
if !ACTIONS.include?(option.to_s.downcase)
|
225
225
|
raise ArgumentError.new("Excepted :add or :drop for PostgreSQLExtensionAlterer action.")
|
226
226
|
end unless option.nil?
|
227
227
|
end
|
@@ -194,19 +194,19 @@ module ActiveRecord
|
|
194
194
|
SECURITIES = %w{ invoker definer }.freeze
|
195
195
|
|
196
196
|
def assert_valid_behavior(option) #:nodoc:
|
197
|
-
if !BEHAVIORS.include?
|
197
|
+
if !BEHAVIORS.include?(option.to_s.downcase)
|
198
198
|
raise ActiveRecord::InvalidFunctionBehavior.new(option)
|
199
199
|
end unless option.nil?
|
200
200
|
end
|
201
201
|
|
202
202
|
def assert_valid_on_null_input(option) #:nodoc:
|
203
|
-
if !ON_NULL_INPUTS.include?
|
203
|
+
if !ON_NULL_INPUTS.include?(option.to_s.downcase)
|
204
204
|
raise ActiveRecord::InvalidFunctionOnNullInputValue.new(option)
|
205
205
|
end unless option.nil?
|
206
206
|
end
|
207
207
|
|
208
208
|
def assert_valid_security(option) #:nodoc:
|
209
|
-
if !SECURITIES.include?
|
209
|
+
if !SECURITIES.include?(option.to_s.downcase)
|
210
210
|
raise ActiveRecord::InvalidFunctionSecurityValue.new(option)
|
211
211
|
end unless option.nil?
|
212
212
|
end
|
@@ -31,7 +31,7 @@ module ActiveRecord
|
|
31
31
|
# You don't often see people using the <tt>:handler</tt> and
|
32
32
|
# <tt>:validator</tt> options, and they're really just kind of
|
33
33
|
# here for the sake of completeness.
|
34
|
-
def create_language
|
34
|
+
def create_language(language, options = {})
|
35
35
|
sql = 'CREATE '
|
36
36
|
sql << 'TRUSTED ' if options[:trusted]
|
37
37
|
sql << "PROCEDURAL LANGUAGE #{quote_language(language)}"
|
@@ -46,7 +46,7 @@ module ActiveRecord
|
|
46
46
|
#
|
47
47
|
# * <tt>:if_exists</tt> - adds IF EXISTS.
|
48
48
|
# * <tt>:cascade</tt> - adds CASCADE.
|
49
|
-
def drop_language
|
49
|
+
def drop_language(language, options = {})
|
50
50
|
sql = 'DROP PROCEDURAL LANGUAGE '
|
51
51
|
sql << 'IF EXISTS ' if options[:if_exists]
|
52
52
|
sql << quote_language(language)
|
@@ -55,13 +55,13 @@ module ActiveRecord
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Renames a language.
|
58
|
-
def alter_language_name
|
58
|
+
def alter_language_name(old_language, new_language, options = {})
|
59
59
|
execute "ALTER PROCEDURAL LANGUAGE #{quote_language(old_language)} RENAME TO #{quote_language(new_language)};"
|
60
60
|
end
|
61
61
|
|
62
62
|
# Changes a language's owner.
|
63
|
-
def alter_language_owner
|
64
|
-
execute "ALTER PROCEDURAL LANGUAGE #{quote_language(language)} OWNER TO #{
|
63
|
+
def alter_language_owner(language, role, options = {})
|
64
|
+
execute "ALTER PROCEDURAL LANGUAGE #{quote_language(language)} OWNER TO #{quote_role(role)};"
|
65
65
|
end
|
66
66
|
|
67
67
|
# Returns an Array of available languages.
|
@@ -15,7 +15,7 @@ module ActiveRecord
|
|
15
15
|
# * <tt>:authorization</tt> - adds an AUTHORIZATION clause. This is
|
16
16
|
# used to set the owner of the schema. This can be changed with
|
17
17
|
# alter_schema_owner as necessary.
|
18
|
-
def create_schema
|
18
|
+
def create_schema(schema, options = {})
|
19
19
|
sql = "CREATE SCHEMA #{quote_schema(schema)}"
|
20
20
|
sql << " AUTHORIZATION #{quote_role(options[:authorization])}" if options[:authorization]
|
21
21
|
execute("#{sql};")
|
@@ -27,7 +27,7 @@ module ActiveRecord
|
|
27
27
|
#
|
28
28
|
# * <tt>:if_exists</tt> - adds IF EXISTS.
|
29
29
|
# * <tt>:cascade</tt> - adds CASCADE.
|
30
|
-
def drop_schema
|
30
|
+
def drop_schema(schemas, options = {})
|
31
31
|
sql = 'DROP SCHEMA '
|
32
32
|
sql << 'IF EXISTS ' if options[:if_exists]
|
33
33
|
sql << Array(schemas).collect { |s| quote_schema(s) }.join(', ')
|
@@ -36,13 +36,13 @@ module ActiveRecord
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# Alter's a schema's name.
|
39
|
-
def alter_schema_name
|
40
|
-
execute
|
39
|
+
def alter_schema_name(old_schema, new_schema)
|
40
|
+
execute("ALTER SCHEMA #{quote_schema(old_schema)} RENAME TO #{quote_schema(new_schema)};")
|
41
41
|
end
|
42
42
|
|
43
43
|
# Changes a schema's owner.
|
44
|
-
def alter_schema_owner
|
45
|
-
execute
|
44
|
+
def alter_schema_owner(schema, role)
|
45
|
+
execute("ALTER SCHEMA #{quote_schema(schema)} OWNER TO #{quote_role(role)};")
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -73,12 +73,12 @@ module ActiveRecord
|
|
73
73
|
|
74
74
|
# Renames the sequence.
|
75
75
|
def rename_sequence(name, rename, options = {})
|
76
|
-
execute
|
76
|
+
execute("ALTER SEQUENCE #{quote_sequence(name)} RENAME TO #{quote_generic_ignore_schema(rename)};")
|
77
77
|
end
|
78
78
|
|
79
79
|
# Alters the sequence's schema.
|
80
80
|
def alter_sequence_schema(name, schema, options = {})
|
81
|
-
execute
|
81
|
+
execute("ALTER SEQUENCE #{quote_sequence(name)} SET SCHEMA #{quote_schema(schema)};")
|
82
82
|
end
|
83
83
|
|
84
84
|
# Alters any of the various options for a sequence. See
|
@@ -90,7 +90,7 @@ module ActiveRecord
|
|
90
90
|
# function <tt>setval</tt> with a false value in the third
|
91
91
|
# parameter.
|
92
92
|
def alter_sequence(name, options = {})
|
93
|
-
execute
|
93
|
+
execute(PostgreSQLSequenceDefinition.new(self, :alter, name, options).to_s)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Calls the <tt>setval</tt> function on the sequence.
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
module ConnectionAdapters
|
13
13
|
class PostgreSQLAdapter < AbstractAdapter
|
14
14
|
# Set the schema of a table.
|
15
|
-
def alter_table_schema
|
15
|
+
def alter_table_schema(table_name, schema, options = {})
|
16
16
|
execute "ALTER TABLE #{quote_schema(table_name)} SET SCHEMA #{quote_schema(schema)};"
|
17
17
|
end
|
18
18
|
|
@@ -46,6 +46,9 @@ module ActiveRecord
|
|
46
46
|
# * <tt>:cascade_drop</tt> - when using the <tt>:force</tt>, this
|
47
47
|
# Jedi mindtrick will pass along the :cascade option to
|
48
48
|
# drop_table.
|
49
|
+
# * <tt>:of_type</tt> - for "OF type_name" clauses.
|
50
|
+
# * <tt>:if_not_exists</tt> - adds the "IF NOT EXISTS" clause.
|
51
|
+
# * <tt>:unlogged</tt> - creates an UNLOGGED table.
|
49
52
|
#
|
50
53
|
# We're expanding the doors of table definition perception with
|
51
54
|
# this exciting new addition to the world of ActiveRecord
|
@@ -102,7 +105,7 @@ module ActiveRecord
|
|
102
105
|
end
|
103
106
|
|
104
107
|
table_definition = PostgreSQLTableDefinition.new(self, table_name, options)
|
105
|
-
yield table_definition
|
108
|
+
yield table_definition if block_given?
|
106
109
|
|
107
110
|
execute table_definition.to_s
|
108
111
|
unless table_definition.post_processing.blank?
|
@@ -182,7 +185,12 @@ module ActiveRecord
|
|
182
185
|
def to_sql #:nodoc:
|
183
186
|
sql = 'CREATE '
|
184
187
|
sql << 'TEMPORARY ' if options[:temporary]
|
185
|
-
sql <<
|
188
|
+
sql << 'UNLOGGED ' if options[:unlogged]
|
189
|
+
sql << 'TABLE '
|
190
|
+
sql << 'IF NOT EXISTS ' if options[:if_not_exists]
|
191
|
+
sql << "#{base.quote_table_name(table_name)} "
|
192
|
+
sql << "OF #{base.quote_table_name(options[:of_type])} " if options[:of_type]
|
193
|
+
sql << "(\n "
|
186
194
|
|
187
195
|
ary = @columns.collect(&:to_sql)
|
188
196
|
ary << @like if @like
|
@@ -190,10 +198,10 @@ module ActiveRecord
|
|
190
198
|
sql << ary * ",\n "
|
191
199
|
sql << "\n)"
|
192
200
|
|
193
|
-
sql << "
|
194
|
-
sql << "
|
195
|
-
sql << "#{options[:options]}" if options[:options]
|
196
|
-
sql << "
|
201
|
+
sql << "\nINHERITS (" << Array(options[:inherits]).collect { |i| base.quote_table_name(i) }.join(', ') << ')' if options[:inherits]
|
202
|
+
sql << "\nON COMMIT #{options[:on_commit].to_s.upcase.gsub(/_/, ' ')}" if options[:on_commit]
|
203
|
+
sql << "\n#{options[:options]}" if options[:options]
|
204
|
+
sql << "\nTABLESPACE #{base.quote_tablespace(options[:tablespace])}" if options[:tablespace]
|
197
205
|
"#{sql};"
|
198
206
|
end
|
199
207
|
alias :to_s :to_sql
|
@@ -292,7 +300,7 @@ module ActiveRecord
|
|
292
300
|
alias_method_chain :column, :constraints
|
293
301
|
|
294
302
|
private
|
295
|
-
LIKE_TYPES =
|
303
|
+
LIKE_TYPES = %w{ defaults constraints indexes }.freeze
|
296
304
|
|
297
305
|
def assert_valid_like_types(likes) #:nodoc:
|
298
306
|
unless likes.blank?
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
class InvalidTablespaceParameter < ActiveRecordError #:nodoc:
|
6
|
+
def initialize(parameter)
|
7
|
+
super("Invalid tablespace parameter - #{parameter}")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ConnectionAdapters
|
12
|
+
class PostgreSQLAdapter < AbstractAdapter
|
13
|
+
# Creates a new PostgreSQL tablespace.
|
14
|
+
def create_tablespace(name, location, options = {})
|
15
|
+
sql = "CREATE TABLESPACE #{quote_tablespace(name)} "
|
16
|
+
sql << "OWNER #{quote_role(options[:owner])} " if options[:owner]
|
17
|
+
sql << "LOCATION #{quote(location)}"
|
18
|
+
|
19
|
+
execute("#{sql};")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Drops a tablespace.
|
23
|
+
#
|
24
|
+
# ==== Options
|
25
|
+
#
|
26
|
+
# * <tt>:if_exists</tt> - adds IF EXISTS.
|
27
|
+
def drop_tablespace(name, options = {})
|
28
|
+
sql = 'DROP TABLESPACE '
|
29
|
+
sql << 'IF EXISTS ' if options[:if_exists]
|
30
|
+
sql << quote_tablespace(name)
|
31
|
+
|
32
|
+
execute("#{sql};")
|
33
|
+
end
|
34
|
+
|
35
|
+
#ALTER TABLESPACE name SET ( tablespace_option = value [, ... ] )
|
36
|
+
#ALTER TABLESPACE name RESET ( tablespace_option [, ... ] )
|
37
|
+
|
38
|
+
# Renames a tablespace.
|
39
|
+
def rename_tablespace(old_name, new_name)
|
40
|
+
execute("ALTER TABLESPACE #{quote_tablespace(old_name)} RENAME TO #{quote_tablespace(new_name)};")
|
41
|
+
end
|
42
|
+
|
43
|
+
# Changes a tablespace's owner.
|
44
|
+
def alter_tablespace_owner(tablespace, role)
|
45
|
+
execute("ALTER TABLESPACE #{quote_tablespace(tablespace)} OWNER TO #{quote_role(role)};")
|
46
|
+
end
|
47
|
+
|
48
|
+
def alter_tablespace_parameters(tablespace, parameters_and_values)
|
49
|
+
sql = "ALTER TABLESPACE #{quote_tablespace(tablespace)} SET ("
|
50
|
+
|
51
|
+
sql << parameters_and_values.collect { |k, v|
|
52
|
+
assert_valid_tablespace_parameter(k)
|
53
|
+
"\n #{quote_generic(k)} = #{v}"
|
54
|
+
}.join(",")
|
55
|
+
|
56
|
+
sql << "\n);"
|
57
|
+
|
58
|
+
execute(sql)
|
59
|
+
end
|
60
|
+
|
61
|
+
def reset_tablespace_parameters(tablespace, *parameters)
|
62
|
+
sql = "ALTER TABLESPACE #{quote_tablespace(tablespace)} RESET ("
|
63
|
+
|
64
|
+
sql << parameters.flatten.collect { |k|
|
65
|
+
assert_valid_tablespace_parameter(k)
|
66
|
+
"\n #{quote_generic(k)}"
|
67
|
+
}.join(",")
|
68
|
+
|
69
|
+
sql << "\n);"
|
70
|
+
|
71
|
+
execute(sql)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
TABLESPACE_PARAMETERS = %w{ seq_page_cost random_page_cost }.freeze
|
76
|
+
|
77
|
+
def assert_valid_tablespace_parameter(parameter)
|
78
|
+
if !TABLESPACE_PARAMETERS.include? parameter.to_s.downcase
|
79
|
+
raise ActiveRecord::InvalidTablespaceParameter.new(option)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -14,6 +14,30 @@ module ActiveRecord
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
class Base
|
18
|
+
class << self
|
19
|
+
# Enable triggers. If no triggers are specified, all triggers will
|
20
|
+
# be enabled.
|
21
|
+
def enable_triggers(*triggers)
|
22
|
+
self.connection.enable_triggers(self.table_name, *triggers)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Disable triggers. If no triggers are specified, all triggers will
|
26
|
+
# be disabled.
|
27
|
+
def disable_triggers(*triggers)
|
28
|
+
self.connection.disable_triggers(self.table_name, *triggers)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Temporarily disable triggers. If no triggers are specified, all
|
32
|
+
# triggers will be disabled.
|
33
|
+
def without_triggers(*triggers)
|
34
|
+
self.connection.without_triggers(self.table_name, *triggers) do
|
35
|
+
yield
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
17
41
|
module ConnectionAdapters
|
18
42
|
class PostgreSQLAdapter < AbstractAdapter
|
19
43
|
# Creates a PostgreSQL trigger.
|
data/test/adapter_tests.rb
CHANGED
@@ -81,4 +81,64 @@ class AdapterExtensionTests < Test::Unit::TestCase
|
|
81
81
|
'SELECT current_role;'
|
82
82
|
], ARBC.statements)
|
83
83
|
end
|
84
|
+
|
85
|
+
def test_enable_triggers
|
86
|
+
ARBC.enable_triggers(:foo)
|
87
|
+
ARBC.enable_triggers(:foo, :bar)
|
88
|
+
ARBC.enable_triggers(:foo, :bar, :baz)
|
89
|
+
|
90
|
+
assert_equal([
|
91
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER ALL;},
|
92
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
93
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
94
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "baz";}
|
95
|
+
], ARBC.statements)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_disable_triggers
|
99
|
+
ARBC.disable_triggers(:foo)
|
100
|
+
ARBC.disable_triggers(:foo, :bar)
|
101
|
+
ARBC.disable_triggers(:foo, :bar, :baz)
|
102
|
+
|
103
|
+
assert_equal([
|
104
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER ALL;},
|
105
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
106
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
107
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "baz";}
|
108
|
+
], ARBC.statements)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_without_triggers
|
112
|
+
begin
|
113
|
+
ARBC.without_triggers(:foo) do
|
114
|
+
raise "WHAT HAPPEN"
|
115
|
+
end
|
116
|
+
rescue
|
117
|
+
end
|
118
|
+
|
119
|
+
begin
|
120
|
+
ARBC.without_triggers(:foo, :bar) do
|
121
|
+
raise "WHAT HAPPEN"
|
122
|
+
end
|
123
|
+
rescue
|
124
|
+
end
|
125
|
+
|
126
|
+
begin
|
127
|
+
ARBC.without_triggers(:foo, :bar, :baz) do
|
128
|
+
raise "WHAT HAPPEN"
|
129
|
+
end
|
130
|
+
rescue
|
131
|
+
end
|
132
|
+
|
133
|
+
assert_equal([
|
134
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER ALL;},
|
135
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER ALL;},
|
136
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
137
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
138
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "bar";},
|
139
|
+
%{ALTER TABLE "foo" DISABLE TRIGGER "baz";},
|
140
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "bar";},
|
141
|
+
%{ALTER TABLE "foo" ENABLE TRIGGER "baz";}
|
142
|
+
], ARBC.statements)
|
143
|
+
end
|
84
144
|
end
|
data/test/tables_tests.rb
CHANGED
@@ -46,4 +46,79 @@ class TablesTests < Test::Unit::TestCase
|
|
46
46
|
"bar_id" integer DEFAULT '1 + 1'
|
47
47
|
);} ], statements)
|
48
48
|
end
|
49
|
+
|
50
|
+
def test_like
|
51
|
+
Mig.create_table('foo') do |t|
|
52
|
+
t.like :bar,
|
53
|
+
:including => %w{ constraints indexes},
|
54
|
+
:excluding => %w{ storage comments }
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal([
|
58
|
+
%{CREATE TABLE "foo" (
|
59
|
+
"id" serial primary key,
|
60
|
+
LIKE "bar" INCLUDING CONSTRAINTS INCLUDING INDEXES EXCLUDING STORAGE EXCLUDING COMMENTS
|
61
|
+
);}
|
62
|
+
], statements)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_option_unlogged
|
66
|
+
Mig.create_table('foo', :unlogged => true)
|
67
|
+
|
68
|
+
assert_equal([
|
69
|
+
%{CREATE UNLOGGED TABLE "foo" (\n "id" serial primary key\n);}
|
70
|
+
], statements)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_option_temporary
|
74
|
+
Mig.create_table('foo', :temporary => true)
|
75
|
+
|
76
|
+
assert_equal([
|
77
|
+
%{CREATE TEMPORARY TABLE "foo" (\n "id" serial primary key\n);}
|
78
|
+
], statements)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_option_if_not_exists
|
82
|
+
Mig.create_table('foo', :if_not_exists => true)
|
83
|
+
|
84
|
+
assert_equal([
|
85
|
+
%{CREATE TABLE IF NOT EXISTS "foo" (\n "id" serial primary key\n);}
|
86
|
+
], statements)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_option_on_commit
|
90
|
+
Mig.create_table('foo', :on_commit => :preserve_rows)
|
91
|
+
Mig.create_table('foo', :on_commit => :delete_rows)
|
92
|
+
Mig.create_table('foo', :on_commit => :drop)
|
93
|
+
|
94
|
+
assert_equal([
|
95
|
+
%{CREATE TABLE "foo" (\n "id" serial primary key\n)\nON COMMIT PRESERVE ROWS;},
|
96
|
+
%{CREATE TABLE "foo" (\n "id" serial primary key\n)\nON COMMIT DELETE ROWS;},
|
97
|
+
%{CREATE TABLE "foo" (\n "id" serial primary key\n)\nON COMMIT DROP;}
|
98
|
+
], statements)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_option_inherits
|
102
|
+
Mig.create_table('foo', :inherits => 'bar')
|
103
|
+
|
104
|
+
assert_equal([
|
105
|
+
%{CREATE TABLE "foo" (\n "id" serial primary key\n)\nINHERITS ("bar");}
|
106
|
+
], statements)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_option_tablespace
|
110
|
+
Mig.create_table('foo', :tablespace => 'bar')
|
111
|
+
|
112
|
+
assert_equal([
|
113
|
+
%{CREATE TABLE "foo" (\n "id" serial primary key\n)\nTABLESPACE "bar";}
|
114
|
+
], statements)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_option_of_type
|
118
|
+
Mig.create_table('foo', :of_type => 'bar')
|
119
|
+
|
120
|
+
assert_equal([
|
121
|
+
%{CREATE TABLE "foo" OF "bar" (\n "id" serial primary key\n);}
|
122
|
+
], statements)
|
123
|
+
end
|
49
124
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
$: << File.dirname(__FILE__)
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TablespaceTests < Test::Unit::TestCase
|
6
|
+
include PostgreSQLExtensionsTestHelper
|
7
|
+
|
8
|
+
def test_create_tablespace
|
9
|
+
Mig.create_tablespace('foo', '/tmp/foo')
|
10
|
+
Mig.create_tablespace('foo', '/tmp/foo', :owner => :bar)
|
11
|
+
|
12
|
+
assert_equal([
|
13
|
+
%{CREATE TABLESPACE "foo" LOCATION '/tmp/foo';},
|
14
|
+
%{CREATE TABLESPACE "foo" OWNER "bar" LOCATION '/tmp/foo';}
|
15
|
+
], statements)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_drop_tablespace
|
19
|
+
Mig.drop_tablespace('foo')
|
20
|
+
Mig.drop_tablespace('foo', :if_exists => true)
|
21
|
+
|
22
|
+
assert_equal([
|
23
|
+
%{DROP TABLESPACE "foo";},
|
24
|
+
%{DROP TABLESPACE IF EXISTS "foo";}
|
25
|
+
], statements)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_rename_tablespace
|
29
|
+
Mig.rename_tablespace('foo', 'bar')
|
30
|
+
|
31
|
+
assert_equal([
|
32
|
+
%{ALTER TABLESPACE "foo" RENAME TO "bar";}
|
33
|
+
], statements)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_alter_tablespace_owner
|
37
|
+
Mig.alter_tablespace_owner('foo', 'bar')
|
38
|
+
|
39
|
+
assert_equal([
|
40
|
+
%{ALTER TABLESPACE "foo" OWNER TO "bar";}
|
41
|
+
], statements)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_alter_tablespace_paramters
|
45
|
+
Mig.alter_tablespace_parameters('foo', :seq_page_cost => 2.0, :random_page_cost => 5.0)
|
46
|
+
|
47
|
+
assert_equal([
|
48
|
+
%{ALTER TABLESPACE "foo" SET (
|
49
|
+
"seq_page_cost" = 2.0,
|
50
|
+
"random_page_cost" = 5.0
|
51
|
+
);} ], statements)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_reset_tablespace_paramters
|
55
|
+
Mig.reset_tablespace_parameters('foo', :seq_page_cost, :random_page_cost)
|
56
|
+
|
57
|
+
assert_equal([
|
58
|
+
%{ALTER TABLESPACE "foo" RESET (
|
59
|
+
"seq_page_cost",
|
60
|
+
"random_page_cost"
|
61
|
+
);} ], statements)
|
62
|
+
end
|
63
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
$: << File.dirname(__FILE__)
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TriggerTests < Test::Unit::TestCase
|
6
|
+
include PostgreSQLExtensionsTestHelper
|
7
|
+
|
8
|
+
def test_enable_triggers
|
9
|
+
Foo.enable_triggers
|
10
|
+
Foo.enable_triggers(:bar)
|
11
|
+
Foo.enable_triggers(:bar, :baz)
|
12
|
+
|
13
|
+
assert_equal([
|
14
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER ALL;},
|
15
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "bar";},
|
16
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "bar";},
|
17
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "baz";}
|
18
|
+
], ARBC.statements)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_disable_triggers
|
22
|
+
Foo.disable_triggers
|
23
|
+
Foo.disable_triggers(:bar)
|
24
|
+
Foo.disable_triggers(:bar, :baz)
|
25
|
+
|
26
|
+
assert_equal([
|
27
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER ALL;},
|
28
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "bar";},
|
29
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "bar";},
|
30
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "baz";}
|
31
|
+
], ARBC.statements)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_without_triggers
|
35
|
+
begin
|
36
|
+
Foo.without_triggers do
|
37
|
+
raise "WHAT HAPPEN"
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
end
|
41
|
+
|
42
|
+
begin
|
43
|
+
Foo.without_triggers(:bar) do
|
44
|
+
raise "WHAT HAPPEN"
|
45
|
+
end
|
46
|
+
rescue
|
47
|
+
end
|
48
|
+
|
49
|
+
begin
|
50
|
+
Foo.without_triggers(:bar, :baz) do
|
51
|
+
raise "WHAT HAPPEN"
|
52
|
+
end
|
53
|
+
rescue
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal([
|
57
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER ALL;},
|
58
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER ALL;},
|
59
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "bar";},
|
60
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "bar";},
|
61
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "bar";},
|
62
|
+
%{ALTER TABLE "foos" DISABLE TRIGGER "baz";},
|
63
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "bar";},
|
64
|
+
%{ALTER TABLE "foos" ENABLE TRIGGER "baz";}
|
65
|
+
], ARBC.statements)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_create_trigger # (name, called, events, table, function, options = {})
|
69
|
+
ARBC.create_trigger(:foo, :before, :update, :bar, 'do_it', :for_each => :row)
|
70
|
+
|
71
|
+
assert_equal([
|
72
|
+
%{CREATE TRIGGER "foo" BEFORE UPDATE ON "bar" FOR EACH ROW EXECUTE PROCEDURE "do_it"();}
|
73
|
+
], ARBC.statements)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_drop_trigger # (name, table, options = {})
|
77
|
+
ARBC.drop_trigger(:bar, :foo)
|
78
|
+
ARBC.drop_trigger(:bar, :foo, :if_exists => true, :cascade => true)
|
79
|
+
|
80
|
+
assert_equal([
|
81
|
+
%{DROP TRIGGER "bar" ON "foo";},
|
82
|
+
%{DROP TRIGGER IF EXISTS "bar" ON "foo" CASCADE;}
|
83
|
+
], ARBC.statements)
|
84
|
+
end
|
85
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-postgresql-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-03-22 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A whole bunch of extensions the ActiveRecord PostgreSQL adapter.
|
15
15
|
email: code@zoocasa.com
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- lib/postgresql_extensions/postgresql_schemas.rb
|
39
39
|
- lib/postgresql_extensions/postgresql_sequences.rb
|
40
40
|
- lib/postgresql_extensions/postgresql_tables.rb
|
41
|
+
- lib/postgresql_extensions/postgresql_tablespaces.rb
|
41
42
|
- lib/postgresql_extensions/postgresql_text_search.rb
|
42
43
|
- lib/postgresql_extensions/postgresql_triggers.rb
|
43
44
|
- lib/postgresql_extensions/postgresql_types.rb
|
@@ -55,8 +56,10 @@ files:
|
|
55
56
|
- test/schemas_tests.rb
|
56
57
|
- test/sequences_tests.rb
|
57
58
|
- test/tables_tests.rb
|
59
|
+
- test/tablespace_tests.rb
|
58
60
|
- test/test_helper.rb
|
59
61
|
- test/text_search_tests.rb
|
62
|
+
- test/trigger_tests.rb
|
60
63
|
homepage: http://github.com/zoocasa/activerecord-postgresql-extensions
|
61
64
|
licenses: []
|
62
65
|
post_install_message:
|
@@ -77,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
80
|
version: '0'
|
78
81
|
requirements: []
|
79
82
|
rubyforge_project:
|
80
|
-
rubygems_version: 1.8.
|
83
|
+
rubygems_version: 1.8.15
|
81
84
|
signing_key:
|
82
85
|
specification_version: 3
|
83
86
|
summary: A whole bunch of extensions the ActiveRecord PostgreSQL adapter.
|