logidze 0.2.1 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +7 -1
- data/lib/generators/logidze/install/templates/migration.rb.erb +59 -37
- data/lib/generators/logidze/model/model_generator.rb +7 -0
- data/lib/generators/logidze/model/templates/migration.rb.erb +8 -1
- data/lib/logidze/history.rb +1 -3
- data/lib/logidze/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcb9249498ac35c0236653c1209d6395679c4d41
|
4
|
+
data.tar.gz: efd95cb463680a5e000f5e2b96dae8d7d1bc7c0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e51780490e139a4a475367527480edd0e3530f7c6bda2ef92d0da2591ac8a4e6f8177d2131b7b4f9563e2db3d4ceb6878e1b3574a6ce14206f7b1e9105ba641
|
7
|
+
data.tar.gz: 9922f8494d288bb0fd520abaae87872c3f1f8ceeaa0613689eee7637d8d9c423549a4aa545b09d9ef743213ca3503a2303bdce2ad4f1cb733bef817a19bddb2e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -46,13 +46,19 @@ rails generate logidze:model Post
|
|
46
46
|
rake db:migrate
|
47
47
|
```
|
48
48
|
|
49
|
+
This also adds `has_logidze` line to your model, which adds methods for working with logs.
|
50
|
+
|
49
51
|
You can provide `limit` option to `generate` to limit the size of the log (by default it's unlimited):
|
50
52
|
|
51
53
|
```ruby
|
52
54
|
rails generate logidze:model Post --limit=10
|
53
55
|
```
|
54
56
|
|
55
|
-
|
57
|
+
To backfill table data (i.e. create initial snapshots) add `backfill` option:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
rails generate logidze:model Post --backfill
|
61
|
+
```
|
56
62
|
|
57
63
|
## Usage
|
58
64
|
|
@@ -10,6 +10,51 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
10
10
|
SQL
|
11
11
|
|
12
12
|
execute <<~SQL
|
13
|
+
CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb) RETURNS jsonb AS $body$
|
14
|
+
BEGIN
|
15
|
+
return json_build_object(
|
16
|
+
'v', 1,
|
17
|
+
'h', jsonb_build_array(
|
18
|
+
jsonb_build_object(
|
19
|
+
'ts',
|
20
|
+
(extract(epoch from now()) * 1000)::bigint,
|
21
|
+
'v',
|
22
|
+
1,
|
23
|
+
'c',
|
24
|
+
item - 'log_data'
|
25
|
+
)
|
26
|
+
)
|
27
|
+
);
|
28
|
+
END;
|
29
|
+
$body$
|
30
|
+
LANGUAGE plpgsql;
|
31
|
+
|
32
|
+
CREATE OR REPLACE FUNCTION logidze_compact_history(log_data jsonb) RETURNS jsonb AS $body$
|
33
|
+
DECLARE
|
34
|
+
merged jsonb;
|
35
|
+
BEGIN
|
36
|
+
merged := jsonb_build_object(
|
37
|
+
'ts',
|
38
|
+
log_data#>'{h,1,ts}',
|
39
|
+
'v',
|
40
|
+
log_data#>'{h,1,v}',
|
41
|
+
'c',
|
42
|
+
(log_data#>'{h,0,c}') || (log_data#>'{h,1,c}')
|
43
|
+
);
|
44
|
+
|
45
|
+
return jsonb_set(
|
46
|
+
log_data,
|
47
|
+
'{h}',
|
48
|
+
jsonb_set(
|
49
|
+
log_data->'h',
|
50
|
+
'{1}',
|
51
|
+
merged
|
52
|
+
) - 0
|
53
|
+
);
|
54
|
+
END;
|
55
|
+
$body$
|
56
|
+
LANGUAGE plpgsql;
|
57
|
+
|
13
58
|
CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
14
59
|
DECLARE
|
15
60
|
changes jsonb;
|
@@ -22,28 +67,18 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
22
67
|
iterator integer;
|
23
68
|
item record;
|
24
69
|
BEGIN
|
25
|
-
ts := (extract(epoch from now()) * 1000)::bigint;
|
26
70
|
|
27
71
|
IF TG_OP = 'INSERT' THEN
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
NEW.log_data := json_build_object(
|
32
|
-
'v',
|
33
|
-
1,
|
34
|
-
'h',
|
35
|
-
jsonb_build_array(
|
36
|
-
jsonb_build_object(
|
37
|
-
'ts',
|
38
|
-
ts,
|
39
|
-
'v',
|
40
|
-
new_v,
|
41
|
-
'c',
|
42
|
-
changes
|
43
|
-
)
|
44
|
-
)
|
45
|
-
);
|
72
|
+
|
73
|
+
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*));
|
74
|
+
|
46
75
|
ELSIF TG_OP = 'UPDATE' THEN
|
76
|
+
|
77
|
+
IF OLD.log_data is NULL OR OLD.log_data = '{}'::jsonb THEN
|
78
|
+
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*));
|
79
|
+
RETURN NEW;
|
80
|
+
END IF;
|
81
|
+
|
47
82
|
history_limit := TG_ARGV[0];
|
48
83
|
current_version := (NEW.log_data->>'v')::int;
|
49
84
|
|
@@ -51,6 +86,8 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
51
86
|
RETURN NEW;
|
52
87
|
END IF;
|
53
88
|
|
89
|
+
ts := (extract(epoch from now()) * 1000)::bigint;
|
90
|
+
|
54
91
|
IF current_version < (NEW.log_data#>>'{h,-1,v}')::int THEN
|
55
92
|
iterator := 0;
|
56
93
|
FOR item in SELECT * FROM jsonb_array_elements(NEW.log_data->'h')
|
@@ -95,24 +132,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
95
132
|
);
|
96
133
|
|
97
134
|
IF history_limit IS NOT NULL AND history_limit = size THEN
|
98
|
-
|
99
|
-
'ts',
|
100
|
-
NEW.log_data#>'{h,1,ts}',
|
101
|
-
'v',
|
102
|
-
NEW.log_data#>'{h,1,v}',
|
103
|
-
'c',
|
104
|
-
(NEW.log_data#>'{h,0,c}') || (NEW.log_data#>'{h,1,c}')
|
105
|
-
);
|
106
|
-
|
107
|
-
NEW.log_data := jsonb_set(
|
108
|
-
NEW.log_data,
|
109
|
-
'{h}',
|
110
|
-
jsonb_set(
|
111
|
-
NEW.log_data->'h',
|
112
|
-
'{1}',
|
113
|
-
merged
|
114
|
-
) - 0
|
115
|
-
);
|
135
|
+
NEW.log_data := logidze_compact_history(NEW.log_data);
|
116
136
|
END IF;
|
117
137
|
END IF;
|
118
138
|
|
@@ -125,6 +145,8 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
125
145
|
|
126
146
|
def down
|
127
147
|
execute <<~SQL
|
148
|
+
DROP FUNCTION logidze_compact_history(jsonb) CASCADE;
|
149
|
+
DROP FUNCTION logidze_snapshot(jsonb) CASCADE;
|
128
150
|
DROP FUNCTION logidze_logger() CASCADE;
|
129
151
|
SQL
|
130
152
|
end
|
@@ -9,6 +9,9 @@ module Logidze
|
|
9
9
|
|
10
10
|
class_option :limit, type: :numeric, optional: true, desc: "Specify history size limit"
|
11
11
|
|
12
|
+
class_option :backfill, type: :boolean, optional: true,
|
13
|
+
desc: "Add query to backfill existing records history"
|
14
|
+
|
12
15
|
def generate_migration
|
13
16
|
migration_template "migration.rb.erb", "db/migrate/#{migration_file_name}"
|
14
17
|
end
|
@@ -31,6 +34,10 @@ module Logidze
|
|
31
34
|
def limit
|
32
35
|
options[:limit]
|
33
36
|
end
|
37
|
+
|
38
|
+
def backfill
|
39
|
+
options[:backfill]
|
40
|
+
end
|
34
41
|
end
|
35
42
|
|
36
43
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class <%= @migration_class_name %> < ActiveRecord::Migration
|
2
2
|
def up
|
3
|
-
add_column :<%= table_name %>, :log_data, :jsonb, default:
|
3
|
+
add_column :<%= table_name %>, :log_data, :jsonb, default: {}, null: false
|
4
4
|
|
5
5
|
execute <<-SQL
|
6
6
|
CREATE TRIGGER logidze_on_<%= table_name %>
|
@@ -8,6 +8,13 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
8
8
|
WHEN (current_setting('logidze.disabled') <> 'on')
|
9
9
|
EXECUTE PROCEDURE logidze_logger(<%= limit || '' %>);
|
10
10
|
SQL
|
11
|
+
|
12
|
+
<% if backfill %>
|
13
|
+
execute <<-SQL
|
14
|
+
UPDATE <%= table_name %> as t
|
15
|
+
SET log_data = logidze_snapshot(to_jsonb(t));
|
16
|
+
SQL
|
17
|
+
<% end %>
|
11
18
|
end
|
12
19
|
|
13
20
|
def down
|
data/lib/logidze/history.rb
CHANGED
data/lib/logidze/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logidze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|