logidze 0.4.1 → 0.5.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 +4 -4
- data/.rubocop.yml +13 -2
- data/CHANGELOG.md +11 -0
- data/README.md +32 -1
- data/lib/generators/logidze/install/templates/migration.rb.erb +35 -14
- data/lib/generators/logidze/model/model_generator.rb +33 -13
- data/lib/generators/logidze/model/templates/migration.rb.erb +1 -1
- data/lib/logidze/model.rb +56 -6
- data/lib/logidze/version.rb +1 -1
- data/lib/logidze/versioned_association.rb +52 -0
- data/lib/logidze.rb +11 -0
- data/logidze.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8e3b2e4793fe16e96a40e2059df0b137be3a6b0
|
4
|
+
data.tar.gz: 96bdab4a164cdb0180d6b91b602b1d5831245512
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b5eccd3de9563162195ca6e8350ed3136a696085485bdd95a806e6eef449b2d76b9690b4aea6558773d39df321be5bbb8998b97f5461907763643bb7f8800e2
|
7
|
+
data.tar.gz: 1b1389f59b82cb3fc637151e3c8561cea387a7d83a58dbf93805d619916b34ca0a682e0be54d88bb934ff4caa1697d2ed2986167837234fdf36f8d6513844a4b
|
data/.rubocop.yml
CHANGED
@@ -23,7 +23,7 @@ Style/Documentation:
|
|
23
23
|
Exclude:
|
24
24
|
- 'spec/**/*.rb'
|
25
25
|
|
26
|
-
Style/StringLiterals:
|
26
|
+
Style/StringLiterals:
|
27
27
|
Enabled: false
|
28
28
|
|
29
29
|
Style/SpaceInsideStringInterpolation:
|
@@ -49,4 +49,15 @@ Rails/Date:
|
|
49
49
|
Enabled: false
|
50
50
|
|
51
51
|
Rails/TimeZone:
|
52
|
-
Enabled: false
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
Style/NumericLiteralPrefix:
|
55
|
+
Enabled: false
|
56
|
+
|
57
|
+
Lint/HandleExceptions:
|
58
|
+
Enabled: true
|
59
|
+
Exclude:
|
60
|
+
- 'spec/**/*.rb'
|
61
|
+
|
62
|
+
Style/DotPosition:
|
63
|
+
EnforcedStyle: leading
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 0.5.0 (2017-03-28)
|
4
|
+
|
5
|
+
- Add an option to preserve future versions. ([@akxcv][])
|
6
|
+
|
7
|
+
- Add `--timestamp_column` option to model migration generator. ([@akxcv][])
|
8
|
+
|
9
|
+
- Default version timestamp to timestamp column. ([@akxcv][])
|
10
|
+
|
11
|
+
- Associations versioning. ([@charlie-wasp][])
|
12
|
+
|
3
13
|
## 0.4.1 (2017-02-06)
|
4
14
|
|
5
15
|
- Add `--path` option to model migration generator. ([@palkan][])
|
@@ -36,3 +46,4 @@
|
|
36
46
|
|
37
47
|
[@palkan]: https://github.com/palkan
|
38
48
|
[@charlie-wasp]: https://github.com/charlie-wasp
|
49
|
+
[@akxcv]: https://github.com/akxcv
|
data/README.md
CHANGED
@@ -75,6 +75,20 @@ By default, Logidze tries to infer the path to the model file from the model nam
|
|
75
75
|
rails generate logidze:model Post --path "app/models/custom/post.rb"
|
76
76
|
```
|
77
77
|
|
78
|
+
By default, Logidze tries to get a timestamp for a version from record's `updated_at` field whenever appropriate. If
|
79
|
+
your model does not have that column, Logidze will gracefully fall back to `statement_timestamp()`.
|
80
|
+
To change the column name or disable this feature completely, you can use the `timestamp_column` option:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
# will try to get the timestamp value from `time` column
|
84
|
+
rails generate logidze:model Post --timestamp_column time
|
85
|
+
# will always set version timestamp to `statement_timestamp()`
|
86
|
+
rails generate logidze:model Post --timestamp_column nil # "null" and "false" will also work
|
87
|
+
```
|
88
|
+
|
89
|
+
Logidze also supports associations versioning. It is experimental feature, and disabled by default. You can learn more
|
90
|
+
in the [wiki](https://github.com/palkan/logidze/wiki/Associations-versioning).
|
91
|
+
|
78
92
|
## Troubleshooting
|
79
93
|
|
80
94
|
The most common problem is `"permission denied to set parameter "logidze.xxx"` caused by `ALTER DATABASE ...` query.
|
@@ -157,7 +171,24 @@ post.redo!
|
|
157
171
|
post.switch_to!(2)
|
158
172
|
```
|
159
173
|
|
160
|
-
|
174
|
+
Normally, if you update record after `#undo!` or `#switch_to!` you lose all "future" versions and `#redo!` is no
|
175
|
+
longer possible. However, you can provide an `append: true` option to `#undo!` or `#switch_to!`, which will
|
176
|
+
create a new version with old data. Caveat: when switching to a newer version, `append` will have no effect.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
post = Post.create!(title: 'first post') # v1
|
180
|
+
post.update!(title: 'new title') # v2
|
181
|
+
post.undo!(append: true) # v3 (with same attributes as v1)
|
182
|
+
```
|
183
|
+
|
184
|
+
Note that `redo!` will not work after `undo!(append: true)` because the latter will create a new version
|
185
|
+
instead of rolling back to an old one.
|
186
|
+
Alternatively, you can configure Logidze to always default to `append: true`.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
Logidze.append_on_undo = true
|
190
|
+
```
|
191
|
+
|
161
192
|
|
162
193
|
## Track responsibility (aka _whodunnit_)
|
163
194
|
|
@@ -19,17 +19,19 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
19
19
|
execute <<-SQL
|
20
20
|
DROP FUNCTION IF EXISTS logidze_version(bigint, jsonb);
|
21
21
|
DROP FUNCTION IF EXISTS logidze_snapshot(jsonb);
|
22
|
+
DROP FUNCTION IF EXISTS logidze_version(bigint, jsonb, text[]);
|
23
|
+
DROP FUNCTION IF EXISTS logidze_snapshot(jsonb, text[]);
|
22
24
|
SQL
|
23
25
|
<% end %>
|
24
26
|
|
25
27
|
execute <<-SQL
|
26
|
-
CREATE OR REPLACE FUNCTION logidze_version(v bigint, data jsonb, blacklist text[] DEFAULT '{}') RETURNS jsonb AS $body$
|
28
|
+
CREATE OR REPLACE FUNCTION logidze_version(v bigint, data jsonb, ts timestamp with time zone, blacklist text[] DEFAULT '{}') RETURNS jsonb AS $body$
|
27
29
|
DECLARE
|
28
30
|
buf jsonb;
|
29
31
|
BEGIN
|
30
32
|
buf := jsonb_build_object(
|
31
33
|
'ts',
|
32
|
-
(extract(epoch from
|
34
|
+
(extract(epoch from ts) * 1000)::bigint,
|
33
35
|
'v',
|
34
36
|
v,
|
35
37
|
'c',
|
@@ -43,12 +45,19 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
43
45
|
$body$
|
44
46
|
LANGUAGE plpgsql;
|
45
47
|
|
46
|
-
CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb, blacklist text[] DEFAULT '{}') RETURNS jsonb AS $body$
|
48
|
+
CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb, ts_column text, blacklist text[] DEFAULT '{}') RETURNS jsonb AS $body$
|
49
|
+
DECLARE
|
50
|
+
ts timestamp with time zone;
|
47
51
|
BEGIN
|
52
|
+
IF ts_column IS NULL THEN
|
53
|
+
ts := statement_timestamp();
|
54
|
+
ELSE
|
55
|
+
ts := coalesce((item->>ts_column)::timestamp with time zone, statement_timestamp());
|
56
|
+
END IF;
|
48
57
|
return json_build_object(
|
49
58
|
'v', 1,
|
50
59
|
'h', jsonb_build_array(
|
51
|
-
logidze_version(1, item, blacklist)
|
60
|
+
logidze_version(1, item, ts, blacklist)
|
52
61
|
)
|
53
62
|
);
|
54
63
|
END;
|
@@ -62,7 +71,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
62
71
|
BEGIN
|
63
72
|
res := obj;
|
64
73
|
FOREACH key IN ARRAY keys
|
65
|
-
LOOP
|
74
|
+
LOOP
|
66
75
|
res := res - key;
|
67
76
|
END LOOP;
|
68
77
|
RETURN res;
|
@@ -93,7 +102,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
93
102
|
jsonb_set(
|
94
103
|
log_data->'h',
|
95
104
|
'{1}',
|
96
|
-
merged
|
105
|
+
merged
|
97
106
|
) - 0
|
98
107
|
);
|
99
108
|
END;
|
@@ -111,23 +120,35 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
111
120
|
iterator integer;
|
112
121
|
item record;
|
113
122
|
columns_blacklist text[];
|
123
|
+
ts timestamp with time zone;
|
124
|
+
ts_column text;
|
114
125
|
BEGIN
|
115
|
-
|
126
|
+
ts_column := NULLIF(TG_ARGV[1], 'null');
|
127
|
+
columns_blacklist := TG_ARGV[2];
|
116
128
|
|
117
129
|
IF TG_OP = 'INSERT' THEN
|
118
130
|
|
119
|
-
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*), columns_blacklist);
|
120
|
-
|
131
|
+
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*), ts_column, columns_blacklist);
|
132
|
+
|
121
133
|
ELSIF TG_OP = 'UPDATE' THEN
|
122
|
-
|
134
|
+
|
123
135
|
IF OLD.log_data is NULL OR OLD.log_data = '{}'::jsonb THEN
|
124
|
-
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*), columns_blacklist);
|
136
|
+
NEW.log_data := logidze_snapshot(to_jsonb(NEW.*), ts_column, columns_blacklist);
|
125
137
|
RETURN NEW;
|
126
138
|
END IF;
|
127
139
|
|
128
140
|
history_limit := NULLIF(TG_ARGV[0], 'null');
|
129
141
|
current_version := (NEW.log_data->>'v')::int;
|
130
142
|
|
143
|
+
IF ts_column IS NULL THEN
|
144
|
+
ts := statement_timestamp();
|
145
|
+
ELSE
|
146
|
+
ts := (to_jsonb(NEW.*)->>ts_column)::timestamp with time zone;
|
147
|
+
IF ts IS NULL OR ts = (to_jsonb(OLD.*)->>ts_column)::timestamp with time zone THEN
|
148
|
+
ts := statement_timestamp();
|
149
|
+
END IF;
|
150
|
+
END IF;
|
151
|
+
|
131
152
|
IF NEW = OLD THEN
|
132
153
|
RETURN NEW;
|
133
154
|
END IF;
|
@@ -158,7 +179,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
158
179
|
NEW.log_data := jsonb_set(
|
159
180
|
NEW.log_data,
|
160
181
|
ARRAY['h', size::text],
|
161
|
-
logidze_version(new_v, changes, columns_blacklist),
|
182
|
+
logidze_version(new_v, changes, ts, columns_blacklist),
|
162
183
|
true
|
163
184
|
);
|
164
185
|
|
@@ -183,9 +204,9 @@ class <%= @migration_class_name %> < ActiveRecord::Migration
|
|
183
204
|
def down
|
184
205
|
<% unless update? %>
|
185
206
|
execute <<-SQL
|
186
|
-
DROP FUNCTION logidze_version(bigint, jsonb, text[]) CASCADE;
|
207
|
+
DROP FUNCTION logidze_version(bigint, jsonb, timestamp with time zone, text[]) CASCADE;
|
187
208
|
DROP FUNCTION logidze_compact_history(jsonb) CASCADE;
|
188
|
-
DROP FUNCTION logidze_snapshot(jsonb, text[]) CASCADE;
|
209
|
+
DROP FUNCTION logidze_snapshot(jsonb, text, text[]) CASCADE;
|
189
210
|
DROP FUNCTION logidze_logger() CASCADE;
|
190
211
|
SQL
|
191
212
|
<% end %>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# rubocop:disable Metrics/BlockLength
|
1
2
|
# frozen_string_literal: true
|
2
3
|
require "rails/generators"
|
3
4
|
require "rails/generators/active_record/migration/migration_generator"
|
@@ -20,6 +21,9 @@ module Logidze
|
|
20
21
|
class_option :blacklist, type: :array, optional: true
|
21
22
|
class_option :whitelist, type: :array, optional: true
|
22
23
|
|
24
|
+
class_option :timestamp_column, type: :string, optional: true,
|
25
|
+
desc: "Specify timestamp column"
|
26
|
+
|
23
27
|
def generate_migration
|
24
28
|
if options[:blacklist] && options[:whitelist]
|
25
29
|
$stderr.puts "Use only one: --whitelist or --blacklist"
|
@@ -62,30 +66,46 @@ module Logidze
|
|
62
66
|
class_name.constantize.column_names - options[:whitelist]
|
63
67
|
end
|
64
68
|
|
65
|
-
array
|
69
|
+
format_pgsql_array(array)
|
70
|
+
end
|
71
|
+
|
72
|
+
def timestamp_column
|
73
|
+
value = options[:timestamp_column] || 'updated_at'
|
74
|
+
return if %w(nil null false).include?(value)
|
75
|
+
escape_pgsql_string(value)
|
66
76
|
end
|
67
77
|
|
68
78
|
def logidze_logger_parameters
|
69
|
-
|
70
|
-
''
|
71
|
-
elsif !limit.nil? && columns_blacklist.empty?
|
72
|
-
limit
|
73
|
-
elsif !limit.nil? && !columns_blacklist.empty?
|
74
|
-
"#{limit}, #{format_pgsql_array(columns_blacklist)}"
|
75
|
-
elsif limit.nil? && !columns_blacklist.empty?
|
76
|
-
"null, #{format_pgsql_array(columns_blacklist)}"
|
77
|
-
end
|
79
|
+
format_pgsql_args(limit, timestamp_column, columns_blacklist)
|
78
80
|
end
|
79
81
|
|
80
82
|
def logidze_snapshot_parameters
|
81
|
-
|
82
|
-
|
83
|
-
"to_jsonb(t), #{format_pgsql_array(columns_blacklist)}"
|
83
|
+
format_pgsql_args('to_jsonb(t)', timestamp_column, columns_blacklist)
|
84
84
|
end
|
85
85
|
|
86
86
|
def format_pgsql_array(ruby_array)
|
87
|
+
return if ruby_array.blank?
|
87
88
|
"'{" + ruby_array.join(', ') + "}'"
|
88
89
|
end
|
90
|
+
|
91
|
+
def escape_pgsql_string(string)
|
92
|
+
return if string.blank?
|
93
|
+
"'#{string}'"
|
94
|
+
end
|
95
|
+
|
96
|
+
# Convenience method for formatting pg arguments.
|
97
|
+
# Some examples:
|
98
|
+
# format_pgsql_args('a', 'b', nil) #=> "a, b"
|
99
|
+
# format_pgsql_args(nil, '', 'c') #=> "null, null, c"
|
100
|
+
# format_pgsql_args('a', '', []) #=> "a"
|
101
|
+
def format_pgsql_args(*values)
|
102
|
+
args = []
|
103
|
+
values.reverse_each do |value|
|
104
|
+
formatted_value = value.presence || (args.any? && 'null')
|
105
|
+
args << formatted_value if formatted_value
|
106
|
+
end
|
107
|
+
args.compact.reverse.join(', ')
|
108
|
+
end
|
89
109
|
end
|
90
110
|
|
91
111
|
private
|
data/lib/logidze/model.rb
CHANGED
@@ -33,23 +33,38 @@ module Logidze
|
|
33
33
|
def without_logging(&block)
|
34
34
|
Logidze.without_logging(&block)
|
35
35
|
end
|
36
|
+
|
37
|
+
def has_logidze?
|
38
|
+
true
|
39
|
+
end
|
36
40
|
end
|
37
41
|
|
38
42
|
# Use this to convert Ruby time to milliseconds
|
39
43
|
TIME_FACTOR = 1_000
|
40
44
|
|
45
|
+
attr_accessor :logidze_requested_ts
|
46
|
+
|
41
47
|
# Return a dirty copy of record at specified time
|
42
48
|
# If time is less then the first version, then return nil.
|
43
49
|
# If time is greater then the last version, then return self.
|
44
50
|
def at(ts)
|
45
51
|
ts = parse_time(ts)
|
52
|
+
|
46
53
|
return nil unless log_data.exists_ts?(ts)
|
47
|
-
|
54
|
+
|
55
|
+
if log_data.current_ts?(ts)
|
56
|
+
self.logidze_requested_ts = ts
|
57
|
+
return self
|
58
|
+
end
|
48
59
|
|
49
60
|
version = log_data.find_by_time(ts).version
|
50
61
|
|
51
62
|
object_at = dup
|
52
63
|
object_at.apply_diff(version, log_data.changes_to(version: version))
|
64
|
+
object_at.id = id
|
65
|
+
object_at.logidze_requested_ts = ts
|
66
|
+
|
67
|
+
object_at
|
53
68
|
end
|
54
69
|
|
55
70
|
# Revert record to the version at specified time (without saving to DB)
|
@@ -93,10 +108,10 @@ module Logidze
|
|
93
108
|
|
94
109
|
# Restore record to the previous version.
|
95
110
|
# Return false if no previous version found, otherwise return updated record.
|
96
|
-
def undo!
|
111
|
+
def undo!(append: Logidze.append_on_undo)
|
97
112
|
version = log_data.previous_version
|
98
113
|
return false if version.nil?
|
99
|
-
switch_to!(version.version)
|
114
|
+
switch_to!(version.version, append: append)
|
100
115
|
end
|
101
116
|
|
102
117
|
# Restore record to the _future_ version (if `undo!` was applied)
|
@@ -109,9 +124,38 @@ module Logidze
|
|
109
124
|
|
110
125
|
# Restore record to the specified version.
|
111
126
|
# Return false if version is unknown.
|
112
|
-
def switch_to!(version)
|
113
|
-
return false unless at_version
|
114
|
-
|
127
|
+
def switch_to!(version, append: Logidze.append_on_undo)
|
128
|
+
return false unless at_version(version)
|
129
|
+
|
130
|
+
if append && version < log_version
|
131
|
+
update!(log_data.changes_to(version: version))
|
132
|
+
else
|
133
|
+
at_version!(version)
|
134
|
+
self.class.without_logging { save! }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def association(name)
|
139
|
+
association = super
|
140
|
+
|
141
|
+
return association unless Logidze.associations_versioning
|
142
|
+
|
143
|
+
should_appply_logidze =
|
144
|
+
logidze_past? &&
|
145
|
+
association.klass.respond_to?(:has_logidze?) &&
|
146
|
+
!association.singleton_class.include?(Logidze::VersionedAssociation)
|
147
|
+
|
148
|
+
return association unless should_appply_logidze
|
149
|
+
|
150
|
+
association.singleton_class.prepend Logidze::VersionedAssociation
|
151
|
+
|
152
|
+
if association.is_a? ActiveRecord::Associations::CollectionAssociation
|
153
|
+
association.singleton_class.prepend(
|
154
|
+
Logidze::VersionedAssociation::CollectionAssociation
|
155
|
+
)
|
156
|
+
end
|
157
|
+
|
158
|
+
association
|
115
159
|
end
|
116
160
|
|
117
161
|
protected
|
@@ -122,6 +166,12 @@ module Logidze
|
|
122
166
|
self
|
123
167
|
end
|
124
168
|
|
169
|
+
def logidze_past?
|
170
|
+
return false unless @logidze_requested_ts
|
171
|
+
|
172
|
+
@logidze_requested_ts < Time.now.to_i * TIME_FACTOR
|
173
|
+
end
|
174
|
+
|
125
175
|
def parse_time(ts)
|
126
176
|
case ts
|
127
177
|
when Numeric
|
data/lib/logidze/version.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Logidze
|
3
|
+
module VersionedAssociation
|
4
|
+
def load_target
|
5
|
+
target = super
|
6
|
+
|
7
|
+
return target if inversed
|
8
|
+
|
9
|
+
time = owner.logidze_requested_ts
|
10
|
+
|
11
|
+
if target.is_a? Array
|
12
|
+
target.map! do |object|
|
13
|
+
object.at(time)
|
14
|
+
end.compact!
|
15
|
+
else
|
16
|
+
target.at!(time)
|
17
|
+
end
|
18
|
+
|
19
|
+
target
|
20
|
+
end
|
21
|
+
|
22
|
+
def stale_target?
|
23
|
+
logidze_stale? || super
|
24
|
+
end
|
25
|
+
|
26
|
+
def logidze_stale?
|
27
|
+
return false if !loaded? || inversed
|
28
|
+
|
29
|
+
unless target.is_a?(Array)
|
30
|
+
return owner.logidze_requested_ts != target.logidze_requested_ts
|
31
|
+
end
|
32
|
+
|
33
|
+
return false if target.empty?
|
34
|
+
|
35
|
+
target.any? do |object|
|
36
|
+
owner.logidze_requested_ts != object.logidze_requested_ts
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module CollectionAssociation
|
41
|
+
def ids_reader
|
42
|
+
reload unless loaded?
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
def empty?
|
47
|
+
reload unless loaded?
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/logidze.rb
CHANGED
@@ -6,6 +6,7 @@ require "logidze/version"
|
|
6
6
|
module Logidze
|
7
7
|
require 'logidze/history'
|
8
8
|
require 'logidze/model'
|
9
|
+
require 'logidze/versioned_association'
|
9
10
|
require 'logidze/has_logidze'
|
10
11
|
require 'logidze/responsible'
|
11
12
|
|
@@ -13,6 +14,16 @@ module Logidze
|
|
13
14
|
|
14
15
|
require 'logidze/engine' if defined?(Rails)
|
15
16
|
|
17
|
+
class << self
|
18
|
+
# Determines if Logidze should append a version to the log after updating an old version.
|
19
|
+
attr_accessor :append_on_undo
|
20
|
+
attr_writer :associations_versioning
|
21
|
+
|
22
|
+
def associations_versioning
|
23
|
+
@associations_versioning || false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
16
27
|
# Temporary disable DB triggers.
|
17
28
|
#
|
18
29
|
# @example
|
data/logidze.gemspec
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.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: timecop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.8'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.8'
|
139
153
|
description: PostgreSQL JSON-based auditing
|
140
154
|
email:
|
141
155
|
- dementiev.vm@gmail.com
|
@@ -189,6 +203,7 @@ files:
|
|
189
203
|
- lib/logidze/model.rb
|
190
204
|
- lib/logidze/responsible.rb
|
191
205
|
- lib/logidze/version.rb
|
206
|
+
- lib/logidze/versioned_association.rb
|
192
207
|
- logidze.gemspec
|
193
208
|
homepage: http://github.com/palkan/logidze
|
194
209
|
licenses:
|