logidze 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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