activerecord-postgresql-extensions 0.0.9 → 0.0.10

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 CHANGED
@@ -4,7 +4,15 @@
4
4
  require 'rubygems'
5
5
  require 'rubygems/package_task'
6
6
  require 'rake/testtask'
7
- require 'rdoc/task'
7
+ require 'rake/rdoctask'
8
+
9
+ if RUBY_VERSION >= '1.9'
10
+ begin
11
+ gem 'psych'
12
+ rescue Exception => e
13
+ # it's okay, fall back on the bundled psych
14
+ end
15
+ end
8
16
 
9
17
  $:.push 'lib'
10
18
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.0.10
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{activerecord-postgresql-extensions}
8
- s.version = "0.0.9"
7
+ s.name = "activerecord-postgresql-extensions"
8
+ s.version = "0.0.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{J Smith}]
12
- s.date = %q{2011-07-14}
13
- s.description = %q{A whole bunch of extensions the ActiveRecord PostgreSQL adapter.}
14
- s.email = %q{code@zoocasa.com}
11
+ s.authors = ["J Smith"]
12
+ s.date = "2011-10-05"
13
+ s.description = "A whole bunch of extensions the ActiveRecord PostgreSQL adapter."
14
+ s.email = "code@zoocasa.com"
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "lib/postgresql_extensions/postgresql_indexes.rb",
31
31
  "lib/postgresql_extensions/postgresql_languages.rb",
32
32
  "lib/postgresql_extensions/postgresql_permissions.rb",
33
+ "lib/postgresql_extensions/postgresql_roles.rb",
33
34
  "lib/postgresql_extensions/postgresql_rules.rb",
34
35
  "lib/postgresql_extensions/postgresql_schemas.rb",
35
36
  "lib/postgresql_extensions/postgresql_sequences.rb",
@@ -45,16 +46,17 @@ Gem::Specification.new do |s|
45
46
  "test/index_test.rb",
46
47
  "test/languages_test.rb",
47
48
  "test/permissions_test.rb",
49
+ "test/roles_test.rb",
48
50
  "test/rules_test.rb",
49
51
  "test/schemas_test.rb",
50
52
  "test/sequences_test.rb",
51
53
  "test/tables_test.rb",
52
54
  "test/test_helper.rb"
53
55
  ]
54
- s.homepage = %q{http://github.com/zoocasa/activerecord-postgresql-extensions}
55
- s.require_paths = [%q{lib}]
56
- s.rubygems_version = %q{1.8.5}
57
- s.summary = %q{A whole bunch of extensions the ActiveRecord PostgreSQL adapter.}
56
+ s.homepage = "http://github.com/zoocasa/activerecord-postgresql-extensions"
57
+ s.require_paths = ["lib"]
58
+ s.rubygems_version = "1.8.10"
59
+ s.summary = "A whole bunch of extensions the ActiveRecord PostgreSQL adapter."
58
60
 
59
61
  if s.respond_to? :specification_version then
60
62
  s.specification_version = 3
@@ -21,6 +21,7 @@ dirname = File.join(File.dirname(__FILE__), 'postgresql_extensions')
21
21
  postgresql_views
22
22
  postgresql_geometry
23
23
  postgresql_types
24
+ postgresql_roles
24
25
  foreign_key_associations
25
26
  }.each do |file|
26
27
  require File.join(dirname, file)
@@ -426,6 +426,43 @@ module ActiveRecord
426
426
  SQL
427
427
  end
428
428
 
429
+ def roles(name = nil)
430
+ query(<<-SQL, name).map { |row| row[0] }
431
+ SELECT rolname
432
+ FROM pg_roles
433
+ SQL
434
+ end
435
+
436
+ def role_exists?(name)
437
+ roles.include?(name)
438
+ end
439
+
440
+ # Sets the current database role/user. The :duration option can be set to
441
+ # :session or :local as described in the PostgreSQL docs.
442
+ def set_role(role, options = {})
443
+ duration = if options[:duration]
444
+ if [ :session, :local ].include?(options[:duration])
445
+ options[:duration].to_s.upcase
446
+ else
447
+ raise ArgumentError.new("The :duration option must be one of :session or :local.")
448
+ end
449
+ end
450
+
451
+ sql = 'SET '
452
+ sql << "#{duration} " if duration
453
+ sql << "ROLE #{quote_role(role)}"
454
+ execute(sql, "Setting current role")
455
+ end
456
+
457
+ def reset_role
458
+ execute('RESET ROLE')
459
+ end
460
+
461
+ def current_role
462
+ execute('SELECT current_role')
463
+ end
464
+ alias :current_user :current_role
465
+
429
466
  # Returns an Array of tables to ignore.
430
467
  def ignored_tables(name = nil)
431
468
  query(<<-SQL, name).map { |row| row[0] }
@@ -0,0 +1,127 @@
1
+
2
+ require 'active_record/connection_adapters/postgresql_adapter'
3
+
4
+ module ActiveRecord
5
+ class InvalidRoleAction < ActiveRecordError #:nodoc:
6
+ def initialize(action)
7
+ super("Invalid role action - #{action}")
8
+ end
9
+ end
10
+
11
+ module ConnectionAdapters
12
+ class PostgreSQLAdapter < AbstractAdapter
13
+ def create_role(name, options = {})
14
+ execute PostgreSQLRole.new(self, :create, name, options).to_sql
15
+ end
16
+ alias :create_user :create_role
17
+
18
+ def alter_role(name, options = {})
19
+ execute PostgreSQLRole.new(self, :alter, name, options).to_sql
20
+ end
21
+ alias :alter_user :alter_role
22
+
23
+ def drop_role(name, options = {})
24
+ sql = 'DROP ROLE '
25
+ sql << 'IF EXISTS ' if options[:if_exists]
26
+ sql << Array(name).collect { |r| quote_role(r) }.join(', ')
27
+ execute sql
28
+ end
29
+ alias :drop_user :drop_role
30
+ end
31
+
32
+ # This is a base class for PostgreSQLGrantPrivilege and
33
+ # PostgreSQLRevokePrivilege and is not meant to be used directly.
34
+ class PostgreSQLRole
35
+ attr_accessor :base, :action, :name, :options
36
+
37
+ def initialize(base, action, name, options = {}) #:nodoc:
38
+ assert_valid_action(action)
39
+
40
+ @base, @action, @name, @options = base, action, name, options
41
+ end
42
+
43
+ def to_sql #:nodoc:
44
+ sql = Array.new
45
+ if action == :create
46
+ sql << 'CREATE'
47
+ else
48
+ sql << 'ALTER'
49
+ end
50
+ sql << "ROLE #{base.quote_role(name)}"
51
+
52
+ if options[:superuser]
53
+ sql << 'SUPERUSER'
54
+ end
55
+
56
+ if options[:create_db]
57
+ sql << 'CREATEDB'
58
+ end
59
+
60
+ if options[:create_role]
61
+ sql << 'CREATEROLE'
62
+ end
63
+
64
+ if options.has_key?(:inherit) && !options[:inherit]
65
+ sql << 'NOINHERIT'
66
+ end
67
+
68
+ if options[:login]
69
+ sql << 'LOGIN'
70
+ end
71
+
72
+ if options[:connection_limit]
73
+ sql << "CONNECTION LIMIT #{options[:connection_limit].to_i}"
74
+ end
75
+
76
+ if options[:password]
77
+ if options.has_key?(:encrypted_password)
78
+ if options[:encrypted_password]
79
+ sql << 'ENCRYPTED'
80
+ else
81
+ sql << 'UNENCRYPTED'
82
+ end
83
+ end
84
+
85
+ sql << 'PASSWORD'
86
+ sql << base.quote(options[:password])
87
+ end
88
+
89
+ if options[:valid_until]
90
+ sql << 'VALID UNTIL'
91
+ timestamp = case options[:valid_until]
92
+ when Date, Time, DateTime
93
+ options[:valid_until].to_s(:sql)
94
+ else
95
+ options[:valid_until].to_s
96
+ end
97
+ sql << base.quote(timestamp)
98
+ end
99
+
100
+ if options[:in_role].present?
101
+ sql << 'IN ROLE'
102
+ sql << Array(options[:in_role]).collect { |r| base.quote_role(r) }.join(', ')
103
+ end
104
+
105
+ if options[:role].present?
106
+ sql << 'ROLE'
107
+ sql << Array(options[:role]).collect { |r| base.quote_role(r) }.join(', ')
108
+ end
109
+
110
+ if options[:admin].present?
111
+ sql << 'ADMIN'
112
+ sql << Array(options[:admin]).collect { |r| base.quote_role(r) }.join(', ')
113
+ end
114
+
115
+ sql.join(' ')
116
+ end
117
+ alias :to_s :to_sql
118
+
119
+ private
120
+ def assert_valid_action(action) #:nodoc:
121
+ if ![ :create, :alter ].include?(action)
122
+ raise ActiveRecord::InvalidRoleAction.new(action)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
data/test/adapter_test.rb CHANGED
@@ -50,4 +50,35 @@ class AdapterExtensionTests < Test::Unit::TestCase
50
50
  assert_equal(:integer, col.send(:simplified_type, 'integer'))
51
51
  assert_equal(nil, col.send(:simplified_type, 'complete_nonsense'))
52
52
  end
53
+
54
+ def test_set_role
55
+ ARBC.set_role('foo')
56
+ ARBC.set_role('foo', :duration => :local)
57
+ ARBC.set_role('foo', :duration => :session)
58
+
59
+ assert_equal([
60
+ %{SET ROLE "foo"},
61
+ %{SET LOCAL ROLE "foo"},
62
+ %{SET SESSION ROLE "foo"}
63
+ ], ARBC.statements)
64
+
65
+ assert_raise(ArgumentError) do
66
+ ARBC.set_role('foo', :duration => :nonsense)
67
+ end
68
+ end
69
+
70
+ def test_reset_role
71
+ ARBC.reset_role
72
+ assert_equal([ 'RESET ROLE' ], ARBC.statements)
73
+ end
74
+
75
+ def test_current_role
76
+ ARBC.current_role
77
+ ARBC.current_user
78
+
79
+ assert_equal([
80
+ 'SELECT current_role',
81
+ 'SELECT current_role'
82
+ ], ARBC.statements)
83
+ end
53
84
  end
@@ -6,11 +6,11 @@ class FunctionsTests < Test::Unit::TestCase
6
6
  include PostgreSQLExtensionsTestHelper
7
7
 
8
8
  def test_create_function
9
- Mig.create_function(:test, :integer, :integer, :sql) do
9
+ ARBC.create_function(:test, :integer, :integer, :sql) do
10
10
  "select 10;"
11
11
  end
12
12
 
13
- Mig.create_function(:test, :integer, :integer, :sql, {
13
+ ARBC.create_function(:test, :integer, :integer, :sql, {
14
14
  :force => true,
15
15
  :delimiter => '$__$',
16
16
  :behavior => :immutable,
@@ -43,8 +43,8 @@ LANGUAGE "sql"
43
43
  end
44
44
 
45
45
  def test_drop_function
46
- Mig.drop_function(:test, :integer)
47
- Mig.drop_function(:test, :integer, :if_exists => true, :cascade => true)
46
+ ARBC.drop_function(:test, :integer)
47
+ ARBC.drop_function(:test, :integer, :if_exists => true, :cascade => true)
48
48
 
49
49
  assert_equal([
50
50
  "DROP FUNCTION \"test\"(integer)",
@@ -53,7 +53,7 @@ LANGUAGE "sql"
53
53
  end
54
54
 
55
55
  def test_rename_function
56
- Mig.rename_function(:test, 'integer, text', :foo)
56
+ ARBC.rename_function(:test, 'integer, text', :foo)
57
57
 
58
58
  assert_equal([
59
59
  "ALTER FUNCTION \"test\"(integer, text) RENAME TO \"foo\""
@@ -61,7 +61,7 @@ LANGUAGE "sql"
61
61
  end
62
62
 
63
63
  def test_alter_function_owner
64
- Mig.alter_function_owner(:test, 'integer, text', :admin)
64
+ ARBC.alter_function_owner(:test, 'integer, text', :admin)
65
65
 
66
66
  assert_equal([
67
67
  "ALTER FUNCTION \"test\"(integer, text) OWNER TO \"admin\""
@@ -69,7 +69,7 @@ LANGUAGE "sql"
69
69
  end
70
70
 
71
71
  def test_alter_function_schema
72
- Mig.alter_function_schema(:test, 'integer, text', :geospatial)
72
+ ARBC.alter_function_schema(:test, 'integer, text', :geospatial)
73
73
 
74
74
  assert_equal([
75
75
  "ALTER FUNCTION \"test\"(integer, text) SET SCHEMA \"geospatial\""
@@ -77,9 +77,9 @@ LANGUAGE "sql"
77
77
  end
78
78
 
79
79
  def test_alter_function
80
- Mig.alter_function('my_function', 'integer', :rename_to => 'another_function')
81
- Mig.alter_function('another_function', 'integer', :owner_to => 'jdoe')
82
- Mig.alter_function('my_function', 'integer') do |f|
80
+ ARBC.alter_function('my_function', 'integer', :rename_to => 'another_function')
81
+ ARBC.alter_function('another_function', 'integer', :owner_to => 'jdoe')
82
+ ARBC.alter_function('my_function', 'integer') do |f|
83
83
  f.rename_to 'another_function'
84
84
  f.owner_to 'jdoe'
85
85
  f.set_schema 'foo'
@@ -6,8 +6,8 @@ class LanguagesTests < Test::Unit::TestCase
6
6
  include PostgreSQLExtensionsTestHelper
7
7
 
8
8
  def test_create_language
9
- Mig.create_language(:foo)
10
- Mig.create_language(
9
+ ARBC.create_language(:foo)
10
+ ARBC.create_language(
11
11
  :foo,
12
12
  :trusted => true,
13
13
  :call_handler => 'plpgsql',
@@ -21,8 +21,8 @@ class LanguagesTests < Test::Unit::TestCase
21
21
  end
22
22
 
23
23
  def test_drop_language
24
- Mig.drop_language(:foo)
25
- Mig.drop_language(:foo, :if_exists => true, :cascade => true)
24
+ ARBC.drop_language(:foo)
25
+ ARBC.drop_language(:foo, :if_exists => true, :cascade => true)
26
26
 
27
27
  assert_equal([
28
28
  "DROP PROCEDURAL LANGUAGE \"foo\"",
@@ -31,7 +31,7 @@ class LanguagesTests < Test::Unit::TestCase
31
31
  end
32
32
 
33
33
  def test_alter_language_name
34
- Mig.alter_language_name(:foo, :bar)
34
+ ARBC.alter_language_name(:foo, :bar)
35
35
 
36
36
  assert_equal([
37
37
  "ALTER PROCEDURAL LANGUAGE \"foo\" RENAME TO \"bar\""
@@ -39,7 +39,7 @@ class LanguagesTests < Test::Unit::TestCase
39
39
  end
40
40
 
41
41
  def test_alter_language_owner
42
- Mig.alter_language_owner(:foo, :bar)
42
+ ARBC.alter_language_owner(:foo, :bar)
43
43
 
44
44
  assert_equal([
45
45
  "ALTER PROCEDURAL LANGUAGE \"foo\" OWNER TO \"bar\""
@@ -0,0 +1,63 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class RolesTests < Test::Unit::TestCase
6
+ include PostgreSQLExtensionsTestHelper
7
+
8
+ def test_create_role
9
+ ARBC.create_role('foo')
10
+ ARBC.create_role('foo', {
11
+ :superuser => true,
12
+ :create_db => true,
13
+ :create_role => true,
14
+ :inherit => false,
15
+ :login => true,
16
+ :connection_limit => 10,
17
+ :password => 'testing',
18
+ :encrypted_password => true,
19
+ :valid_until => Date.parse('2011-10-12'),
20
+ :in_role => 'bar',
21
+ :role => 'baz',
22
+ :admin => 'blort'
23
+ })
24
+
25
+ assert_equal([
26
+ 'CREATE ROLE "foo"',
27
+ %{CREATE ROLE "foo" SUPERUSER CREATEDB CREATEROLE NOINHERIT LOGIN CONNECTION LIMIT 10 ENCRYPTED PASSWORD 'testing' VALID UNTIL '2011-10-12' IN ROLE "bar" ROLE "baz" ADMIN "blort"}
28
+ ], statements)
29
+ end
30
+
31
+ def test_alter_role
32
+ ARBC.alter_role('foo', {
33
+ :superuser => true,
34
+ :create_db => true,
35
+ :create_role => true,
36
+ :inherit => false,
37
+ :login => true,
38
+ :connection_limit => 10,
39
+ :password => 'testing',
40
+ :encrypted_password => true,
41
+ :valid_until => Date.parse('2011-10-12'),
42
+ :in_role => 'bar',
43
+ :role => 'baz',
44
+ :admin => 'blort'
45
+ })
46
+
47
+ assert_equal([
48
+ %{ALTER ROLE "foo" SUPERUSER CREATEDB CREATEROLE NOINHERIT LOGIN CONNECTION LIMIT 10 ENCRYPTED PASSWORD 'testing' VALID UNTIL '2011-10-12' IN ROLE "bar" ROLE "baz" ADMIN "blort"}
49
+ ], statements)
50
+ end
51
+
52
+ def test_drop_role
53
+ ARBC.drop_role('foo')
54
+ ARBC.drop_role(%w{ foo bar baz })
55
+ ARBC.drop_role(%w{ foo bar baz }, :if_exists => true)
56
+
57
+ assert_equal([
58
+ 'DROP ROLE "foo"',
59
+ 'DROP ROLE "foo", "bar", "baz"',
60
+ 'DROP ROLE IF EXISTS "foo", "bar", "baz"',
61
+ ], statements)
62
+ end
63
+ end
data/test/rules_test.rb CHANGED
@@ -6,10 +6,10 @@ class RulesTests < Test::Unit::TestCase
6
6
  include PostgreSQLExtensionsTestHelper
7
7
 
8
8
  def test_create_rule
9
- Mig.create_rule(
9
+ ARBC.create_rule(
10
10
  :ignore_root, :update, :users, :instead, :nothing, :conditions => 'user_id = 0'
11
11
  )
12
- Mig.create_rule(
12
+ ARBC.create_rule(
13
13
  :ignore_root, :update, :users, :instead, 'SELECT * FROM non_admins', {
14
14
  :force => true,
15
15
  :conditions => 'user_id > 0'
@@ -23,7 +23,7 @@ class RulesTests < Test::Unit::TestCase
23
23
  end
24
24
 
25
25
  def test_drop_rule
26
- Mig.drop_rule(:foo, :bar)
26
+ ARBC.drop_rule(:foo, :bar)
27
27
 
28
28
  assert_equal([
29
29
  "DROP RULE \"foo\" ON \"bar\"",
data/test/test_helper.rb CHANGED
@@ -8,8 +8,6 @@ require 'active_record'
8
8
  require 'test/unit'
9
9
  require File.join(File.dirname(__FILE__), *%w{ .. lib activerecord-postgresql-extensions })
10
10
 
11
- puts "Testing against ActiveRecord #{Gem.loaded_specs['activerecord'].version.to_s}"
12
-
13
11
  ActiveRecord::Base.configurations = {
14
12
  'arunit' => {
15
13
  :adapter => 'postgresql',
@@ -24,6 +22,11 @@ ActiveRecord::Base.establish_connection 'arunit'
24
22
 
25
23
  ARBC = ActiveRecord::Base.connection
26
24
 
25
+ puts "Testing against ActiveRecord #{Gem.loaded_specs['activerecord'].version.to_s}"
26
+ if postgresql_version = ARBC.query('SELECT version()').flatten.to_s
27
+ puts "PostgreSQL info from version(): #{postgresql_version}"
28
+ end
29
+
27
30
  class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
28
31
  def statements
29
32
  @statements ||= []
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.9
4
+ version: 0.0.10
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: 2011-07-14 00:00:00.000000000Z
12
+ date: 2011-10-05 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
@@ -32,6 +32,7 @@ files:
32
32
  - lib/postgresql_extensions/postgresql_indexes.rb
33
33
  - lib/postgresql_extensions/postgresql_languages.rb
34
34
  - lib/postgresql_extensions/postgresql_permissions.rb
35
+ - lib/postgresql_extensions/postgresql_roles.rb
35
36
  - lib/postgresql_extensions/postgresql_rules.rb
36
37
  - lib/postgresql_extensions/postgresql_schemas.rb
37
38
  - lib/postgresql_extensions/postgresql_sequences.rb
@@ -47,6 +48,7 @@ files:
47
48
  - test/index_test.rb
48
49
  - test/languages_test.rb
49
50
  - test/permissions_test.rb
51
+ - test/roles_test.rb
50
52
  - test/rules_test.rb
51
53
  - test/schemas_test.rb
52
54
  - test/sequences_test.rb
@@ -72,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
74
  version: '0'
73
75
  requirements: []
74
76
  rubyforge_project:
75
- rubygems_version: 1.8.5
77
+ rubygems_version: 1.8.10
76
78
  signing_key:
77
79
  specification_version: 3
78
80
  summary: A whole bunch of extensions the ActiveRecord PostgreSQL adapter.