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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 437f0707fbb215fbfb5655156b0f2f8450f2aa20
4
- data.tar.gz: 533a010cbc9d240c5c70d565621ace20d571579a
3
+ metadata.gz: fcb9249498ac35c0236653c1209d6395679c4d41
4
+ data.tar.gz: efd95cb463680a5e000f5e2b96dae8d7d1bc7c0a
5
5
  SHA512:
6
- metadata.gz: 419c21e03ba9196ff236bb7d8ea1bc897eaa1e7b8573bff1e1196008113641975341712e2f55d0ea8abb887820c18e0f32b654ee673ea379ef263cdae63ce875
7
- data.tar.gz: 8a885b62f97e4492001ef11a1961556faa0810d976f95fdb44dcb3071a5506622edc798f87aa6dd8fb27e40b46d605dd6adced7aa16e19278d2feb40f20beeb8
6
+ metadata.gz: 9e51780490e139a4a475367527480edd0e3530f7c6bda2ef92d0da2591ac8a4e6f8177d2131b7b4f9563e2db3d4ceb6878e1b3574a6ce14206f7b1e9105ba641
7
+ data.tar.gz: 9922f8494d288bb0fd520abaae87872c3f1f8ceeaa0613689eee7637d8d9c423549a4aa545b09d9ef743213ca3503a2303bdce2ad4f1cb733bef817a19bddb2e
@@ -1,3 +1,7 @@
1
+ # 0.2.2
2
+ - Add `--backfill` option to model migration
3
+ - Handle legacy data (that doesn't have log data)
4
+
1
5
  # 0.2.1
2
6
  - Support both Rails 4 and 5
3
7
 
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
- This also adds `has_logidze` line to your model, which adds methods for working with logs.
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
- changes := to_jsonb(NEW.*) - 'log_data';
29
- new_v := 1;
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
- merged := jsonb_build_object(
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: '{}', null: false
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
@@ -19,11 +19,9 @@ module Logidze
19
19
  end
20
20
 
21
21
  def self.load(json)
22
- new(json) unless json.nil?
22
+ new(json) if json.present?
23
23
  end
24
24
 
25
- ### Rails 4 ###
26
-
27
25
  def initialize(data)
28
26
  @data = data
29
27
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Logidze
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
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.1
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-02 00:00:00.000000000 Z
11
+ date: 2016-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails