pg_audit_log 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -5,7 +5,6 @@ module PgAuditLog
5
5
 
6
6
  def install
7
7
  directory "spec/models"
8
- copy_file "spec/models/pg_audit_log_spec.rb", "spec/models/pg_audit_log_spec.rb"
9
8
  end
10
9
  end
11
10
  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 all_tables.include?(PgAuditLog::Entry.table_name)
4
+ unless PgAuditLog::Entry.installed?
7
5
  puts "Creating #{PgAuditLog::Entry.table_name} table..."
8
- sql = File.read(File.join(sql_path, "create_audit_log_table.sql"))
9
- connection.execute_without_auditing(sql)
6
+ PgAuditLog::Entry.install
10
7
  end
8
+
11
9
  puts "Installing audit_changes() function..."
12
- sql = File.read(File.join(sql_path, "create_audit_changes.sql"))
13
- connection.execute_without_auditing(sql)
10
+ PgAuditLog::Function.install
14
11
 
15
12
  puts "Installing all audit log triggers... "
16
- run_on(audit_log_tables) do |table|
17
- <<-SQL
18
- CREATE TRIGGER audit_#{table}
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
- run_on(audit_log_tables) do |table|
34
- "DROP TRIGGER audit_#{table} ON #{table};"
35
- end
21
+ PgAuditLog::Triggers.uninstall
22
+
36
23
  puts "Uninstalling audit_changes() function..."
37
- sql = File.read(File.join(sql_path, "uninstall_audit_changes.sql"))
38
- connection.execute_without_auditing(sql)
24
+ PgAuditLog::Function.uninstall
39
25
 
40
- puts "Exporting development_structure.sql..."
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 connection
48
- ActiveRecord::Base.connection
49
- end
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
 
@@ -0,0 +1,15 @@
1
+ module PgAuditLog
2
+ class ActiveRecord
3
+ class << self
4
+ private
5
+
6
+ def connection
7
+ ::ActiveRecord::Base.connection
8
+ end
9
+
10
+ def execute(sql)
11
+ connection.execute_without_auditing(sql)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -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
- CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
2
- CREATE OR REPLACE FUNCTION audit_changes() RETURNS trigger
3
- LANGUAGE plpgsql
4
- AS $_$
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
@@ -1,3 +1,3 @@
1
1
  module PgAuditLog
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -18,20 +18,9 @@ rescue PGError => e
18
18
  raise e
19
19
  end
20
20
 
21
- connection.execute("DROP TABLE IF EXISTS audit_log")
22
-
23
- sql_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "generators", "pg_audit_log", "templates", "lib", "tasks", "pg_audit_log"))
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.1
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-28 00:00:00 -04:00
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/lib/tasks/pg_audit_log/create_audit_changes.sql
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
@@ -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;