pg_audit_log 0.0.1 → 0.0.2
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/lib/generators/pg_audit_log/install_generator.rb +7 -0
- data/lib/generators/pg_audit_log/rspec_generator.rb +0 -1
- data/lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log.rake +15 -55
- data/lib/generators/pg_audit_log/templates/migration.rb +15 -0
- data/lib/pg_audit_log.rb +4 -0
- data/lib/pg_audit_log/active_record.rb +15 -0
- data/lib/pg_audit_log/entry.rb +36 -2
- data/lib/{generators/pg_audit_log/templates/lib/tasks/pg_audit_log/create_audit_changes.sql → pg_audit_log/function.rb} +18 -4
- data/lib/pg_audit_log/triggers.rb +36 -0
- data/lib/pg_audit_log/version.rb +1 -1
- data/spec/spec_helper.rb +3 -14
- metadata +6 -5
- data/lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/create_audit_log_table.sql +0 -18
- data/lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/uninstall_audit_changes.sql +0 -1
@@ -1,11 +1,18 @@
|
|
1
|
+
require "rails/generators/active_record"
|
2
|
+
|
1
3
|
module PgAuditLog
|
2
4
|
module Generators
|
3
5
|
class InstallGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
extend ActiveRecord::Generators::Migration
|
8
|
+
|
4
9
|
source_root File.expand_path('../templates', __FILE__)
|
5
10
|
|
6
11
|
def install
|
7
12
|
directory "lib/tasks"
|
13
|
+
migration_template "migration.rb", "db/migrate/install_pg_audit_log"
|
8
14
|
end
|
15
|
+
|
9
16
|
end
|
10
17
|
end
|
11
18
|
end
|
@@ -1,76 +1,36 @@
|
|
1
1
|
namespace :pg_audit_log do
|
2
|
-
IGNORED_TABLES = ["plugin_schema_migrations", "sessions", "schema_migrations"]
|
3
|
-
|
4
2
|
desc "Install audit_log triggers on all tables"
|
5
3
|
task :install => :environment do
|
6
|
-
unless
|
4
|
+
unless PgAuditLog::Entry.installed?
|
7
5
|
puts "Creating #{PgAuditLog::Entry.table_name} table..."
|
8
|
-
|
9
|
-
connection.execute_without_auditing(sql)
|
6
|
+
PgAuditLog::Entry.install
|
10
7
|
end
|
8
|
+
|
11
9
|
puts "Installing audit_changes() function..."
|
12
|
-
|
13
|
-
connection.execute_without_auditing(sql)
|
10
|
+
PgAuditLog::Function.install
|
14
11
|
|
15
12
|
puts "Installing all audit log triggers... "
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
AFTER INSERT OR UPDATE OR DELETE
|
20
|
-
ON #{table}
|
21
|
-
FOR EACH ROW
|
22
|
-
EXECUTE PROCEDURE audit_changes()
|
23
|
-
SQL
|
24
|
-
end
|
25
|
-
puts "Exporting development_structure.sql..."
|
26
|
-
Rake::Task["db:structure:dump"].reenable
|
27
|
-
Rake::Task["db:structure:dump"].invoke
|
13
|
+
PgAuditLog::Triggers.install
|
14
|
+
|
15
|
+
export_development_structure
|
28
16
|
end
|
29
17
|
|
30
18
|
desc "Uninstall audit log triggers on all tables"
|
31
19
|
task :uninstall => :environment do
|
32
20
|
puts "Dropping all audit_log triggers... "
|
33
|
-
|
34
|
-
|
35
|
-
end
|
21
|
+
PgAuditLog::Triggers.uninstall
|
22
|
+
|
36
23
|
puts "Uninstalling audit_changes() function..."
|
37
|
-
|
38
|
-
connection.execute_without_auditing(sql)
|
24
|
+
PgAuditLog::Function.uninstall
|
39
25
|
|
40
|
-
|
41
|
-
Rake::Task["db:structure:dump"].reenable
|
42
|
-
Rake::Task["db:structure:dump"].invoke
|
26
|
+
export_development_structure
|
43
27
|
end
|
44
28
|
|
45
29
|
private
|
46
30
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
def all_tables
|
52
|
-
connection.tables
|
53
|
-
end
|
54
|
-
|
55
|
-
def audit_log_tables
|
56
|
-
all_tables - (IGNORED_TABLES + [PgAuditLog::Entry.table_name])
|
57
|
-
end
|
58
|
-
|
59
|
-
def sql_path
|
60
|
-
Rails.root.join("lib/tasks/pg_audit_log")
|
61
|
-
end
|
62
|
-
|
63
|
-
def run_on(tables, &block)
|
64
|
-
tables.sort.each do |table|
|
65
|
-
puts "* #{table}"
|
66
|
-
sql = yield(table)
|
67
|
-
begin
|
68
|
-
connection.execute_without_auditing(sql)
|
69
|
-
rescue => e
|
70
|
-
puts e.to_s
|
71
|
-
connection.reconnect!
|
72
|
-
end
|
73
|
-
end
|
31
|
+
def export_development_structure
|
32
|
+
puts "Exporting development_structure.sql..."
|
33
|
+
Rake::Task["db:structure:dump"].reenable
|
34
|
+
Rake::Task["db:structure:dump"].invoke
|
74
35
|
end
|
75
|
-
|
76
36
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class InstallPgAuditLog < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
PgAuditLog::Entry.install
|
5
|
+
PgAuditLog::Function.install
|
6
|
+
PgAuditLog::Triggers.install
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
PgAuditLog::Triggers.uninstall
|
11
|
+
PgAuditLog::Function.uninstall
|
12
|
+
PgAuditLog::Entry.uninstall
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
data/lib/pg_audit_log.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
module PgAuditLog
|
2
|
+
IGNORED_TABLES = ["plugin_schema_migrations", "sessions", "schema_migrations"]
|
2
3
|
end
|
3
4
|
|
4
5
|
require "active_record"
|
5
6
|
require "pg_audit_log/version"
|
6
7
|
require "pg_audit_log/extensions/postgresql_adapter.rb"
|
8
|
+
require "pg_audit_log/active_record"
|
7
9
|
require "pg_audit_log/entry"
|
10
|
+
require "pg_audit_log/function"
|
11
|
+
require "pg_audit_log/triggers"
|
8
12
|
|
data/lib/pg_audit_log/entry.rb
CHANGED
@@ -1,16 +1,50 @@
|
|
1
1
|
class PgAuditLog::Entry < ActiveRecord::Base
|
2
|
+
TABLE_NAME = "audit_log"
|
3
|
+
set_table_name TABLE_NAME
|
4
|
+
|
2
5
|
class CannotDeleteError < StandardError
|
3
6
|
def message
|
4
7
|
"Audit Logs cannot be deleted!"
|
5
8
|
end
|
6
9
|
end
|
7
|
-
set_table_name :audit_log
|
8
10
|
|
9
11
|
before_destroy do
|
10
12
|
raise CannotDeleteError
|
11
13
|
end
|
12
14
|
|
13
15
|
class << self
|
16
|
+
def installed?
|
17
|
+
connection.tables.include?(self.table_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def install
|
21
|
+
sql = <<-SQL
|
22
|
+
CREATE SEQUENCE #{self.table_name}_id_seq
|
23
|
+
START WITH 1
|
24
|
+
INCREMENT BY 1;
|
25
|
+
|
26
|
+
CREATE TABLE #{self.table_name} (
|
27
|
+
id integer PRIMARY KEY DEFAULT nextval('#{self.table_name}_id_seq'),
|
28
|
+
user_id integer,
|
29
|
+
user_unique_name character varying(255),
|
30
|
+
operation character varying(255),
|
31
|
+
table_name character varying(255),
|
32
|
+
field_name character varying(255),
|
33
|
+
field_value_new text,
|
34
|
+
field_value_old text,
|
35
|
+
occurred_at timestamp without time zone,
|
36
|
+
primary_key character varying(255)
|
37
|
+
);
|
38
|
+
|
39
|
+
ALTER SEQUENCE #{self.table_name}_id_seq OWNED BY #{self.table_name}.id;
|
40
|
+
SQL
|
41
|
+
connection.execute_without_auditing(sql)
|
42
|
+
end
|
43
|
+
|
44
|
+
def uninstall
|
45
|
+
connection.execute("DROP TABLE IF EXISTS #{self.table_name}")
|
46
|
+
end
|
47
|
+
|
14
48
|
def delete(id)
|
15
49
|
raise CannotDeleteError
|
16
50
|
end
|
@@ -20,4 +54,4 @@ class PgAuditLog::Entry < ActiveRecord::Base
|
|
20
54
|
end
|
21
55
|
end
|
22
56
|
|
23
|
-
end
|
57
|
+
end
|
@@ -1,7 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module PgAuditLog
|
2
|
+
class Function < ActiveRecord
|
3
|
+
class << self
|
4
|
+
def install
|
5
|
+
execute <<-SQL
|
6
|
+
CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
|
7
|
+
CREATE OR REPLACE FUNCTION audit_changes() RETURNS trigger
|
8
|
+
LANGUAGE plpgsql
|
9
|
+
AS $_$
|
5
10
|
DECLARE
|
6
11
|
col information_schema.columns %ROWTYPE;
|
7
12
|
new_value text;
|
@@ -70,3 +75,12 @@ CREATE OR REPLACE FUNCTION audit_changes() RETURNS trigger
|
|
70
75
|
RETURN NULL;
|
71
76
|
END
|
72
77
|
$_$;
|
78
|
+
SQL
|
79
|
+
end
|
80
|
+
|
81
|
+
def uninstall
|
82
|
+
execute "DROP FUNCTION audit_changes()"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module PgAuditLog
|
2
|
+
class Triggers < ActiveRecord
|
3
|
+
class << self
|
4
|
+
def tables
|
5
|
+
connection.tables - (PgAuditLog::IGNORED_TABLES + [PgAuditLog::Entry.table_name])
|
6
|
+
end
|
7
|
+
|
8
|
+
def install
|
9
|
+
tables.each do |table|
|
10
|
+
create_for_table(table)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def uninstall
|
15
|
+
tables.each do |table|
|
16
|
+
drop_for_table(table)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_for_table(table_name)
|
21
|
+
execute <<-SQL
|
22
|
+
CREATE TRIGGER audit_#{table_name}
|
23
|
+
AFTER INSERT OR UPDATE OR DELETE
|
24
|
+
ON #{table_name}
|
25
|
+
FOR EACH ROW
|
26
|
+
EXECUTE PROCEDURE audit_changes()
|
27
|
+
SQL
|
28
|
+
end
|
29
|
+
|
30
|
+
def drop_for_table(table_name)
|
31
|
+
execute "DROP TRIGGER audit_#{table_name} ON #{table_name};"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/pg_audit_log/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -18,20 +18,9 @@ rescue PGError => e
|
|
18
18
|
raise e
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
["create_audit_changes.sql", "create_audit_log_table.sql"].each do |sql_file|
|
26
|
-
begin
|
27
|
-
connection.execute File.read(File.join(sql_path, sql_file))
|
28
|
-
rescue => e
|
29
|
-
puts "-" * 80
|
30
|
-
puts "Unable to install #{sql_file}"
|
31
|
-
puts "-" * 80
|
32
|
-
raise e
|
33
|
-
end
|
34
|
-
end
|
21
|
+
PgAuditLog::Entry.uninstall
|
22
|
+
PgAuditLog::Entry.install
|
23
|
+
PgAuditLog::Function.install
|
35
24
|
|
36
25
|
RSpec.configure do |config|
|
37
26
|
config.mock_with :rspec
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: pg_audit_log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Case Commons, LLC
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-29 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -66,14 +66,15 @@ files:
|
|
66
66
|
- lib/generators/pg_audit_log/install_generator.rb
|
67
67
|
- lib/generators/pg_audit_log/rspec_generator.rb
|
68
68
|
- lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log.rake
|
69
|
-
- lib/generators/pg_audit_log/templates/
|
70
|
-
- lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/create_audit_log_table.sql
|
71
|
-
- lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/uninstall_audit_changes.sql
|
69
|
+
- lib/generators/pg_audit_log/templates/migration.rb
|
72
70
|
- lib/generators/pg_audit_log/templates/spec/models/pg_audit_log_spec.rb
|
73
71
|
- lib/generators/pg_audit_log/templates/spec/models/pg_audit_log_spec_helper.rb
|
74
72
|
- lib/pg_audit_log.rb
|
73
|
+
- lib/pg_audit_log/active_record.rb
|
75
74
|
- lib/pg_audit_log/entry.rb
|
76
75
|
- lib/pg_audit_log/extensions/postgresql_adapter.rb
|
76
|
+
- lib/pg_audit_log/function.rb
|
77
|
+
- lib/pg_audit_log/triggers.rb
|
77
78
|
- lib/pg_audit_log/version.rb
|
78
79
|
- pg_audit_log.gemspec
|
79
80
|
- spec/configuration_spec.rb
|
data/lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/create_audit_log_table.sql
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
CREATE SEQUENCE audit_log_id_seq
|
2
|
-
START WITH 1
|
3
|
-
INCREMENT BY 1;
|
4
|
-
|
5
|
-
CREATE TABLE audit_log (
|
6
|
-
id integer PRIMARY KEY DEFAULT nextval('audit_log_id_seq'),
|
7
|
-
user_id integer,
|
8
|
-
user_unique_name character varying(255),
|
9
|
-
operation character varying(255),
|
10
|
-
table_name character varying(255),
|
11
|
-
field_name character varying(255),
|
12
|
-
field_value_new text,
|
13
|
-
field_value_old text,
|
14
|
-
occurred_at timestamp without time zone,
|
15
|
-
primary_key character varying(255)
|
16
|
-
);
|
17
|
-
|
18
|
-
ALTER SEQUENCE audit_log_id_seq OWNED BY audit_log.id;
|
data/lib/generators/pg_audit_log/templates/lib/tasks/pg_audit_log/uninstall_audit_changes.sql
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
DROP FUNCTION audit_changes();
|