logidze 0.7.0 → 0.8.0

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
  SHA256:
3
- metadata.gz: bfd80509e728582e7c8b3629a6704d7d2d7b8d4e835974df0bd10dac03333348
4
- data.tar.gz: 5f3f386533f330d41d4acaeaf9e724df4a3d1ee3851cd99dbbff4ab5b6573546
3
+ metadata.gz: cd2ab4ea5c739000052b48f4288a45056741b99f2e698c7960e5a0eda32b29ea
4
+ data.tar.gz: 2ec438f29345455137bfedab7dcaf4e01b1d9d84d903b92ac4517753b10db5eb
5
5
  SHA512:
6
- metadata.gz: a17ac5c2fb65280a3897c5f672d0d0ef719870cd8f019a0d525e314d0c60795e5fda4068ba3fb0b1003f2ec5a848b3a2150237d29256fa8828a8401e775afcb6
7
- data.tar.gz: f9023b0b9731f9ddbb28fda06ae07995eb0e0a7cb33778238d582e82d8752632c7ca3fa84bfbe639ce2553fbe9c4b10dbaf0dc92d361f01deb08a2d97aebc447
6
+ metadata.gz: '0527218328332350cf799e746956b6b4ff7bb6503df1ae2d9fbf32feae01813eb81edbad7b90dc1dfd96c8fef34d079e646b66f1d0e0329ac12d99fdb6a79f4f'
7
+ data.tar.gz: 44b70aaaae2f7c9bf3f32a58c2891c4e0c5dda61387367b79406681580fc9667bf85ebb0255c6c74fe8827829230015a94a086555f6ffe223ace709c0a01a8c1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,92 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.8.0 (2018-10-01)
6
+
7
+ - [PR [#87](https://github.com/palkan/logidze/pull/87)] Adding debounce time to avoid spamming changelog creation ([@zocoi][])
8
+
9
+ Usage:
10
+
11
+ ```shell
12
+ # 5000ms
13
+ rails generate logidze:model story --debounce_time=5000
14
+ ```
15
+
16
+ You see the following in generated migration
17
+
18
+ ```sql
19
+ CREATE TRIGGER logidze_on_stories
20
+ BEFORE UPDATE OR INSERT ON stories FOR EACH ROW
21
+ WHEN (coalesce(#{current_setting('logidze.disabled')}, '') <> 'on')
22
+ EXECUTE PROCEDURE logidze_logger(null, 'updated_at', null, 5000);
23
+ ```
24
+
25
+ How to upgrade.
26
+
27
+ Please run `rails generate logidze:install --update` to regenerate stored functions.
28
+
29
+ This feature checks if several logs came in within a debounce time period then only keep the latest one
30
+ by merging the latest in previous others.
31
+
32
+ The concept is similar to https://underscorejs.org/#debounce
33
+
34
+ without `debounce_time`
35
+
36
+ ```js
37
+ {
38
+ "h": [
39
+ {
40
+ "c": {
41
+ "content": "Content 1"
42
+ },
43
+ "v": 1,
44
+ "ts": 0
45
+ },
46
+ {
47
+ "c": {
48
+ "content": "content 2",
49
+ "active": true
50
+ },
51
+ "v": 2,
52
+ "ts": 100
53
+ },
54
+ {
55
+ "c": {
56
+ "content": "content 3",
57
+ },
58
+ "v": 3,
59
+ "ts": 101
60
+ }
61
+ ],
62
+ "v": 3
63
+ }
64
+ ```
65
+
66
+ with `debounce_time` of `10ms`
67
+
68
+ ```js
69
+ {
70
+ "h": [
71
+ {
72
+ "c": {
73
+ "content": "Content 1"
74
+ },
75
+ "v": 1,
76
+ "ts": 0
77
+ },
78
+ {
79
+ "c": {
80
+ "content": "content 3",
81
+ "active": true
82
+ },
83
+ "v": 2,
84
+ "ts": 101
85
+ }
86
+ ],
87
+ "v": 3
88
+ }
89
+ ```
90
+
5
91
  ## 0.7.0 (2018-08-29)
6
92
 
7
93
  - [Fixes [#75](https://github.com/palkan/logidze/issues/70)] Fix association versioning with an optional belongs to ([@ankursethi-uscis][])
@@ -72,7 +158,7 @@ This is a quick fix for a more general problem (see [#59](https://github.com/pal
72
158
 
73
159
  ## 0.5.1 (2017-06-15)
74
160
 
75
- - _(Fix)_ Drop *all* created functions upon rolling back (https://github.com/palkan/logidze/commit/b8e150cc18b3316a8cf0c78f7117339481fb49c6). ([@vassilevsky][])
161
+ - _(Fix)_ Drop _all_ created functions upon rolling back (https://github.com/palkan/logidze/commit/b8e150cc18b3316a8cf0c78f7117339481fb49c6). ([@vassilevsky][])
76
162
 
77
163
  ## 0.5.0 (2017-03-28)
78
164
 
@@ -123,4 +209,5 @@ This is a quick fix for a more general problem (see [#59](https://github.com/pal
123
209
  [@akxcv]: https://github.com/akxcv
124
210
  [@vassilevsky]: https://github.com/vassilevsky
125
211
  [@ankursethi-uscis]: https://github.com/ankursethi-uscis
126
- [@DmitryTsepelev]: https://github.com/DmitryTsepelev
212
+ [@dmitrytsepelev]: https://github.com/DmitryTsepelev
213
+ [@zocoi]: https://github.com/zocoi
data/README.md CHANGED
@@ -1,6 +1,4 @@
1
- [![Cult Of Martians](http://cultofmartians.com/assets/badges/badge.svg)](http://cultofmartians.com)
2
- [![Gem Version](https://badge.fury.io/rb/logidze.svg)](https://rubygems.org/gems/logidze) [![Build Status](https://travis-ci.org/palkan/logidze.svg?branch=master)](https://travis-ci.org/palkan/logidze)
3
- [![Open Source Helpers](https://www.codetriage.com/palkan/logidze/badges/users.svg)](https://www.codetriage.com/palkan/logidze)
1
+ [![Cult Of Martians](http://cultofmartians.com/assets/badges/badge.svg)](http://cultofmartians.com) [![Gem Version](https://badge.fury.io/rb/logidze.svg)](https://rubygems.org/gems/logidze) [![Build Status](https://travis-ci.org/palkan/logidze.svg?branch=master)](https://travis-ci.org/palkan/logidze) [![Open Source Helpers](https://www.codetriage.com/palkan/logidze/badges/users.svg)](https://www.codetriage.com/palkan/logidze)
4
2
 
5
3
  # Logidze
6
4
 
@@ -290,7 +288,11 @@ The `log_data` column has the following format:
290
288
  "attr": "new value", // updated fields with new values
291
289
  "attr2": "new value"
292
290
  },
293
- "r": 42 // Resposibility ID (if provided)
291
+ "r": 42, // Resposibility ID (if provided), not in use since 0.7.0
292
+ "m": {
293
+ "_r": 42 // Resposibility ID (if provided), in use since 0.7.0
294
+ // any other meta information provided, please see Track meta information section for the details
295
+ }
294
296
  }
295
297
  ]
296
298
  }
@@ -18,6 +18,7 @@ module Logidze
18
18
 
19
19
  def generate_hstore_migration
20
20
  return if update?
21
+
21
22
  migration_template "hstore.rb.erb", "db/migrate/enable_hstore.rb"
22
23
  end
23
24
 
@@ -117,6 +117,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration<%= ActiveRecord::VE
117
117
  new_v integer;
118
118
  size integer;
119
119
  history_limit integer;
120
+ debounce_time integer;
120
121
  current_version integer;
121
122
  merged jsonb;
122
123
  iterator integer;
@@ -126,7 +127,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration<%= ActiveRecord::VE
126
127
  ts_column text;
127
128
  BEGIN
128
129
  ts_column := NULLIF(TG_ARGV[1], 'null');
129
- columns_blacklist := TG_ARGV[2];
130
+ columns_blacklist := COALESCE(NULLIF(TG_ARGV[2], 'null'), '{}');
130
131
 
131
132
  IF TG_OP = 'INSERT' THEN
132
133
  snapshot = logidze_snapshot(to_jsonb(NEW.*), ts_column, columns_blacklist);
@@ -146,6 +147,8 @@ class <%= @migration_class_name %> < ActiveRecord::Migration<%= ActiveRecord::VE
146
147
  END IF;
147
148
 
148
149
  history_limit := NULLIF(TG_ARGV[0], 'null');
150
+ debounce_time := NULLIF(TG_ARGV[3], 'null');
151
+
149
152
  current_version := (NEW.log_data->>'v')::int;
150
153
 
151
154
  IF ts_column IS NULL THEN
@@ -189,6 +192,21 @@ class <%= @migration_class_name %> < ActiveRecord::Migration<%= ActiveRecord::VE
189
192
  RETURN NEW;
190
193
  END IF;
191
194
 
195
+ IF (
196
+ debounce_time IS NOT NULL AND
197
+ (version->>'ts')::bigint - (NEW.log_data#>'{h,-1,ts}')::text::bigint <= debounce_time
198
+ ) THEN
199
+ -- merge new version with the previous one
200
+ new_v := (NEW.log_data#>>'{h,-1,v}')::int;
201
+ version := logidze_version(new_v, (NEW.log_data#>'{h,-1,c}')::jsonb || changes, ts, columns_blacklist);
202
+ -- remove the previous version from log
203
+ NEW.log_data := jsonb_set(
204
+ NEW.log_data,
205
+ '{h}',
206
+ (NEW.log_data->'h') - (size - 1)
207
+ );
208
+ END IF;
209
+
192
210
  NEW.log_data := jsonb_set(
193
211
  NEW.log_data,
194
212
  ARRAY['h', size::text],
@@ -10,6 +10,9 @@ module Logidze
10
10
 
11
11
  class_option :limit, type: :numeric, optional: true, desc: "Specify history size limit"
12
12
 
13
+ class_option :debounce_time, type: :numeric, optional: true,
14
+ desc: "Specify debounce time in millisecond"
15
+
13
16
  class_option :backfill, type: :boolean, optional: true,
14
17
  desc: "Add query to backfill existing records history"
15
18
 
@@ -37,6 +40,7 @@ module Logidze
37
40
 
38
41
  def inject_logidze_to_model
39
42
  return if update?
43
+
40
44
  indents = " " * (class_name.scan("::").count + 1)
41
45
 
42
46
  inject_into_class(model_file_path, class_name.demodulize, "#{indents}has_logidze\n")
@@ -84,11 +88,16 @@ module Logidze
84
88
  def timestamp_column
85
89
  value = options[:timestamp_column] || 'updated_at'
86
90
  return if %w(nil null false).include?(value)
91
+
87
92
  escape_pgsql_string(value)
88
93
  end
89
94
 
95
+ def debounce_time
96
+ options[:debounce_time]
97
+ end
98
+
90
99
  def logidze_logger_parameters
91
- format_pgsql_args(limit, timestamp_column, columns_blacklist)
100
+ format_pgsql_args(limit, timestamp_column, columns_blacklist, debounce_time)
92
101
  end
93
102
 
94
103
  def logidze_snapshot_parameters
@@ -97,11 +106,13 @@ module Logidze
97
106
 
98
107
  def format_pgsql_array(ruby_array)
99
108
  return if ruby_array.blank?
109
+
100
110
  "'{" + ruby_array.join(', ') + "}'"
101
111
  end
102
112
 
103
113
  def escape_pgsql_string(string)
104
114
  return if string.blank?
115
+
105
116
  "'#{string}'"
106
117
  end
107
118
 
@@ -59,10 +59,12 @@ module Logidze
59
59
  # Optional `data` paramater can be used as initial diff state.
60
60
  def changes_to(time: nil, version: nil, data: {}, from: 0)
61
61
  raise ArgumentError, "Time or version must be specified" if time.nil? && version.nil?
62
+
62
63
  filter = time.nil? ? method(:version_filter) : method(:time_filter)
63
64
  versions.each_with_object(data.dup) do |v, acc|
64
65
  next if v.version < from
65
66
  break acc if filter.call(v, version, time)
67
+
66
68
  acc.merge!(v.changes)
67
69
  end
68
70
  end
@@ -114,6 +116,7 @@ module Logidze
114
116
 
115
117
  def ==(other)
116
118
  return super unless other.is_a?(self.class)
119
+
117
120
  data == other.data
118
121
  end
119
122
 
data/lib/logidze/meta.rb CHANGED
@@ -9,6 +9,7 @@ module Logidze # :nodoc:
9
9
 
10
10
  def with_responsible(responsible_id, &block)
11
11
  return yield if responsible_id.nil?
12
+
12
13
  meta = { Logidze::History::Version::META_RESPONSIBLE => responsible_id }
13
14
  with_meta(meta, &block)
14
15
  end
@@ -30,6 +31,7 @@ module Logidze # :nodoc:
30
31
  def perform
31
32
  return if block.nil?
32
33
  return block.call if meta.nil?
34
+
33
35
  ActiveRecord::Base.transaction { call_block_in_meta_context }
34
36
  end
35
37
 
data/lib/logidze/model.rb CHANGED
@@ -144,6 +144,7 @@ module Logidze
144
144
  def undo!(append: Logidze.append_on_undo)
145
145
  version = log_data.previous_version
146
146
  return false if version.nil?
147
+
147
148
  switch_to!(version.version, append: append)
148
149
  end
149
150
 
@@ -152,6 +153,7 @@ module Logidze
152
153
  def redo!
153
154
  version = log_data.next_version
154
155
  return false if version.nil?
156
+
155
157
  switch_to!(version.version)
156
158
  end
157
159
 
@@ -206,6 +208,7 @@ module Logidze
206
208
 
207
209
  def apply_column_diff(column, value)
208
210
  return if deleted_column?(column)
211
+
209
212
  write_attribute column, deserialize_value(column, value)
210
213
  end
211
214
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Logidze
3
- VERSION = "0.7.0"
3
+ VERSION = "0.8.0"
4
4
  end
data/logidze.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "pry-byebug"
27
27
  spec.add_development_dependency "rake", ">= 10.0"
28
28
  spec.add_development_dependency "rspec-rails", ">= 3.4"
29
- spec.add_development_dependency "rubocop", "~> 0.58.0"
29
+ spec.add_development_dependency "rubocop", "~> 0.59.0"
30
30
  spec.add_development_dependency "rubocop-md", "~> 0.2.0"
31
31
  spec.add_development_dependency "simplecov", ">= 0.3.8"
32
32
  spec.add_development_dependency "timecop", "~> 0.8"
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.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-29 00:00:00.000000000 Z
11
+ date: 2018-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.58.0
131
+ version: 0.59.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.58.0
138
+ version: 0.59.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rubocop-md
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -254,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
254
  version: '0'
255
255
  requirements: []
256
256
  rubyforge_project:
257
- rubygems_version: 2.7.6
257
+ rubygems_version: 2.7.7
258
258
  signing_key:
259
259
  specification_version: 4
260
260
  summary: PostgreSQL JSON-based auditing