logidze 0.8.1 → 1.0.0.rc1

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +124 -5
  3. data/LICENSE.txt +1 -1
  4. data/README.md +310 -80
  5. data/lib/generators/logidze/fx_helper.rb +17 -0
  6. data/lib/generators/logidze/inject_sql.rb +18 -0
  7. data/lib/generators/logidze/install/USAGE +6 -1
  8. data/lib/generators/logidze/install/functions/logidze_compact_history.sql +38 -0
  9. data/lib/generators/logidze/install/functions/logidze_filter_keys.sql +27 -0
  10. data/lib/generators/logidze/install/functions/logidze_logger.sql +150 -0
  11. data/lib/generators/logidze/install/functions/logidze_snapshot.sql +24 -0
  12. data/lib/generators/logidze/install/functions/logidze_version.sql +20 -0
  13. data/lib/generators/logidze/install/install_generator.rb +61 -3
  14. data/lib/generators/logidze/install/templates/hstore.rb.erb +1 -1
  15. data/lib/generators/logidze/install/templates/migration.rb.erb +19 -232
  16. data/lib/generators/logidze/install/templates/migration_fx.rb.erb +41 -0
  17. data/lib/generators/logidze/model/model_generator.rb +56 -20
  18. data/lib/generators/logidze/model/templates/migration.rb.erb +57 -36
  19. data/lib/generators/logidze/model/triggers/logidze.sql +6 -0
  20. data/lib/logidze.rb +43 -20
  21. data/lib/logidze/engine.rb +4 -1
  22. data/lib/logidze/has_logidze.rb +12 -3
  23. data/lib/logidze/history.rb +7 -15
  24. data/lib/logidze/history/type.rb +1 -1
  25. data/lib/logidze/history/version.rb +6 -5
  26. data/lib/logidze/ignore_log_data.rb +22 -0
  27. data/lib/logidze/ignore_log_data/cast_attribute_patch.rb +17 -0
  28. data/lib/logidze/meta.rb +44 -17
  29. data/lib/logidze/model.rb +65 -37
  30. data/lib/logidze/version.rb +2 -1
  31. data/lib/logidze/versioned_association.rb +0 -1
  32. metadata +47 -103
  33. data/.gitignore +0 -40
  34. data/.hound.yml +0 -3
  35. data/.rubocop.yml +0 -94
  36. data/.travis.yml +0 -39
  37. data/Gemfile +0 -13
  38. data/Rakefile +0 -28
  39. data/bench/performance/README.md +0 -109
  40. data/bench/performance/diff_bench.rb +0 -36
  41. data/bench/performance/insert_bench.rb +0 -20
  42. data/bench/performance/memory_profile.rb +0 -53
  43. data/bench/performance/setup.rb +0 -308
  44. data/bench/performance/update_bench.rb +0 -36
  45. data/bench/triggers/Makefile +0 -56
  46. data/bench/triggers/Readme.md +0 -58
  47. data/bench/triggers/bench.sql +0 -6
  48. data/bench/triggers/hstore_trigger_setup.sql +0 -38
  49. data/bench/triggers/jsonb_minus_2_setup.sql +0 -47
  50. data/bench/triggers/jsonb_minus_setup.sql +0 -49
  51. data/bench/triggers/keys2_trigger_setup.sql +0 -44
  52. data/bench/triggers/keys_trigger_setup.sql +0 -50
  53. data/bin/console +0 -8
  54. data/bin/setup +0 -9
  55. data/gemfiles/rails42.gemfile +0 -5
  56. data/gemfiles/rails5.gemfile +0 -6
  57. data/gemfiles/rails52.gemfile +0 -6
  58. data/gemfiles/railsmaster.gemfile +0 -7
  59. data/lib/logidze/migration.rb +0 -19
  60. data/logidze.gemspec +0 -33
@@ -1,6 +0,0 @@
1
- \set naccounts 100000 * :scale
2
- \setrandom aid 1 :naccounts
3
- \setrandom delta -5000 5000
4
- BEGIN;
5
- UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
6
- END;
@@ -1,38 +0,0 @@
1
- CREATE OR REPLACE FUNCTION hstore_logger() RETURNS TRIGGER AS $body$
2
- DECLARE
3
- changes_h jsonb;
4
- size integer;
5
- buffer jsonb;
6
- BEGIN
7
- size := jsonb_array_length(NEW.log);
8
-
9
- changes_h := hstore_to_jsonb_loose(
10
- hstore(NEW.*) - hstore(OLD.*)
11
- );
12
-
13
- NEW.log := jsonb_set(
14
- NEW.log,
15
- ARRAY[size::text],
16
- jsonb_build_object(
17
- 'ts',
18
- extract(epoch from now())::int,
19
- 'i',
20
- (NEW.log#>>ARRAY[(size - 1)::text, 'i'])::int + 1,
21
- 'd',
22
- changes_h
23
- ),
24
- true
25
- );
26
- return NEW;
27
- END;
28
- $body$
29
- LANGUAGE plpgsql;
30
-
31
-
32
- ALTER TABLE pgbench_accounts ADD COLUMN log jsonb DEFAULT '[]' NOT NULL;
33
-
34
- UPDATE pgbench_accounts SET log = to_jsonb(ARRAY[json_build_object('i', 0)])::jsonb;
35
-
36
- CREATE TRIGGER hstore_log_accounts
37
- BEFORE UPDATE ON pgbench_accounts FOR EACH ROW
38
- EXECUTE PROCEDURE hstore_logger();
@@ -1,47 +0,0 @@
1
- CREATE OR REPLACE FUNCTION jsonb_minus(arg1 jsonb, arg2 jsonb) RETURNS jsonb
2
- AS $$
3
-
4
- SELECT
5
- COALESCE(json_object_agg(key, value), '{}')::jsonb
6
- FROM
7
- jsonb_each(arg1)
8
- WHERE NOT jsonb_build_object(key, value) <@ arg2;
9
-
10
- $$ LANGUAGE SQL;
11
-
12
- CREATE OR REPLACE FUNCTION jsonb_minus_2_logger() RETURNS TRIGGER AS $body$
13
- DECLARE
14
- changes_h jsonb;
15
- size integer;
16
- buffer jsonb;
17
- BEGIN
18
- size := jsonb_array_length(NEW.log);
19
-
20
- changes_h := jsonb_minus(row_to_json(OLD)::jsonb, row_to_json(NEW)::jsonb);
21
-
22
- NEW.log := jsonb_set(
23
- NEW.log,
24
- ARRAY[size::text],
25
- jsonb_build_object(
26
- 'ts',
27
- extract(epoch from now())::int,
28
- 'i',
29
- (NEW.log#>>ARRAY[(size - 1)::text, 'i'])::int + 1,
30
- 'd',
31
- changes_h
32
- ),
33
- true
34
- );
35
- return NEW;
36
- END;
37
- $body$
38
- LANGUAGE plpgsql;
39
-
40
-
41
- ALTER TABLE pgbench_accounts ADD COLUMN log jsonb DEFAULT '[]' NOT NULL;
42
-
43
- UPDATE pgbench_accounts SET log = to_jsonb(ARRAY[json_build_object('i', 0)])::jsonb;
44
-
45
- CREATE TRIGGER hstore_log_accounts
46
- BEFORE UPDATE ON pgbench_accounts FOR EACH ROW
47
- EXECUTE PROCEDURE jsonb_minus_2_logger();
@@ -1,49 +0,0 @@
1
- CREATE OR REPLACE FUNCTION jsonb_minus(arg1 jsonb, arg2 jsonb) RETURNS jsonb
2
- AS $$
3
-
4
- SELECT
5
- COALESCE(json_object_agg(key, value), '{}')::jsonb
6
- FROM
7
- jsonb_each(arg1)
8
- WHERE
9
- arg1 -> key <> arg2 -> key
10
- OR arg2 -> key IS NULL;
11
-
12
- $$ LANGUAGE SQL;
13
-
14
- CREATE OR REPLACE FUNCTION jsonb_minus_logger() RETURNS TRIGGER AS $body$
15
- DECLARE
16
- changes_h jsonb;
17
- size integer;
18
- buffer jsonb;
19
- BEGIN
20
- size := jsonb_array_length(NEW.log);
21
-
22
- changes_h := jsonb_minus(row_to_json(OLD)::jsonb, row_to_json(NEW)::jsonb);
23
-
24
- NEW.log := jsonb_set(
25
- NEW.log,
26
- ARRAY[size::text],
27
- jsonb_build_object(
28
- 'ts',
29
- extract(epoch from now())::int,
30
- 'i',
31
- (NEW.log#>>ARRAY[(size - 1)::text, 'i'])::int + 1,
32
- 'd',
33
- changes_h
34
- ),
35
- true
36
- );
37
- return NEW;
38
- END;
39
- $body$
40
- LANGUAGE plpgsql;
41
-
42
-
43
- ALTER TABLE pgbench_accounts ADD COLUMN log jsonb DEFAULT '[]' NOT NULL;
44
-
45
- UPDATE pgbench_accounts SET log = to_jsonb(ARRAY[json_build_object('i', 0)])::jsonb;
46
-
47
- CREATE TRIGGER hstore_log_accounts
48
- BEFORE UPDATE ON pgbench_accounts FOR EACH ROW
49
- EXECUTE PROCEDURE jsonb_minus_logger();
@@ -1,44 +0,0 @@
1
- CREATE OR REPLACE FUNCTION keys_2_logger() RETURNS TRIGGER AS $body$
2
- DECLARE
3
- size integer;
4
- old_j jsonb;
5
- changes_j jsonb;
6
- item record;
7
- BEGIN
8
- size := jsonb_array_length(NEW.log);
9
- old_j := to_jsonb(OLD);
10
- changes_j := to_jsonb(NEW);
11
-
12
- FOR item in SELECT key as k, value as v FROM jsonb_each(old_j)
13
- LOOP
14
- IF changes_j->item.k = item.v THEN
15
- changes_j := changes_j - item.k;
16
- END IF;
17
- END LOOP;
18
-
19
- NEW.log := jsonb_set(
20
- NEW.log,
21
- ARRAY[size::text],
22
- jsonb_build_object(
23
- 'ts',
24
- extract(epoch from now())::int,
25
- 'i',
26
- (NEW.log#>>ARRAY[(size - 1)::text, 'i'])::int + 1,
27
- 'd',
28
- changes_j
29
- ),
30
- true
31
- );
32
- return NEW;
33
- END;
34
- $body$
35
- LANGUAGE plpgsql;
36
-
37
-
38
- ALTER TABLE pgbench_accounts ADD COLUMN log jsonb DEFAULT '[]' NOT NULL;
39
-
40
- UPDATE pgbench_accounts SET log = to_jsonb(ARRAY[json_build_object('i', 0)])::jsonb;
41
-
42
- CREATE TRIGGER keys_log_accounts
43
- BEFORE UPDATE ON pgbench_accounts FOR EACH ROW
44
- EXECUTE PROCEDURE keys_2_logger();
@@ -1,50 +0,0 @@
1
- CREATE OR REPLACE FUNCTION keys_logger() RETURNS TRIGGER AS $body$
2
- DECLARE
3
- changes_h jsonb;
4
- size integer;
5
- old_j jsonb;
6
- new_j jsonb;
7
- item record;
8
- BEGIN
9
- size := jsonb_array_length(NEW.log);
10
- old_j := to_jsonb(OLD);
11
- new_j := to_jsonb(NEW);
12
- changes_h := '{}'::jsonb;
13
-
14
- FOR item in SELECT key as k, value as v FROM jsonb_each(new_j)
15
- LOOP
16
- IF item.v <> jsonb_extract_path(old_j, item.k) THEN
17
- changes_h := jsonb_set(
18
- changes_h,
19
- ARRAY[item.k],
20
- item.v
21
- );
22
- END IF;
23
- END LOOP;
24
-
25
- NEW.log := jsonb_set(
26
- NEW.log,
27
- ARRAY[size::text],
28
- jsonb_build_object(
29
- 'ts',
30
- extract(epoch from now())::int,
31
- 'i',
32
- (NEW.log#>>ARRAY[(size - 1)::text, 'i'])::int + 1,
33
- 'd',
34
- changes_h
35
- ),
36
- true
37
- );
38
- return NEW;
39
- END;
40
- $body$
41
- LANGUAGE plpgsql;
42
-
43
-
44
- ALTER TABLE pgbench_accounts ADD COLUMN log jsonb DEFAULT '[]' NOT NULL;
45
-
46
- UPDATE pgbench_accounts SET log = to_jsonb(ARRAY[json_build_object('i', 0)])::jsonb;
47
-
48
- CREATE TRIGGER keys_log_accounts
49
- BEFORE UPDATE ON pgbench_accounts FOR EACH ROW
50
- EXECUTE PROCEDURE keys_logger();
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "rails"
5
- require "logidze"
6
-
7
- require "pry"
8
- Pry.start
data/bin/setup DELETED
@@ -1,9 +0,0 @@
1
- #!/bin/sh
2
-
3
- set -e
4
-
5
- gem install bundler --conservative
6
- bundle check || bundle install
7
-
8
- bundle exec rake dummy:db:create
9
- bundle exec rake dummy:db:test:prepare
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '~> 4.2'
4
-
5
- gemspec path: '..'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '~> 5.1.0'
4
- gem 'rspec-rails', '~> 3.5'
5
-
6
- gemspec path: '..'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '~> 5.2.1'
4
- gem 'rspec-rails', '~> 3.5'
5
-
6
- gemspec path: '..'
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'arel', github: 'rails/arel'
4
- gem 'rails', github: 'rails/rails'
5
- gem 'rspec-rails', '>= 3.5'
6
-
7
- gemspec path: '..'
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
- module Logidze
3
- # Contains helpers for handling different PG versions
4
- module Migration
5
- # Checks whether pg function `current_setting` support `missing_ok` argument
6
- # (since 9.6)
7
- def current_setting_missing_supported?
8
- ActiveRecord::Base.connection.send(:postgresql_version) >= 90_600
9
- end
10
-
11
- def current_setting(name)
12
- if current_setting_missing_supported?
13
- "current_setting('#{name}', true)"
14
- else
15
- "current_setting('#{name}')"
16
- end
17
- end
18
- end
19
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'logidze/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "logidze"
8
- spec.version = Logidze::VERSION
9
- spec.authors = ["palkan"]
10
- spec.email = ["dementiev.vm@gmail.com"]
11
-
12
- spec.summary = "PostgreSQL JSON-based auditing"
13
- spec.description = "PostgreSQL JSON-based auditing"
14
- spec.homepage = "http://github.com/palkan/logidze"
15
- spec.license = "MIT"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_dependency "rails", ">= 4.2"
21
-
22
- spec.add_development_dependency "ammeter", "~> 1.1.3"
23
- spec.add_development_dependency "bundler", "~> 1"
24
- spec.add_development_dependency "database_cleaner", "~> 1.5"
25
- spec.add_development_dependency "pg", "~>0.18"
26
- spec.add_development_dependency "pry-byebug"
27
- spec.add_development_dependency "rake", ">= 10.0"
28
- spec.add_development_dependency "rspec-rails", ">= 3.4"
29
- spec.add_development_dependency "rubocop", "~> 0.59.0"
30
- spec.add_development_dependency "rubocop-md", "~> 0.2.0"
31
- spec.add_development_dependency "simplecov", ">= 0.3.8"
32
- spec.add_development_dependency "timecop", "~> 0.8"
33
- end