logidze 0.8.1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +124 -5
  3. data/LICENSE.txt +1 -1
  4. data/README.md +310 -80
  5. data/lib/generators/logidze/fx_helper.rb +17 -0
  6. data/lib/generators/logidze/inject_sql.rb +18 -0
  7. data/lib/generators/logidze/install/USAGE +6 -1
  8. data/lib/generators/logidze/install/functions/logidze_compact_history.sql +38 -0
  9. data/lib/generators/logidze/install/functions/logidze_filter_keys.sql +27 -0
  10. data/lib/generators/logidze/install/functions/logidze_logger.sql +150 -0
  11. data/lib/generators/logidze/install/functions/logidze_snapshot.sql +24 -0
  12. data/lib/generators/logidze/install/functions/logidze_version.sql +20 -0
  13. data/lib/generators/logidze/install/install_generator.rb +61 -3
  14. data/lib/generators/logidze/install/templates/hstore.rb.erb +1 -1
  15. data/lib/generators/logidze/install/templates/migration.rb.erb +19 -232
  16. data/lib/generators/logidze/install/templates/migration_fx.rb.erb +41 -0
  17. data/lib/generators/logidze/model/model_generator.rb +56 -20
  18. data/lib/generators/logidze/model/templates/migration.rb.erb +57 -36
  19. data/lib/generators/logidze/model/triggers/logidze.sql +6 -0
  20. data/lib/logidze.rb +43 -20
  21. data/lib/logidze/engine.rb +4 -1
  22. data/lib/logidze/has_logidze.rb +12 -3
  23. data/lib/logidze/history.rb +7 -15
  24. data/lib/logidze/history/type.rb +1 -1
  25. data/lib/logidze/history/version.rb +6 -5
  26. data/lib/logidze/ignore_log_data.rb +22 -0
  27. data/lib/logidze/ignore_log_data/cast_attribute_patch.rb +17 -0
  28. data/lib/logidze/meta.rb +44 -17
  29. data/lib/logidze/model.rb +65 -37
  30. data/lib/logidze/version.rb +2 -1
  31. data/lib/logidze/versioned_association.rb +0 -1
  32. metadata +47 -103
  33. data/.gitignore +0 -40
  34. data/.hound.yml +0 -3
  35. data/.rubocop.yml +0 -94
  36. data/.travis.yml +0 -39
  37. data/Gemfile +0 -13
  38. data/Rakefile +0 -28
  39. data/bench/performance/README.md +0 -109
  40. data/bench/performance/diff_bench.rb +0 -36
  41. data/bench/performance/insert_bench.rb +0 -20
  42. data/bench/performance/memory_profile.rb +0 -53
  43. data/bench/performance/setup.rb +0 -308
  44. data/bench/performance/update_bench.rb +0 -36
  45. data/bench/triggers/Makefile +0 -56
  46. data/bench/triggers/Readme.md +0 -58
  47. data/bench/triggers/bench.sql +0 -6
  48. data/bench/triggers/hstore_trigger_setup.sql +0 -38
  49. data/bench/triggers/jsonb_minus_2_setup.sql +0 -47
  50. data/bench/triggers/jsonb_minus_setup.sql +0 -49
  51. data/bench/triggers/keys2_trigger_setup.sql +0 -44
  52. data/bench/triggers/keys_trigger_setup.sql +0 -50
  53. data/bin/console +0 -8
  54. data/bin/setup +0 -9
  55. data/gemfiles/rails42.gemfile +0 -5
  56. data/gemfiles/rails5.gemfile +0 -6
  57. data/gemfiles/rails52.gemfile +0 -6
  58. data/gemfiles/railsmaster.gemfile +0 -7
  59. data/lib/logidze/migration.rb +0 -19
  60. 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
@@ -1,3 +0,0 @@
1
- ruby:
2
- enabled: true
3
- config_file: .rubocop.yml
@@ -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
@@ -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)
@@ -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)