pg_audit_log 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,7 +8,7 @@ module PgAuditLog
8
8
  end
9
9
 
10
10
  def execute(sql)
11
- connection.execute_without_auditing(sql)
11
+ connection.execute(sql)
12
12
  end
13
13
  end
14
14
  end
@@ -75,7 +75,7 @@ class PgAuditLog::Entry < ActiveRecord::Base
75
75
  BEFORE INSERT ON audit_log
76
76
  FOR EACH ROW EXECUTE PROCEDURE audit_log_insert_trigger();
77
77
  SQL
78
- connection.execute_without_auditing(sql)
78
+ connection.execute(sql)
79
79
  end
80
80
 
81
81
  def uninstall
@@ -2,30 +2,6 @@ require "active_record/connection_adapters/postgresql_adapter"
2
2
 
3
3
  # Did not want to reopen the class but sending an include seemingly is not working.
4
4
  class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
- def begin_db_transaction
6
- execute_without_auditing "BEGIN"
7
- end
8
-
9
- def commit_db_transaction
10
- execute_without_auditing "COMMIT"
11
- end
12
-
13
- def rollback_db_transaction
14
- execute_without_auditing "ROLLBACK"
15
- end
16
-
17
- def create_savepoint
18
- execute_without_auditing("SAVEPOINT #{current_savepoint_name}")
19
- end
20
-
21
- def rollback_to_savepoint
22
- execute_without_auditing("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
23
- end
24
-
25
- def release_savepoint
26
- execute_without_auditing("RELEASE SAVEPOINT #{current_savepoint_name}")
27
- end
28
-
29
5
  def drop_table_with_auditing(table_name, options = {})
30
6
  if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
31
7
  PgAuditLog::Triggers.drop_for_table(table_name)
@@ -49,17 +25,55 @@ class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
49
25
  alias_method_chain :create_table, :auditing
50
26
 
51
27
  def rename_table_with_auditing(table_name, new_name)
52
- rename_table_without_auditing(table_name, new_name)
53
28
  if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
54
29
  PgAuditLog::Triggers.drop_for_table(table_name)
55
30
  end
56
- unless PgAuditLog::IGNORED_TABLES.include?(table_name) ||
57
- PgAuditLog::Triggers.tables_with_triggers.include?(new_name)
31
+ rename_table_without_auditing(table_name, new_name)
32
+ unless PgAuditLog::IGNORED_TABLES.include?(table_name) || PgAuditLog::Triggers.tables_with_triggers.include?(new_name)
58
33
  PgAuditLog::Triggers.create_for_table(new_name)
59
34
  end
60
35
  end
61
36
  alias_method_chain :rename_table, :auditing
62
37
 
38
+ def set_audit_user_id_and_name
39
+ user_id, unique_name = user_id_and_name
40
+ return true if (@last_user_id && @last_user_id == user_id) && (@last_unique_name && @last_unique_name == unique_name)
41
+
42
+ execute_without_pg_audit_log PgAuditLog::Function::user_identifier_temporary_function(user_id)
43
+ execute_without_pg_audit_log PgAuditLog::Function::user_unique_name_temporary_function(unique_name)
44
+ @last_user_id = user_id
45
+ @last_unique_name = unique_name
46
+
47
+ true
48
+ end
49
+
50
+ def blank_audit_user_id_and_name
51
+ @last_user_id = @last_unique_name = nil
52
+ true
53
+ end
54
+
55
+ def reconnect_with_pg_audit_log!
56
+ reconnect_without_pg_audit_log!
57
+ @last_user_id = @last_unique_name = nil
58
+ end
59
+ alias_method_chain :reconnect!, :pg_audit_log
60
+
61
+ def execute_with_pg_audit_log(sql, name = nil)
62
+ conn = execute_without_pg_audit_log(sql, name = nil)
63
+ set_audit_user_id_and_name
64
+ conn
65
+ end
66
+ alias_method_chain :execute, :pg_audit_log
67
+
68
+ if ::ActiveRecord::VERSION::MAJOR >= 3 && ::ActiveRecord::VERSION::MINOR >= 1
69
+ def exec_query_with_pg_audit_log(sql, name = 'SQL', binds = [])
70
+ conn = exec_query_without_pg_audit_log(sql, name, binds)
71
+ set_audit_user_id_and_name
72
+ conn
73
+ end
74
+ alias_method_chain :exec_query, :pg_audit_log
75
+ end
76
+
63
77
  private
64
78
 
65
79
  def user_id_and_name
@@ -22,29 +22,11 @@ module PgAuditLog
22
22
  end
23
23
 
24
24
  def user_identifier_temporary_function(user_id)
25
- sql = <<-SQL
26
- CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_identifier() RETURNS integer
27
- LANGUAGE plpgsql
28
- AS $_$
29
- BEGIN
30
- RETURN #{user_id};
31
- END
32
- $_$;
33
- SQL
34
- sql.split("\n").join(" ")
25
+ "CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_identifier() RETURNS integer AS 'SELECT #{user_id}' LANGUAGE SQL STABLE;"
35
26
  end
36
27
 
37
28
  def user_unique_name_temporary_function(username)
38
- sql = <<-SQL
39
- CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_unique_name() RETURNS varchar
40
- LANGUAGE plpgsql
41
- AS $_$
42
- BEGIN
43
- RETURN '#{username}';
44
- END
45
- $_$;
46
- SQL
47
- sql.split("\n").join(" ")
29
+ "CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_unique_name() RETURNS varchar AS $_$ SELECT '#{username}'::varchar $_$ LANGUAGE SQL STABLE;"
48
30
  end
49
31
 
50
32
  def install
@@ -1,3 +1,3 @@
1
1
  module PgAuditLog
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
data/lib/pg_audit_log.rb CHANGED
@@ -5,17 +5,9 @@ end
5
5
  require "active_record"
6
6
  require "pg_audit_log/version"
7
7
 
8
- case ::ActiveRecord::VERSION::MAJOR
9
- when 3
10
- require "pg_audit_log/extensions/shared/postgresql_adapter.rb"
11
- if ::ActiveRecord::VERSION::MINOR == 0
12
- require "pg_audit_log/extensions/3.0/postgresql_adapter.rb"
13
- else
14
- require "pg_audit_log/extensions/3.1/postgresql_adapter.rb"
15
- end
16
- else
17
- raise "ActiveRecord #{::ActiveRecord::VERSION::MAJOR}.x unsupported!"
18
- end
8
+ raise "ActiveRecord #{::ActiveRecord::VERSION::MAJOR}.x unsupported!" unless ::ActiveRecord::VERSION::MAJOR == 3
9
+
10
+ require "pg_audit_log/extensions/postgresql_adapter.rb"
19
11
  require "pg_audit_log/active_record"
20
12
  require "pg_audit_log/entry"
21
13
  require "pg_audit_log/function"
@@ -265,12 +265,23 @@ describe PgAuditLog do
265
265
  end
266
266
 
267
267
  describe "when renaming the table" do
268
+ def trigger_names
269
+ connection.select_values <<-SQL
270
+ SELECT triggers.tgname as trigger_name
271
+ FROM pg_trigger triggers
272
+ WHERE triggers.tgname LIKE '#{PgAuditLog::Triggers.trigger_prefix}%'
273
+ SQL
274
+ end
275
+
268
276
  it "should automatically drop and create the trigger" do
269
277
  new_table_name = "new_table_#{Time.now.to_i}"
270
278
  connection.create_table("test_table")
271
279
  connection.rename_table("test_table", new_table_name)
272
- PgAuditLog::Triggers.tables_with_triggers.should_not include("test_table")
280
+
281
+ trigger_names.should_not include("audit_test_table")
282
+ trigger_names.should include("audit_#{new_table_name}")
273
283
  PgAuditLog::Triggers.tables_with_triggers.should include(new_table_name)
284
+
274
285
  connection.drop_table(new_table_name) rescue nil
275
286
  end
276
287
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_audit_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-09 00:00:00.000000000 Z
12
+ date: 2012-04-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70242168359480 !ruby/object:Gem::Requirement
16
+ requirement: &70263689333140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70242168359480
24
+ version_requirements: *70263689333140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: pg
27
- requirement: &70242168358980 !ruby/object:Gem::Requirement
27
+ requirement: &70263689332640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70242168358980
35
+ version_requirements: *70263689332640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec-rails
38
- requirement: &70242168358520 !ruby/object:Gem::Requirement
38
+ requirement: &70263689332180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - =
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '2.7'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70242168358520
46
+ version_requirements: *70263689332180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: with_model
49
- requirement: &70242168358060 !ruby/object:Gem::Requirement
49
+ requirement: &70263689331720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.1.3
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70242168358060
57
+ version_requirements: *70263689331720
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: autotest
60
- requirement: &70242168357680 !ruby/object:Gem::Requirement
60
+ requirement: &70263689331340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70242168357680
68
+ version_requirements: *70263689331340
69
69
  description: A completely transparent audit logging component for your application
70
70
  using a stored procedure and triggers. Comes with specs for your project and a rake
71
71
  task to generate the reverse SQL to undo changes logged
@@ -92,15 +92,12 @@ files:
92
92
  - lib/pg_audit_log.rb
93
93
  - lib/pg_audit_log/active_record.rb
94
94
  - lib/pg_audit_log/entry.rb
95
- - lib/pg_audit_log/extensions/3.0/postgresql_adapter.rb
96
- - lib/pg_audit_log/extensions/3.1/postgresql_adapter.rb
97
- - lib/pg_audit_log/extensions/shared/postgresql_adapter.rb
95
+ - lib/pg_audit_log/extensions/postgresql_adapter.rb
98
96
  - lib/pg_audit_log/function.rb
99
97
  - lib/pg_audit_log/triggers.rb
100
98
  - lib/pg_audit_log/version.rb
101
99
  - pg_audit_log.gemspec
102
100
  - spec/configuration_spec.rb
103
- - spec/connection_adapter_spec.rb
104
101
  - spec/function_spec.rb
105
102
  - spec/model_spec.rb
106
103
  - spec/pg_audit_log_spec.rb
@@ -120,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
117
  version: '0'
121
118
  segments:
122
119
  - 0
123
- hash: 1658347057273507033
120
+ hash: -372258529913880576
124
121
  required_rubygems_version: !ruby/object:Gem::Requirement
125
122
  none: false
126
123
  requirements:
@@ -129,16 +126,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
126
  version: '0'
130
127
  segments:
131
128
  - 0
132
- hash: 1658347057273507033
129
+ hash: -372258529913880576
133
130
  requirements: []
134
131
  rubyforge_project:
135
- rubygems_version: 1.8.15
132
+ rubygems_version: 1.8.17
136
133
  signing_key:
137
134
  specification_version: 3
138
135
  summary: postgresql only database-level audit logging of all databases changes
139
136
  test_files:
140
137
  - spec/configuration_spec.rb
141
- - spec/connection_adapter_spec.rb
142
138
  - spec/function_spec.rb
143
139
  - spec/model_spec.rb
144
140
  - spec/pg_audit_log_spec.rb
@@ -1,26 +0,0 @@
1
- require "active_record/connection_adapters/postgresql_adapter"
2
-
3
- # Did not want to reopen the class but sending an include seemingly is not working.
4
- class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
- def execute_with_auditing(sql, name = nil)
6
- user_id, unique_name = user_id_and_name
7
- log_user_id = PgAuditLog::Function.user_identifier_temporary_function(user_id)
8
- log_user_unique_name = PgAuditLog::Function.user_unique_name_temporary_function(unique_name)
9
-
10
- logged_sql = ENV["LOG_AUDIT_SQL"] ? [log_user_id, log_user_unique_name, sql].values.join('; ') : sql
11
- log(logged_sql, name) do
12
- if @async
13
- @connection.async_exec(log_user_id)
14
- @connection.async_exec(log_user_unique_name)
15
- @connection.async_exec(sql)
16
- else
17
- @connection.exec(log_user_id)
18
- @connection.exec(log_user_unique_name)
19
- @connection.exec(sql)
20
- end
21
- end
22
- end
23
-
24
- alias_method_chain :execute, :auditing
25
- end
26
-
@@ -1,35 +0,0 @@
1
- require "active_record/connection_adapters/postgresql_adapter"
2
-
3
- # Did not want to reopen the class but sending an include seemingly is not working.
4
- class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
- def generate_auditing_sql(sql)
6
- user_id, unique_name = user_id_and_name
7
- log_user_id = PgAuditLog::Function.user_identifier_temporary_function(user_id)
8
- log_user_unique_name = PgAuditLog::Function.user_unique_name_temporary_function(unique_name)
9
- { :user_id => log_user_id, :unique_name => log_user_unique_name, :sql => sql }
10
- end
11
-
12
- def exec_query_with_auditing(sql, name = 'SQL', binds = [])
13
- audited_sql = generate_auditing_sql(sql)
14
- logged_sql = ENV["LOG_AUDIT_SQL"] ? audited_sql.values.join('; ') : sql
15
- log(logged_sql, name, binds) do
16
- exec_no_cache(audited_sql[:user_id], binds)
17
- exec_no_cache(audited_sql[:unique_name], binds)
18
- result = binds.empty? ? exec_no_cache(sql, binds) :
19
- exec_cache(sql, binds)
20
-
21
- ret = ActiveRecord::Result.new(result.fields, result_as_array(result))
22
- result.clear
23
- return ret
24
- end
25
- end
26
- alias_method_chain :exec_query, :auditing
27
-
28
- def execute_with_auditing(sql, name = nil)
29
- log(generate_auditing_sql(sql), name) do
30
- @connection.async_exec(sql)
31
- end
32
- end
33
- alias_method_chain :execute, :auditing
34
- end
35
-
@@ -1,13 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "the connection adapter" do
4
- subject { ActiveRecord::Base.connection }
5
-
6
- it { should respond_to(:execute_without_auditing) }
7
-
8
- it "should work for both execute and execute_without_auditing" do
9
- subject.execute("SELECT 1 = 1")
10
- subject.execute_without_auditing("SELECT 1 = 1")
11
- end
12
-
13
- end