logidze 0.11.0 → 1.2.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +79 -4
  3. data/LICENSE.txt +1 -1
  4. data/README.md +305 -102
  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_capture_exception.sql +23 -0
  9. data/lib/generators/logidze/install/functions/logidze_compact_history.sql +38 -0
  10. data/lib/generators/logidze/install/functions/logidze_filter_keys.sql +27 -0
  11. data/lib/generators/logidze/install/functions/logidze_logger.sql +203 -0
  12. data/lib/generators/logidze/install/functions/logidze_snapshot.sql +33 -0
  13. data/lib/generators/logidze/install/functions/logidze_version.sql +21 -0
  14. data/lib/generators/logidze/install/install_generator.rb +43 -1
  15. data/lib/generators/logidze/install/templates/hstore.rb.erb +1 -1
  16. data/lib/generators/logidze/install/templates/migration.rb.erb +19 -232
  17. data/lib/generators/logidze/install/templates/migration_fx.rb.erb +41 -0
  18. data/lib/generators/logidze/model/model_generator.rb +53 -13
  19. data/lib/generators/logidze/model/templates/migration.rb.erb +57 -36
  20. data/lib/generators/logidze/model/triggers/logidze.sql +6 -0
  21. data/lib/logidze.rb +37 -14
  22. data/lib/logidze/engine.rb +9 -0
  23. data/lib/logidze/has_logidze.rb +1 -1
  24. data/lib/logidze/history.rb +2 -11
  25. data/lib/logidze/ignore_log_data.rb +1 -3
  26. data/lib/logidze/meta.rb +43 -16
  27. data/lib/logidze/model.rb +51 -44
  28. data/lib/logidze/utils/check_pending.rb +57 -0
  29. data/lib/logidze/utils/function_definitions.rb +49 -0
  30. data/lib/logidze/utils/pending_migration_error.rb +25 -0
  31. data/lib/logidze/version.rb +1 -1
  32. metadata +69 -77
  33. data/.gitattributes +0 -3
  34. data/.github/ISSUE_TEMPLATE.md +0 -20
  35. data/.github/PULL_REQUEST_TEMPLATE.md +0 -29
  36. data/.gitignore +0 -40
  37. data/.rubocop.yml +0 -55
  38. data/.travis.yml +0 -42
  39. data/Gemfile +0 -15
  40. data/Rakefile +0 -28
  41. data/assets/pg_log_data_chart.png +0 -0
  42. data/bench/performance/README.md +0 -109
  43. data/bench/performance/diff_bench.rb +0 -38
  44. data/bench/performance/insert_bench.rb +0 -22
  45. data/bench/performance/memory_profile.rb +0 -56
  46. data/bench/performance/setup.rb +0 -315
  47. data/bench/performance/update_bench.rb +0 -38
  48. data/bench/triggers/Makefile +0 -56
  49. data/bench/triggers/Readme.md +0 -58
  50. data/bench/triggers/bench.sql +0 -6
  51. data/bench/triggers/hstore_trigger_setup.sql +0 -38
  52. data/bench/triggers/jsonb_minus_2_setup.sql +0 -47
  53. data/bench/triggers/jsonb_minus_setup.sql +0 -49
  54. data/bench/triggers/keys2_trigger_setup.sql +0 -44
  55. data/bench/triggers/keys_trigger_setup.sql +0 -50
  56. data/bin/console +0 -8
  57. data/bin/setup +0 -9
  58. data/gemfiles/rails42.gemfile +0 -6
  59. data/gemfiles/rails5.gemfile +0 -6
  60. data/gemfiles/rails52.gemfile +0 -6
  61. data/gemfiles/rails6.gemfile +0 -6
  62. data/gemfiles/railsmaster.gemfile +0 -7
  63. data/lib/logidze/ignore_log_data/association.rb +0 -11
  64. data/lib/logidze/ignore_log_data/ignored_columns.rb +0 -46
  65. data/lib/logidze/migration.rb +0 -20
  66. data/logidze.gemspec +0 -41
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./function_definitions"
4
+ require_relative "./pending_migration_error"
5
+
6
+ module Logidze
7
+ module Utils
8
+ # This Rack middleware is used to verify that all functions are up to date
9
+ class CheckPending
10
+ def initialize(app)
11
+ @app = app
12
+ @needs_check = true
13
+ @mutex = Mutex.new
14
+ end
15
+
16
+ delegate :connection, to: ActiveRecord::Base
17
+
18
+ def call(env)
19
+ @mutex.synchronize do
20
+ if @needs_check
21
+ notify_or_raise! if needs_migration?
22
+ end
23
+ @needs_check = false
24
+ end
25
+
26
+ @app.call(env)
27
+ end
28
+
29
+ private
30
+
31
+ def notify_or_raise!
32
+ case Logidze.on_pending_upgrade
33
+ when :warn
34
+ warn "\n**************************************************\n"\
35
+ "⛔️ WARNING: Logidze needs an upgrade and might not work correctly.\n"\
36
+ "Please, make sure to run `bundle exec rails generate logidze:install --update` "\
37
+ "and apply generated migration."\
38
+ "\n**************************************************\n\n"
39
+ when :raise
40
+ raise Logidze::Utils::PendingMigrationError, "Logidze needs upgrade. Run `bundle exec rails generate logidze:install --update` and apply generated migration."
41
+ end
42
+ end
43
+
44
+ def needs_migration?
45
+ (library_function_versions - pg_function_versions).any?
46
+ end
47
+
48
+ def pg_function_versions
49
+ Logidze::Utils::FunctionDefinitions.from_db.map { |func| [func.name, func.version] }
50
+ end
51
+
52
+ def library_function_versions
53
+ @library_function_versions ||= Logidze::Utils::FunctionDefinitions.from_fs.map { |func| [func.name, func.version] }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logidze
4
+ module Utils
5
+ class FuncDef < Struct.new(:name, :version, :signature); end
6
+
7
+ module FunctionDefinitions
8
+ class << self
9
+ def from_fs
10
+ function_paths = Dir.glob(File.join(__dir__, "..", "..", "generators", "logidze", "install", "functions", "*.sql"))
11
+ function_paths.map do |path|
12
+ name = path.match(/([^\/]+)\.sql/)[1]
13
+
14
+ file = File.open(path)
15
+ header, version_comment = file.readline, file.readline
16
+
17
+ signature = parse_signature(header)
18
+ version = parse_version(version_comment)
19
+ FuncDef.new(name, version, signature)
20
+ end
21
+ end
22
+
23
+ def from_db
24
+ query = <<~SQL
25
+ SELECT pp.proname, pg_get_functiondef(pp.oid) AS definition
26
+ FROM pg_proc pp
27
+ WHERE pp.proname like 'logidze_%'
28
+ ORDER BY pp.oid;
29
+ SQL
30
+ ActiveRecord::Base.connection.execute(query).map do |row|
31
+ version = parse_version(row["definition"])
32
+ FuncDef.new(row["proname"], version, nil)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def parse_version(line)
39
+ line.match(/version:\s+(\d+)/)&.[](1).to_i
40
+ end
41
+
42
+ def parse_signature(line)
43
+ parameters = line.match(/CREATE OR REPLACE FUNCTION\s+[\w_]+\((.*)\)/)[1]
44
+ parameters.split(/\s*,\s*/).map { |param| param.split(/\s+/, 2).last.sub(/\s+DEFAULT .*$/, "") }.join(", ")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Logidze
6
+ module Utils
7
+ class PendingMigrationError < StandardError
8
+ if Rails::VERSION::MAJOR >= 6
9
+ require "active_record"
10
+ require "active_support/actionable_error"
11
+ include ActiveSupport::ActionableError
12
+
13
+ action "Upgrade Logidze" do
14
+ Rails::Generators.invoke("logidze:install", ["--update"])
15
+ ActiveRecord::Tasks::DatabaseTasks.migrate
16
+ if ActiveRecord::Base.dump_schema_after_migration
17
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(
18
+ ActiveRecord::Base.connection_db_config
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Logidze
4
- VERSION = "0.11.0"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,127 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logidze
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-15 00:00:00.000000000 Z
11
+ date: 2021-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: railties
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '5.0'
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: '4.2'
26
+ version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: ammeter
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-next-core
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 1.1.3
34
- type: :development
47
+ version: '0.9'
48
+ type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 1.1.3
54
+ version: '0.9'
41
55
  - !ruby/object:Gem::Dependency
42
- name: bundler
56
+ name: ammeter
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.10'
61
+ version: 1.1.3
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.10'
68
+ version: 1.1.3
55
69
  - !ruby/object:Gem::Dependency
56
- name: pg
70
+ name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '0.18'
75
+ version: '1.10'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '0.18'
82
+ version: '1.10'
69
83
  - !ruby/object:Gem::Dependency
70
- name: rake
84
+ name: fx
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '10.0'
89
+ version: '0.5'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '10.0'
96
+ version: '0.5'
83
97
  - !ruby/object:Gem::Dependency
84
- name: rspec-rails
98
+ name: pg
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: '3.4'
103
+ version: '0.18'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: '3.4'
110
+ version: '0.18'
97
111
  - !ruby/object:Gem::Dependency
98
- name: rubocop-md
112
+ name: rake
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - "~>"
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
- version: 0.2.0
117
+ version: '13.0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - "~>"
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
- version: 0.2.0
124
+ version: '13.0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: standard
126
+ name: rspec-rails
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - "~>"
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
- version: 0.1.2
131
+ version: '3.4'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - "~>"
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
- version: 0.1.2
138
+ version: '3.4'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: timecop
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -136,54 +150,33 @@ dependencies:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0.8'
139
- description: PostgreSQL JSON-based auditing
153
+ description: PostgreSQL JSONB-based model changes tracking
140
154
  email:
141
155
  - dementiev.vm@gmail.com
142
156
  executables: []
143
157
  extensions: []
144
158
  extra_rdoc_files: []
145
159
  files:
146
- - ".gitattributes"
147
- - ".github/ISSUE_TEMPLATE.md"
148
- - ".github/PULL_REQUEST_TEMPLATE.md"
149
- - ".gitignore"
150
- - ".rspec"
151
- - ".rubocop.yml"
152
- - ".travis.yml"
153
160
  - CHANGELOG.md
154
- - Gemfile
155
161
  - LICENSE.txt
156
162
  - README.md
157
- - Rakefile
158
- - assets/pg_log_data_chart.png
159
- - bench/performance/README.md
160
- - bench/performance/diff_bench.rb
161
- - bench/performance/insert_bench.rb
162
- - bench/performance/memory_profile.rb
163
- - bench/performance/setup.rb
164
- - bench/performance/update_bench.rb
165
- - bench/triggers/Makefile
166
- - bench/triggers/Readme.md
167
- - bench/triggers/bench.sql
168
- - bench/triggers/hstore_trigger_setup.sql
169
- - bench/triggers/jsonb_minus_2_setup.sql
170
- - bench/triggers/jsonb_minus_setup.sql
171
- - bench/triggers/keys2_trigger_setup.sql
172
- - bench/triggers/keys_trigger_setup.sql
173
- - bin/console
174
- - bin/setup
175
- - gemfiles/rails42.gemfile
176
- - gemfiles/rails5.gemfile
177
- - gemfiles/rails52.gemfile
178
- - gemfiles/rails6.gemfile
179
- - gemfiles/railsmaster.gemfile
163
+ - lib/generators/logidze/fx_helper.rb
164
+ - lib/generators/logidze/inject_sql.rb
180
165
  - lib/generators/logidze/install/USAGE
166
+ - lib/generators/logidze/install/functions/logidze_capture_exception.sql
167
+ - lib/generators/logidze/install/functions/logidze_compact_history.sql
168
+ - lib/generators/logidze/install/functions/logidze_filter_keys.sql
169
+ - lib/generators/logidze/install/functions/logidze_logger.sql
170
+ - lib/generators/logidze/install/functions/logidze_snapshot.sql
171
+ - lib/generators/logidze/install/functions/logidze_version.sql
181
172
  - lib/generators/logidze/install/install_generator.rb
182
173
  - lib/generators/logidze/install/templates/hstore.rb.erb
183
174
  - lib/generators/logidze/install/templates/migration.rb.erb
175
+ - lib/generators/logidze/install/templates/migration_fx.rb.erb
184
176
  - lib/generators/logidze/model/USAGE
185
177
  - lib/generators/logidze/model/model_generator.rb
186
178
  - lib/generators/logidze/model/templates/migration.rb.erb
179
+ - lib/generators/logidze/model/triggers/logidze.sql
187
180
  - lib/logidze.rb
188
181
  - lib/logidze/engine.rb
189
182
  - lib/logidze/has_logidze.rb
@@ -191,15 +184,14 @@ files:
191
184
  - lib/logidze/history/type.rb
192
185
  - lib/logidze/history/version.rb
193
186
  - lib/logidze/ignore_log_data.rb
194
- - lib/logidze/ignore_log_data/association.rb
195
187
  - lib/logidze/ignore_log_data/cast_attribute_patch.rb
196
- - lib/logidze/ignore_log_data/ignored_columns.rb
197
188
  - lib/logidze/meta.rb
198
- - lib/logidze/migration.rb
199
189
  - lib/logidze/model.rb
190
+ - lib/logidze/utils/check_pending.rb
191
+ - lib/logidze/utils/function_definitions.rb
192
+ - lib/logidze/utils/pending_migration_error.rb
200
193
  - lib/logidze/version.rb
201
194
  - lib/logidze/versioned_association.rb
202
- - logidze.gemspec
203
195
  homepage: http://github.com/palkan/logidze
204
196
  licenses:
205
197
  - MIT
@@ -209,7 +201,7 @@ metadata:
209
201
  documentation_uri: http://github.com/palkan/logidze
210
202
  homepage_uri: http://github.com/palkan/logidze
211
203
  source_code_uri: http://github.com/palkan/logidze
212
- post_install_message:
204
+ post_install_message:
213
205
  rdoc_options: []
214
206
  require_paths:
215
207
  - lib
@@ -217,15 +209,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
209
  requirements:
218
210
  - - ">="
219
211
  - !ruby/object:Gem::Version
220
- version: 2.4.0
212
+ version: 2.5.0
221
213
  required_rubygems_version: !ruby/object:Gem::Requirement
222
214
  requirements:
223
215
  - - ">="
224
216
  - !ruby/object:Gem::Version
225
217
  version: '0'
226
218
  requirements: []
227
- rubygems_version: 3.0.4
228
- signing_key:
219
+ rubygems_version: 3.2.10
220
+ signing_key:
229
221
  specification_version: 4
230
- summary: PostgreSQL JSON-based auditing
222
+ summary: PostgreSQL JSONB-based model changes tracking
231
223
  test_files: []
data/.gitattributes DELETED
@@ -1,3 +0,0 @@
1
- assets/**/* linguist-vendored
2
- bench/**/* linguist-vendored
3
- .github/**/* linguist-vendored
@@ -1,20 +0,0 @@
1
- <!--
2
- This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
3
- feel free to skip the rest of this template.
4
- -->
5
-
6
- ### Tell us about your environment
7
-
8
- **Ruby Version:**
9
-
10
- **Rails Version:**
11
-
12
- **PostgreSQL Version:**
13
-
14
- **Logidze Version:**
15
-
16
- ### What did you do?
17
-
18
- ### What did you expect to happen?
19
-
20
- ### What actually happened?