logidze 0.9.0 → 1.0.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/CHANGELOG.md +101 -5
- data/LICENSE.txt +1 -1
- data/README.md +309 -89
- data/lib/generators/logidze/fx_helper.rb +17 -0
- data/lib/generators/logidze/inject_sql.rb +18 -0
- data/lib/generators/logidze/install/USAGE +6 -1
- data/lib/generators/logidze/install/functions/logidze_compact_history.sql +38 -0
- data/lib/generators/logidze/install/functions/logidze_filter_keys.sql +27 -0
- data/lib/generators/logidze/install/functions/logidze_logger.sql +150 -0
- data/lib/generators/logidze/install/functions/logidze_snapshot.sql +24 -0
- data/lib/generators/logidze/install/functions/logidze_version.sql +20 -0
- data/lib/generators/logidze/install/install_generator.rb +61 -3
- data/lib/generators/logidze/install/templates/hstore.rb.erb +1 -1
- data/lib/generators/logidze/install/templates/migration.rb.erb +19 -232
- data/lib/generators/logidze/install/templates/migration_fx.rb.erb +41 -0
- data/lib/generators/logidze/model/model_generator.rb +60 -20
- data/lib/generators/logidze/model/templates/migration.rb.erb +57 -36
- data/lib/generators/logidze/model/triggers/logidze.sql +6 -0
- data/lib/logidze.rb +43 -21
- data/lib/logidze/engine.rb +4 -1
- data/lib/logidze/has_logidze.rb +12 -4
- data/lib/logidze/history.rb +7 -15
- data/lib/logidze/history/type.rb +1 -1
- data/lib/logidze/history/version.rb +6 -5
- data/lib/logidze/ignore_log_data.rb +11 -19
- data/lib/logidze/meta.rb +44 -17
- data/lib/logidze/model.rb +63 -46
- data/lib/logidze/version.rb +2 -1
- data/lib/logidze/versioned_association.rb +0 -1
- metadata +43 -103
- data/.gitignore +0 -40
- data/.hound.yml +0 -3
- data/.rubocop.yml +0 -94
- data/.travis.yml +0 -39
- data/Gemfile +0 -13
- data/Rakefile +0 -28
- data/bench/performance/README.md +0 -109
- data/bench/performance/diff_bench.rb +0 -36
- data/bench/performance/insert_bench.rb +0 -20
- data/bench/performance/memory_profile.rb +0 -53
- data/bench/performance/setup.rb +0 -308
- data/bench/performance/update_bench.rb +0 -36
- data/bench/triggers/Makefile +0 -56
- data/bench/triggers/Readme.md +0 -58
- data/bench/triggers/bench.sql +0 -6
- data/bench/triggers/hstore_trigger_setup.sql +0 -38
- data/bench/triggers/jsonb_minus_2_setup.sql +0 -47
- data/bench/triggers/jsonb_minus_setup.sql +0 -49
- data/bench/triggers/keys2_trigger_setup.sql +0 -44
- data/bench/triggers/keys_trigger_setup.sql +0 -50
- data/bin/console +0 -8
- data/bin/setup +0 -9
- data/gemfiles/rails42.gemfile +0 -5
- data/gemfiles/rails5.gemfile +0 -6
- data/gemfiles/rails52.gemfile +0 -6
- data/gemfiles/railsmaster.gemfile +0 -7
- data/lib/logidze/ignore_log_data/ignored_columns.rb +0 -46
- data/lib/logidze/ignore_log_data/missing_attribute_patch.rb +0 -16
- data/lib/logidze/migration.rb +0 -19
- data/logidze.gemspec +0 -33
data/.gitignore
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# Numerous always-ignore extensions
|
2
|
-
*.diff
|
3
|
-
*.err
|
4
|
-
*.orig
|
5
|
-
*.log
|
6
|
-
*.rej
|
7
|
-
*.swo
|
8
|
-
*.swp
|
9
|
-
*.vi
|
10
|
-
*~
|
11
|
-
*.sass-cache
|
12
|
-
*.iml
|
13
|
-
.idea/
|
14
|
-
|
15
|
-
# Sublime
|
16
|
-
*.sublime-project
|
17
|
-
*.sublime-workspace
|
18
|
-
|
19
|
-
# OS or Editor folders
|
20
|
-
.DS_Store
|
21
|
-
.cache
|
22
|
-
.project
|
23
|
-
.settings
|
24
|
-
.tmproj
|
25
|
-
Thumbs.db
|
26
|
-
|
27
|
-
.bundle/
|
28
|
-
log/*.log
|
29
|
-
*.gz
|
30
|
-
pkg/
|
31
|
-
spec/dummy/db/*.sqlite3
|
32
|
-
spec/dummy/db/*.sqlite3-journal
|
33
|
-
spec/dummy/tmp/
|
34
|
-
|
35
|
-
Gemfile.lock
|
36
|
-
Gemfile.local
|
37
|
-
.rspec
|
38
|
-
*.gem
|
39
|
-
tmp/
|
40
|
-
coverage/
|
data/.hound.yml
DELETED
data/.rubocop.yml
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
require:
|
2
|
-
- rubocop-md
|
3
|
-
|
4
|
-
AllCops:
|
5
|
-
# Include gemspec and Rakefile
|
6
|
-
Include:
|
7
|
-
- 'lib/**/*.rb'
|
8
|
-
- 'lib/**/*.rake'
|
9
|
-
- 'spec/**/*.rb'
|
10
|
-
Exclude:
|
11
|
-
- 'bin/**/*'
|
12
|
-
- 'spec/dummy/**/*'
|
13
|
-
- 'vendor/**/*'
|
14
|
-
- 'gemfiles/**/*'
|
15
|
-
- 'tmp/**/*'
|
16
|
-
- 'bench/**/*'
|
17
|
-
- 'Rakefile'
|
18
|
-
- 'Gemfile'
|
19
|
-
- '*.gemspec'
|
20
|
-
DisplayCopNames: true
|
21
|
-
StyleGuideCopsOnly: false
|
22
|
-
TargetRubyVersion: 2.3
|
23
|
-
|
24
|
-
Naming/AccessorMethodName:
|
25
|
-
Enabled: false
|
26
|
-
|
27
|
-
Naming/UncommunicativeMethodParamName:
|
28
|
-
Enabled: false
|
29
|
-
|
30
|
-
Style/TrivialAccessors:
|
31
|
-
Enabled: false
|
32
|
-
|
33
|
-
Style/Documentation:
|
34
|
-
Exclude:
|
35
|
-
- 'spec/**/*.rb'
|
36
|
-
|
37
|
-
Style/StringLiterals:
|
38
|
-
Enabled: false
|
39
|
-
|
40
|
-
Layout/SpaceInsideStringInterpolation:
|
41
|
-
EnforcedStyle: no_space
|
42
|
-
|
43
|
-
Style/BlockDelimiters:
|
44
|
-
Exclude:
|
45
|
-
- 'spec/**/*.rb'
|
46
|
-
|
47
|
-
Style/PercentLiteralDelimiters:
|
48
|
-
Enabled: false
|
49
|
-
|
50
|
-
Lint/AmbiguousRegexpLiteral:
|
51
|
-
Enabled: false
|
52
|
-
|
53
|
-
Lint/MissingCopEnableDirective:
|
54
|
-
Enabled: false
|
55
|
-
|
56
|
-
Lint/UselessAssignment:
|
57
|
-
Exclude:
|
58
|
-
- '**/*.md'
|
59
|
-
|
60
|
-
Metrics/MethodLength:
|
61
|
-
Exclude:
|
62
|
-
- 'spec/**/*.rb'
|
63
|
-
|
64
|
-
Metrics/BlockLength:
|
65
|
-
Exclude:
|
66
|
-
- 'spec/**/*.rb'
|
67
|
-
|
68
|
-
Metrics/LineLength:
|
69
|
-
Max: 100
|
70
|
-
Exclude:
|
71
|
-
- 'spec/**/*.rb'
|
72
|
-
|
73
|
-
Rails/Date:
|
74
|
-
Enabled: false
|
75
|
-
|
76
|
-
Rails/TimeZone:
|
77
|
-
Enabled: false
|
78
|
-
|
79
|
-
Style/NumericLiteralPrefix:
|
80
|
-
Enabled: false
|
81
|
-
|
82
|
-
Lint/HandleExceptions:
|
83
|
-
Enabled: true
|
84
|
-
Exclude:
|
85
|
-
- 'spec/**/*.rb'
|
86
|
-
|
87
|
-
Layout/DotPosition:
|
88
|
-
EnforcedStyle: leading
|
89
|
-
|
90
|
-
Layout/IndentHeredoc:
|
91
|
-
Enabled: false
|
92
|
-
|
93
|
-
Layout/EmptyLineAfterMagicComment:
|
94
|
-
Enabled: false
|
data/.travis.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
|
4
|
-
dist: trusty
|
5
|
-
sudo: false
|
6
|
-
|
7
|
-
addons:
|
8
|
-
postgresql: "9.6"
|
9
|
-
|
10
|
-
env:
|
11
|
-
global:
|
12
|
-
- LOGIDZE_DB_USER=postgres
|
13
|
-
- LOGIDZE_DB_NAME=logidze
|
14
|
-
|
15
|
-
before_script:
|
16
|
-
- gem update --system
|
17
|
-
- bundle exec rake dummy:db:create
|
18
|
-
- psql -U postgres -d logidze -c 'CREATE EXTENSION IF NOT EXISTS hstore;'
|
19
|
-
- bundle exec rake dummy:db:test:prepare
|
20
|
-
|
21
|
-
matrix:
|
22
|
-
include:
|
23
|
-
- rvm: ruby-head
|
24
|
-
gemfile: gemfiles/railsmaster.gemfile
|
25
|
-
- rvm: 2.5.0
|
26
|
-
gemfile: gemfiles/railsmaster.gemfile
|
27
|
-
- rvm: 2.5.0
|
28
|
-
gemfile: gemfiles/rails5.gemfile
|
29
|
-
- rvm: 2.5.1
|
30
|
-
gemfile: gemfiles/rails52.gemfile
|
31
|
-
- rvm: 2.4.1
|
32
|
-
gemfile: gemfiles/rails5.gemfile
|
33
|
-
- rvm: 2.3.1
|
34
|
-
gemfile: gemfiles/rails42.gemfile
|
35
|
-
allow_failures:
|
36
|
-
- rvm: ruby-head
|
37
|
-
gemfile: gemfiles/railsmaster.gemfile
|
38
|
-
- rvm: 2.5.0
|
39
|
-
gemfile: gemfiles/railsmaster.gemfile
|
data/Gemfile
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
source 'https://rubygems.org'
|
3
|
-
|
4
|
-
# Specify your gem's dependencies in logidze.gemspec
|
5
|
-
gemspec
|
6
|
-
|
7
|
-
local_gemfile = "#{File.dirname(__FILE__)}/Gemfile.local"
|
8
|
-
|
9
|
-
if File.exist?(local_gemfile)
|
10
|
-
eval(File.read(local_gemfile)) # rubocop:disable Lint/Eval
|
11
|
-
else
|
12
|
-
gem 'activerecord', '~> 5.1.1'
|
13
|
-
end
|
data/Rakefile
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "bundler/gem_tasks"
|
3
|
-
require "rspec/core/rake_task"
|
4
|
-
require "rubocop/rake_task"
|
5
|
-
|
6
|
-
RuboCop::RakeTask.new
|
7
|
-
RSpec::Core::RakeTask.new(:spec)
|
8
|
-
|
9
|
-
namespace :dummy do
|
10
|
-
require_relative "spec/dummy/config/application"
|
11
|
-
Dummy::Application.load_tasks
|
12
|
-
end
|
13
|
-
|
14
|
-
task(:spec).clear
|
15
|
-
desc "Run specs other than spec/acceptance"
|
16
|
-
RSpec::Core::RakeTask.new("spec") do |task|
|
17
|
-
task.exclude_pattern = "spec/acceptance/**/*_spec.rb"
|
18
|
-
task.verbose = false
|
19
|
-
end
|
20
|
-
|
21
|
-
desc "Run acceptance specs in spec/acceptance"
|
22
|
-
RSpec::Core::RakeTask.new("spec:acceptance") do |task|
|
23
|
-
task.pattern = "spec/acceptance/**/*_spec.rb"
|
24
|
-
task.verbose = false
|
25
|
-
end
|
26
|
-
|
27
|
-
desc "Run the specs and acceptance tests"
|
28
|
-
task default: %w(rubocop spec spec:acceptance)
|
data/bench/performance/README.md
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
# Performance benchmarks: PaperTail vs. Logidze
|
2
|
-
|
3
|
-
We want to compare Logidze with the most popular versioning library for Rails – PaperTrail.
|
4
|
-
|
5
|
-
|
6
|
-
## Insert ([source](insert_bench.rb))
|
7
|
-
|
8
|
-
```
|
9
|
-
PaperTrail INSERT 213.148 (± 8.9%) i/s - 1.060k in 5.018504s
|
10
|
-
Logidze INSERT 613.387 (±16.3%) i/s - 2.970k in 5.036127s
|
11
|
-
```
|
12
|
-
|
13
|
-
|
14
|
-
## Update ([source](update_bench.rb))
|
15
|
-
|
16
|
-
When changeset has 2 fields:
|
17
|
-
|
18
|
-
```
|
19
|
-
PaperTrail UPDATE #1 256.651 (±26.5%) i/s - 1.206k in 5.002300s
|
20
|
-
Logidze UPDATE #1 356.932 (±12.6%) i/s - 1.764k in 5.030560s
|
21
|
-
```
|
22
|
-
|
23
|
-
When changeset has 5 fields:
|
24
|
-
|
25
|
-
```
|
26
|
-
PaperTrail UPDATE #2 246.281 (±24.0%) i/s - 1.168k in 5.008234s
|
27
|
-
Logidze UPDATE #2 331.942 (±16.6%) i/s - 1.593k in 5.028135s
|
28
|
-
```
|
29
|
-
|
30
|
-
## Getting diff ([source](diff_bench.rb))
|
31
|
-
|
32
|
-
PaperTrail doesn't have built-in method to calculate diff between not adjacent versions.
|
33
|
-
We add `diff_from(ts)` and `diff_from_joined(ts)` (which uses SQL JOIN) methods to calculate diff from specified version using changesets.
|
34
|
-
|
35
|
-
When each record has 10 versions:
|
36
|
-
|
37
|
-
```
|
38
|
-
PT DIFF 20.874 (± 4.8%) i/s - 106.000 in 5.091402s
|
39
|
-
PT (join) DIFF 20.619 (± 4.8%) i/s - 104.000 in 5.070160s
|
40
|
-
Logidze DIFF 109.482 (±24.7%) i/s - 500.000 in 5.103534s
|
41
|
-
```
|
42
|
-
|
43
|
-
When each record has 100 versions:
|
44
|
-
|
45
|
-
```
|
46
|
-
PT DIFF 2.998 (± 0.0%) i/s - 15.000 in 5.019494s
|
47
|
-
PT (join) DIFF 3.193 (± 0.0%) i/s - 16.000 in 5.030155s
|
48
|
-
Logidze DIFF 19.627 (±25.5%) i/s - 88.000 in 5.035555s
|
49
|
-
```
|
50
|
-
|
51
|
-
And, finally, when each record has 1000 versions:
|
52
|
-
|
53
|
-
```
|
54
|
-
PT DIFF 0.270 (± 0.0%) i/s - 17.000 in 63.038374s
|
55
|
-
PT (join) DIFF 0.235 (± 0.0%) i/s - 14.000 in 60.350886s
|
56
|
-
Logidze DIFF 2.022 (± 0.0%) i/s - 120.000 in 60.142965s
|
57
|
-
```
|
58
|
-
|
59
|
-
## Select memory usage ([source](memory_profile.rb))
|
60
|
-
|
61
|
-
Logidze loads more data (because it stores log in-place). But how much more?
|
62
|
-
We consider two cases for PaperTrail: when we want to calculate diff (and thus loading versions) and when we don't need any history related data.
|
63
|
-
|
64
|
-
When each record has 10 versions:
|
65
|
-
|
66
|
-
```
|
67
|
-
PT records
|
68
|
-
Total Allocated: 27.8 KB
|
69
|
-
Total Retained: 16.59 KB
|
70
|
-
Retained memory (per record): 2.14 KB
|
71
|
-
|
72
|
-
PT with versions
|
73
|
-
Total Allocated: 228.01 KB
|
74
|
-
Total Retained: 170.78 KB
|
75
|
-
Retained memory (per record): 143.13 KB
|
76
|
-
|
77
|
-
Logidze records
|
78
|
-
Total Allocated: 46.45 KB
|
79
|
-
Total Retained: 34.73 KB
|
80
|
-
Retained memory (per record): 4.11 KB
|
81
|
-
```
|
82
|
-
|
83
|
-
When each record has 100 versions:
|
84
|
-
|
85
|
-
```
|
86
|
-
PT with versions
|
87
|
-
Total Allocated: 1.92 MB
|
88
|
-
Total Retained: 1.56 MB
|
89
|
-
Retained memory (per record): 1.53 MB
|
90
|
-
|
91
|
-
Logidze records
|
92
|
-
Total Allocated: 162.48 KB
|
93
|
-
Total Retained: 150.76 KB
|
94
|
-
Retained memory (per record): 15.4 KB
|
95
|
-
```
|
96
|
-
|
97
|
-
When each record has 1000 versions:
|
98
|
-
|
99
|
-
```
|
100
|
-
PT with versions
|
101
|
-
Total Allocated: 18.23 MB
|
102
|
-
Total Retained: 14.86 MB
|
103
|
-
Retained memory (per record): 14.83 MB
|
104
|
-
|
105
|
-
Logidze records
|
106
|
-
Total Allocated: 1.32 MB
|
107
|
-
Total Retained: 1.31 MB
|
108
|
-
Retained memory (per record): 131.59 KB
|
109
|
-
```
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'benchmark/ips'
|
2
|
-
require './setup'
|
3
|
-
|
4
|
-
# How many records do you want?
|
5
|
-
N = (ENV['N'] || '100').to_i
|
6
|
-
|
7
|
-
# How many version each record has?
|
8
|
-
V = (ENV['V'] || '10').to_i
|
9
|
-
|
10
|
-
# Benchmark run time
|
11
|
-
BM_TIME = (ENV['BM_TIME'] || 5).to_i
|
12
|
-
|
13
|
-
BM_WARMUP = [(BM_TIME / 10), 2].max
|
14
|
-
|
15
|
-
LogidzeBench.cleanup
|
16
|
-
LogidzeBench.populate(N)
|
17
|
-
|
18
|
-
ts1 = LogidzeBench.generate_versions(V/2)
|
19
|
-
|
20
|
-
LogidzeBench.generate_versions(V/2)
|
21
|
-
|
22
|
-
Benchmark.ips do |x|
|
23
|
-
x.config(time: BM_TIME, warmup: BM_WARMUP)
|
24
|
-
|
25
|
-
x.report('PT DIFF') do
|
26
|
-
User.random(N/2).diff_from(ts1)
|
27
|
-
end
|
28
|
-
|
29
|
-
x.report('PT (join) DIFF') do
|
30
|
-
User.random(N/2).diff_from_joined(ts1)
|
31
|
-
end
|
32
|
-
|
33
|
-
x.report('Logidze DIFF') do
|
34
|
-
LogidzeUser.random(N/2).diff_from(ts1)
|
35
|
-
end
|
36
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'benchmark/ips'
|
2
|
-
require './setup'
|
3
|
-
|
4
|
-
params = {
|
5
|
-
email: Faker::Internet.email,
|
6
|
-
position: Faker::Number.number(3),
|
7
|
-
name: Faker::Name.name,
|
8
|
-
age: Faker::Number.number(2),
|
9
|
-
bio: Faker::Lorem.paragraph
|
10
|
-
}
|
11
|
-
|
12
|
-
Benchmark.ips do |x|
|
13
|
-
x.report('PaperTrail INSERT') do
|
14
|
-
User.create!(params)
|
15
|
-
end
|
16
|
-
|
17
|
-
x.report('Logidze INSERT') do
|
18
|
-
LogidzeUser.create!(params)
|
19
|
-
end
|
20
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require './setup'
|
2
|
-
require 'active_support/core_ext'
|
3
|
-
require 'memory_profiler'
|
4
|
-
|
5
|
-
# How many records do you want?
|
6
|
-
N = (ENV['N'] || '10').to_i
|
7
|
-
|
8
|
-
# How many version each record has?
|
9
|
-
V = (ENV['V'] || '10').to_i
|
10
|
-
|
11
|
-
LogidzeBench.cleanup
|
12
|
-
LogidzeBench.populate(N)
|
13
|
-
LogidzeBench.generate_versions(V)
|
14
|
-
|
15
|
-
module MemoryReport
|
16
|
-
KILO_BYTE = 1024
|
17
|
-
MEGA_BYTE = 1024 * 1024
|
18
|
-
|
19
|
-
module_function
|
20
|
-
def call(msg, relation)
|
21
|
-
buffer = nil
|
22
|
-
delta = N / 10
|
23
|
-
r0 = MemoryProfiler.report do
|
24
|
-
buffer = relation.random(N - delta).to_a
|
25
|
-
end
|
26
|
-
|
27
|
-
buffer = nil
|
28
|
-
r1 = MemoryProfiler.report do
|
29
|
-
buffer = relation.to_a
|
30
|
-
end
|
31
|
-
|
32
|
-
$stdout.puts msg
|
33
|
-
$stdout.puts "Total Allocated:\t\t\t\t#{to_human_size(r1.total_allocated_memsize)}"
|
34
|
-
$stdout.puts "Total Retained:\t\t\t\t\t#{to_human_size(r1.total_retained_memsize)}"
|
35
|
-
$stdout.puts "Retained_memsize memory (per record):\t\t#{to_human_size((r1.total_retained_memsize - r0.total_retained_memsize) / delta)}"
|
36
|
-
end
|
37
|
-
|
38
|
-
module_function
|
39
|
-
def to_human_size(size)
|
40
|
-
if size > MEGA_BYTE
|
41
|
-
"#{(size.to_f / MEGA_BYTE).round(2)} MB"
|
42
|
-
elsif size > KILO_BYTE
|
43
|
-
"#{(size.to_f / KILO_BYTE).round(2)} KB"
|
44
|
-
else
|
45
|
-
"#{size} B"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
MemoryReport.("PT records", User.all)
|
52
|
-
MemoryReport.("PT with versions", User.joins(:versions).all)
|
53
|
-
MemoryReport.("Logidze records", LogidzeUser.all)
|