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