-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
hamster
committed
Feb 18, 2020
1 parent
98c778c
commit 31e17fa
Showing
13 changed files
with
257 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Change Log | ||
All notable changes to this project will be documented in this file. | ||
|
||
## [1.0.0] - 2020-02-18 | ||
|
||
### Migration from 0.2.0 to 1.0.0 | ||
|
||
Recreate audit_changes() function with new changes. | ||
|
||
### Changed | ||
|
||
- instead of creating model_to_table_map temp table now keeps just model_name | ||
- temp table now drops on commit | ||
- temp table now named as "__schema_table_audit_logs_trid" | ||
- temp table now has array of audited table columns | ||
- trigger function now uses array of columns from temp table instead of querying for them | ||
- remade specs | ||
- readme | ||
- isolated tests | ||
- incapsulated preparations for tests in SeedHelper | ||
|
||
### Removed | ||
|
||
- redundant self | ||
- redundant excluded columns option | ||
- ability to use #with_current_user on instances of audited class | ||
- spec for polymorhic associations | ||
|
||
## [0.2.0] - 2018-06-08 | ||
|
||
Initial version. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# frozen_string_literal: true | ||
|
||
require "pry" | ||
require "sequel/plugins/bulk_audit" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,52 @@ | ||
# frozen_string_literal: true | ||
|
||
require "sequel/plugins/bulk_audit/version" | ||
require 'sequel/model' | ||
|
||
module Sequel | ||
module Plugins | ||
module BulkAudit | ||
def self.apply(model, opts={}) | ||
model.instance_eval do | ||
@excluded_columns = [*opts[:excluded_columns]] | ||
module ClassMethods | ||
def with_current_user(current_user, attributes = {}) | ||
db.transaction do | ||
data = db.select( | ||
Sequel.expr(current_user&.id || 0).as(:user_id), | ||
Sequel.cast(current_user&.login || "unspecified", :text).as(:username), | ||
Sequel.expr(name).as(:model_name), | ||
Sequel.pg_array(stringified_columns).as(:columns), | ||
Sequel.pg_jsonb(attributes).as(:data), | ||
) | ||
|
||
create_temp_table(data) | ||
|
||
yield if block_given? | ||
end | ||
end | ||
end | ||
|
||
module SharedMethods | ||
def model_to_table_map | ||
@@model_to_table_map ||= ObjectSpace.each_object(Class).select do |klazz| | ||
next if klazz.name.nil? | ||
klazz < Sequel::Model && klazz&.plugins&.include?(Sequel::Plugins::BulkAudit) | ||
end.map { |c| [c.to_s, c.table_name] }.to_h.invert | ||
def trid | ||
db.get(Sequel.function(:txid_current)) | ||
end | ||
|
||
def with_current_user(current_user, attributes = nil) | ||
self.db.transaction do | ||
trid = self.db.select(Sequel.function(:txid_current)).single_value | ||
data = self.db.select(Sequel.expr(current_user&.id || 0).as(:user_id), | ||
Sequel.cast(current_user&.login || "unspecified", :text).as(:username), | ||
Sequel.pg_jsonb(model_to_table_map).as(:model_map), | ||
Sequel.pg_jsonb(attributes || {}).as(:data)) | ||
self.db.create_table!(:"__audit_info_#{trid}", temp: true, as: data) | ||
result = yield if block_given? | ||
self.db.drop_table?(:"__audit_info_#{trid}") | ||
result | ||
end | ||
def create_temp_table(data) | ||
db.create_table!(audit_logs_temp_table_name, on_commit: :drop, temp: true, as: data) | ||
end | ||
end | ||
|
||
module ClassMethods | ||
include SharedMethods | ||
end | ||
def stringified_columns | ||
columns.map(&:to_s) | ||
end | ||
|
||
module InstanceMethods | ||
include SharedMethods | ||
# uses trid so temp table would be unique between transactions | ||
# uses table_name so temp table would be unique if several models are audited at once | ||
def audit_logs_temp_table_name | ||
"__#{table_name_with_schema}_audit_info_#{trid}".to_sym | ||
end | ||
|
||
def table_name_with_schema | ||
return "public_#{table_name}" if table_name.is_a?(Symbol) | ||
|
||
"#{table_name.table}_#{table_name.column}" # for QualifiedIdentifier | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
module Sequel | ||
module Plugins | ||
module BulkAudit | ||
VERSION = "0.2.0" | ||
VERSION = "1.0.0" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,12 @@ | ||
- id: 1 | ||
created_at: '2017-04-01' | ||
value: 1 | ||
- id: 2 | ||
created_at: '2017-04-01' | ||
value: 2 | ||
- id: 3 | ||
created_at: '2017-05-01' | ||
value: 3 | ||
- id: 4 | ||
created_at: '2017-05-01' | ||
value: 4 | ||
- id: 5 | ||
created_at: '2017-05-01' | ||
value: 5 | ||
- id: 6 | ||
created_at: '2017-05-01' | ||
value: 6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# frozen_string_literal: true | ||
|
||
module SeedHelper | ||
class << self | ||
def prepare_data_table | ||
drop_data | ||
create_data | ||
seed_data | ||
restart_data_seq | ||
create_trigger_on_data | ||
end | ||
|
||
def create_data | ||
DB.create_table(:data) do | ||
primary_key :id | ||
String :value | ||
end | ||
end | ||
|
||
def seed_data | ||
data = YAML.load(IO.read("spec/fixtures/data.yml")) | ||
DB[:data].multi_insert(data) | ||
end | ||
|
||
def restart_data_seq | ||
id = DB[:data].max(:id) + 1 | ||
|
||
DB.execute(<<-SQL) | ||
ALTER SEQUENCE data_id_seq RESTART WITH #{id}; | ||
SQL | ||
end | ||
|
||
def create_trigger_on_data | ||
DB.run <<~SQL | ||
CREATE TRIGGER audit_changes_on_data BEFORE INSERT OR UPDATE OR DELETE ON data | ||
FOR EACH ROW EXECUTE PROCEDURE audit_changes(); | ||
SQL | ||
end | ||
|
||
def drop_data | ||
DB.drop_table?(:data) | ||
end | ||
|
||
def clear_audit_logs | ||
DB.tables.include?(:audit_logs) && DB[:audit_logs].truncate | ||
end | ||
end | ||
end |
Oops, something went wrong.