logidze 0.0.1 → 0.1.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/.gitignore +40 -9
- data/.rubocop.yml +3 -1
- data/.travis.yml +36 -3
- data/CHANGELOG.md +0 -0
- data/Gemfile +0 -1
- data/README.md +144 -9
- data/Rakefile +20 -1
- data/bench/Makefile +37 -9
- data/bench/Readme.md +58 -0
- data/bench/jsonb_minus_2_setup.sql +47 -0
- data/bench/jsonb_minus_setup.sql +49 -0
- data/bench/keys2_trigger_setup.sql +44 -0
- data/bin/console +7 -0
- data/bin/setup +9 -0
- data/circle.yml +17 -0
- data/gemfiles/rails42.gemfile +5 -0
- data/gemfiles/rails5.gemfile +5 -0
- data/lib/generators/logidze/install/USAGE +7 -0
- data/lib/generators/logidze/install/install_generator.rb +25 -0
- data/lib/generators/logidze/install/templates/hstore.rb.erb +5 -0
- data/lib/generators/logidze/install/templates/migration.rb.erb +131 -0
- data/lib/generators/logidze/model/USAGE +8 -0
- data/lib/generators/logidze/model/model_generator.rb +43 -0
- data/lib/generators/logidze/model/templates/migration.rb.erb +18 -0
- data/lib/logidze.rb +21 -1
- data/lib/logidze/engine.rb +12 -0
- data/lib/logidze/has_logidze.rb +18 -0
- data/lib/logidze/history.rb +156 -0
- data/lib/logidze/model.rb +128 -0
- data/lib/logidze/version.rb +2 -1
- data/logidze.gemspec +7 -2
- metadata +101 -11
data/lib/logidze.rb
CHANGED
@@ -1,5 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "logidze/version"
|
2
3
|
|
4
|
+
# Logidze provides tools for adding in-table JSON-based audit to DB tables
|
5
|
+
# and ActiveRecord extensions to work with changes history.
|
3
6
|
module Logidze
|
4
|
-
|
7
|
+
require 'logidze/history'
|
8
|
+
require 'logidze/model'
|
9
|
+
require 'logidze/has_logidze'
|
10
|
+
|
11
|
+
require 'logidze/engine' if defined?(Rails)
|
12
|
+
|
13
|
+
# Temporary disable DB triggers.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# Logidze.without_logging { Post.update_all(active: true) }
|
17
|
+
def self.without_logging
|
18
|
+
ActiveRecord::Base.transaction do
|
19
|
+
ActiveRecord::Base.connection.execute "SET LOCAL logidze.disabled = 'on';"
|
20
|
+
res = yield
|
21
|
+
ActiveRecord::Base.connection.execute "SET LOCAL logidze.disabled = DEFAULT;"
|
22
|
+
res
|
23
|
+
end
|
24
|
+
end
|
5
25
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'logidze'
|
3
|
+
|
4
|
+
module Logidze
|
5
|
+
class Engine < Rails::Engine # :nodoc:
|
6
|
+
initializer "extend ActiveRecord with Logidze" do |_app|
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
ActiveRecord::Base.send :include, Logidze::HasLogidze
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
module Logidze
|
5
|
+
# Add `has_logidze` method to AR::Base
|
6
|
+
module HasLogidze
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods # :nodoc:
|
10
|
+
# Include methods to work with history.
|
11
|
+
#
|
12
|
+
# rubocop:disable Style/PredicateName
|
13
|
+
def has_logidze
|
14
|
+
include Logidze::Model
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Logidze
|
3
|
+
# Log data coder used for attribute serialization
|
4
|
+
class History
|
5
|
+
# History key
|
6
|
+
HISTORY = 'h'
|
7
|
+
# Version key
|
8
|
+
VERSION = 'v'
|
9
|
+
|
10
|
+
# Represents one log item
|
11
|
+
class Version
|
12
|
+
# Timestamp key
|
13
|
+
TS = 'ts'
|
14
|
+
# Changes key
|
15
|
+
CHANGES = 'c'
|
16
|
+
|
17
|
+
attr_reader :data
|
18
|
+
|
19
|
+
def initialize(data)
|
20
|
+
@data = data
|
21
|
+
end
|
22
|
+
|
23
|
+
def version
|
24
|
+
data.fetch(VERSION)
|
25
|
+
end
|
26
|
+
|
27
|
+
def changes
|
28
|
+
data.fetch(CHANGES)
|
29
|
+
end
|
30
|
+
|
31
|
+
def time
|
32
|
+
data.fetch(TS)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.dump(object)
|
37
|
+
ActiveSupport::JSON.encode(object)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.load(json)
|
41
|
+
new(json) unless json.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :data
|
45
|
+
|
46
|
+
delegate :size, to: :versions
|
47
|
+
|
48
|
+
def initialize(data)
|
49
|
+
@data = data
|
50
|
+
end
|
51
|
+
|
52
|
+
def versions
|
53
|
+
@versions ||= data.fetch(HISTORY).map { |v| Version.new(v) }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns current version number
|
57
|
+
def version
|
58
|
+
data.fetch(VERSION)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Change current version
|
62
|
+
def version=(val)
|
63
|
+
data.store(VERSION, val)
|
64
|
+
end
|
65
|
+
|
66
|
+
def current_version
|
67
|
+
find_by_version(version)
|
68
|
+
end
|
69
|
+
|
70
|
+
def previous_version
|
71
|
+
find_by_version(version - 1)
|
72
|
+
end
|
73
|
+
|
74
|
+
def next_version
|
75
|
+
find_by_version(version + 1)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return diff from the initial state to specified time or version.
|
79
|
+
# Optional `data` paramater can be used as initial diff state.
|
80
|
+
def changes_to(time: nil, version: nil, data: {}, from: 0)
|
81
|
+
raise ArgumentError, "Time or version must be specified" if time.nil? && version.nil?
|
82
|
+
filter = time.nil? ? method(:version_filter) : method(:time_filter)
|
83
|
+
versions.each_with_object(data.dup) do |v, acc|
|
84
|
+
next if v.version < from
|
85
|
+
break acc if filter.call(v, version, time)
|
86
|
+
acc.merge!(v.changes)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return diff object representing changes since specified time or version.
|
91
|
+
#
|
92
|
+
# @example
|
93
|
+
#
|
94
|
+
# diff_from(time: 2.days.ago)
|
95
|
+
# #=> { "id" => 1, "changes" => { "title" => { "old" => "Hello!", "new" => "World" } } }
|
96
|
+
# rubocop:disable Metrics/AbcSize
|
97
|
+
def diff_from(time: nil, version: nil)
|
98
|
+
raise ArgumentError, "Time or version must be specified" if time.nil? && version.nil?
|
99
|
+
|
100
|
+
from_version = version.nil? ? find_by_time(time) : find_by_version(version)
|
101
|
+
from_version ||= versions.first
|
102
|
+
|
103
|
+
base = changes_to(version: from_version.version)
|
104
|
+
diff = changes_to(version: self.version, data: base, from: from_version.version + 1)
|
105
|
+
|
106
|
+
build_changes(base, diff)
|
107
|
+
end
|
108
|
+
# rubocop:enable Metrics/AbcSize
|
109
|
+
|
110
|
+
# Return true iff time greater or equal to the first version time
|
111
|
+
def exists_ts?(time)
|
112
|
+
versions.present? && versions.first.time <= time
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return true iff time corresponds to current version
|
116
|
+
def current_ts?(time)
|
117
|
+
(current_version.time <= time) &&
|
118
|
+
(next_version.nil? || (next_version.time < time))
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return version by number or nil
|
122
|
+
def find_by_version(num)
|
123
|
+
versions.find { |v| v.version == num }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Return nearest (from the bottom) version to the specified time
|
127
|
+
def find_by_time(time)
|
128
|
+
versions.reverse.find { |v| v.time <= time }
|
129
|
+
end
|
130
|
+
|
131
|
+
def ==(other)
|
132
|
+
return super unless other.is_a?(self.class)
|
133
|
+
data == other.data
|
134
|
+
end
|
135
|
+
|
136
|
+
def as_json(options = {})
|
137
|
+
data.as_json(options)
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def build_changes(a, b)
|
143
|
+
b.each_with_object({}) do |kv, acc|
|
144
|
+
acc[kv.first] = { "old" => a[kv.first], "new" => kv.last } unless kv.last == a[kv.first]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def version_filter(item, version, _)
|
149
|
+
item.version > version
|
150
|
+
end
|
151
|
+
|
152
|
+
def time_filter(item, _, time)
|
153
|
+
item.time > time
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
module Logidze
|
5
|
+
# Extends model with methods to browse history
|
6
|
+
module Model
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
serialize :log_data, Logidze::History
|
11
|
+
|
12
|
+
delegate :version, :size, to: :log_data, prefix: "log"
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods # :nodoc:
|
16
|
+
# Return records reverted to specified time
|
17
|
+
def at(ts)
|
18
|
+
all.map { |record| record.at(ts) }.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return changes made to records since specified time
|
22
|
+
def diff_from(ts)
|
23
|
+
all.map { |record| record.diff_from(ts) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Alias for Logidze.without_logging
|
27
|
+
def without_logging(&block)
|
28
|
+
Logidze.without_logging(&block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Use this to convert Ruby time to milliseconds
|
33
|
+
TIME_FACTOR = 1_000
|
34
|
+
|
35
|
+
# Return a dirty copy of record at specified time
|
36
|
+
# If time is less then the first version, then return nil.
|
37
|
+
# If time is greater then the last version, then return self.
|
38
|
+
def at(ts)
|
39
|
+
ts = parse_time(ts)
|
40
|
+
return nil unless log_data.exists_ts?(ts)
|
41
|
+
return self if log_data.current_ts?(ts)
|
42
|
+
|
43
|
+
object_at = dup
|
44
|
+
object_at.apply_diff(log_data.changes_to(time: ts))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Revert record to the version at specified time (without saving to DB)
|
48
|
+
def at!(ts)
|
49
|
+
ts = parse_time(ts)
|
50
|
+
return self if log_data.current_ts?(ts)
|
51
|
+
return false unless log_data.exists_ts?(ts)
|
52
|
+
|
53
|
+
apply_diff(log_data.changes_to(time: ts))
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return a dirty copy of specified version of record
|
57
|
+
def at_version(version)
|
58
|
+
return self if log_data.version == version
|
59
|
+
return nil unless log_data.find_by_version(version)
|
60
|
+
|
61
|
+
object_at = dup
|
62
|
+
object_at.apply_diff(log_data.changes_to(version: version))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Revert record to the specified version (without saving to DB)
|
66
|
+
def at_version!(version)
|
67
|
+
return self if log_data.version == version
|
68
|
+
return false unless log_data.find_by_version(version)
|
69
|
+
|
70
|
+
apply_diff(log_data.changes_to(version: version))
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return diff object representing changes since specified time.
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
#
|
77
|
+
# post.diff_from(2.days.ago)
|
78
|
+
# #=> { "id" => 1, "changes" => { "title" => { "old" => "Hello!", "new" => "World" } } }
|
79
|
+
def diff_from(ts)
|
80
|
+
ts = parse_time(ts)
|
81
|
+
{ "id" => id, "changes" => log_data.diff_from(time: ts) }
|
82
|
+
end
|
83
|
+
|
84
|
+
# Restore record to the previous version.
|
85
|
+
# Return false if no previous version found, otherwise return updated record.
|
86
|
+
def undo!
|
87
|
+
version = log_data.previous_version
|
88
|
+
return false if version.nil?
|
89
|
+
switch_to!(version.version)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Restore record to the _future_ version (if `undo!` was applied)
|
93
|
+
# Return false if no future version found, otherwise return updated record.
|
94
|
+
def redo!
|
95
|
+
version = log_data.next_version
|
96
|
+
return false if version.nil?
|
97
|
+
switch_to!(version.version)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Restore record to the specified version.
|
101
|
+
# Return false if version is unknown.
|
102
|
+
def switch_to!(version)
|
103
|
+
return false unless at_version!(version)
|
104
|
+
log_data.version = version
|
105
|
+
self.class.without_logging { save! }
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
|
110
|
+
def apply_diff(diff)
|
111
|
+
diff.each { |k, v| send("#{k}=", v) }
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
def parse_time(ts)
|
116
|
+
case ts
|
117
|
+
when Numeric
|
118
|
+
ts.to_i
|
119
|
+
when String
|
120
|
+
(Time.parse(ts).to_r * TIME_FACTOR).to_i
|
121
|
+
when Date
|
122
|
+
(ts.to_time.to_r * TIME_FACTOR).to_i
|
123
|
+
when Time
|
124
|
+
(ts.to_r * TIME_FACTOR).to_i
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/logidze/version.rb
CHANGED
data/logidze.gemspec
CHANGED
@@ -17,10 +17,15 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.
|
20
|
+
spec.add_dependency "rails", ">= 4.2.6"
|
21
21
|
|
22
22
|
spec.add_development_dependency "pg", "~>0.18"
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.11"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
-
spec.add_development_dependency "rspec", "
|
25
|
+
spec.add_development_dependency "rspec", ">= 3.4"
|
26
|
+
spec.add_development_dependency "rspec-rails", ">= 3.4"
|
27
|
+
spec.add_development_dependency "database_cleaner", "~> 1.5"
|
28
|
+
spec.add_development_dependency "simplecov", ">= 0.3.8"
|
29
|
+
spec.add_development_dependency "ammeter", "~> 1.1.3"
|
30
|
+
spec.add_development_dependency "pry-byebug"
|
26
31
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logidze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.2.6
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 4.2.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +70,86 @@ dependencies:
|
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '3.4'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '3.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: database_cleaner
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.8
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.3.8
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: ammeter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.1.3
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.1.3
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry-byebug
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
83
153
|
description: PostgreSQL JSON-based auditing
|
84
154
|
email:
|
85
155
|
- dementiev.vm@gmail.com
|
@@ -91,15 +161,36 @@ files:
|
|
91
161
|
- ".rspec"
|
92
162
|
- ".rubocop.yml"
|
93
163
|
- ".travis.yml"
|
164
|
+
- CHANGELOG.md
|
94
165
|
- Gemfile
|
95
166
|
- LICENSE.txt
|
96
167
|
- README.md
|
97
168
|
- Rakefile
|
98
169
|
- bench/Makefile
|
170
|
+
- bench/Readme.md
|
99
171
|
- bench/bench.sql
|
100
172
|
- bench/hstore_trigger_setup.sql
|
173
|
+
- bench/jsonb_minus_2_setup.sql
|
174
|
+
- bench/jsonb_minus_setup.sql
|
175
|
+
- bench/keys2_trigger_setup.sql
|
101
176
|
- bench/keys_trigger_setup.sql
|
177
|
+
- bin/console
|
178
|
+
- bin/setup
|
179
|
+
- circle.yml
|
180
|
+
- gemfiles/rails42.gemfile
|
181
|
+
- gemfiles/rails5.gemfile
|
182
|
+
- lib/generators/logidze/install/USAGE
|
183
|
+
- lib/generators/logidze/install/install_generator.rb
|
184
|
+
- lib/generators/logidze/install/templates/hstore.rb.erb
|
185
|
+
- lib/generators/logidze/install/templates/migration.rb.erb
|
186
|
+
- lib/generators/logidze/model/USAGE
|
187
|
+
- lib/generators/logidze/model/model_generator.rb
|
188
|
+
- lib/generators/logidze/model/templates/migration.rb.erb
|
102
189
|
- lib/logidze.rb
|
190
|
+
- lib/logidze/engine.rb
|
191
|
+
- lib/logidze/has_logidze.rb
|
192
|
+
- lib/logidze/history.rb
|
193
|
+
- lib/logidze/model.rb
|
103
194
|
- lib/logidze/version.rb
|
104
195
|
- logidze.gemspec
|
105
196
|
homepage: http://github.com/palkan/logidze
|
@@ -122,9 +213,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
213
|
version: '0'
|
123
214
|
requirements: []
|
124
215
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.
|
216
|
+
rubygems_version: 2.6.4
|
126
217
|
signing_key:
|
127
218
|
specification_version: 4
|
128
219
|
summary: PostgreSQL JSON-based auditing
|
129
220
|
test_files: []
|
130
|
-
has_rdoc:
|