iron_trail 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4743b8660d0a3f59c82131213a4e9b85396c0efa83f2a00c2678dcb2a2d57a7
4
- data.tar.gz: 6d53fef0dbb300ce504c8065616142ba012cb697647a5f588d4f2bea3935e293
3
+ metadata.gz: fbae2be821b8553a0ddf746fd9d30b3b7420b27e80e293b0716d78bf60c2c4dd
4
+ data.tar.gz: 9525cad670a20bc43414a56a0ea87734e82c908f175a82545cbe0c386f7fec86
5
5
  SHA512:
6
- metadata.gz: 7bc826ad0ff24c91b6e7d9bac08fb7c5a0f893142a91315804aafe68a95bc96e3be5b9b98ed83de9f4d293daab9b1bbce3432579116db79fa3c47ca8b184b0a7
7
- data.tar.gz: b43255cfbe9833075c44335eaaeb5e2067e942d99f4ff3b8e35aee42c9960cdfe6e1e96cfe5c75fd2b4ae53c8dbef580dae2768cf308f92b2bb2d5a5e06ec667
6
+ metadata.gz: b6a32637f82a839336850df3f5b8a090a367b87eb519db903c41681de33578ea3b4d13f9ed15301985a29ce0b82c2bfacd98651da1e266373a639741453e2925
7
+ data.tar.gz: 8bb96a201f38d6923d864f65d92b3bec8cab90df9ad30144716d8ea0943d8fad25f46b4433a6e868177454cef3c6f8e7c738d22e7c83354162f897c3e7882795
@@ -7,23 +7,25 @@ module IronTrail
7
7
  class MigrationGenerator < Rails::Generators::Base
8
8
  include ::Rails::Generators::Migration
9
9
 
10
- source_root File.expand_path('templates', __dir__)
10
+ source_root File.expand_path("templates", __dir__)
11
11
 
12
- desc 'Generates a migration adding the iron trail changes table'
12
+ desc "Generates a migration adding the iron trail changes table"
13
13
  def create_changes_migration_file
14
+ migration_dir = File.expand_path("db/migrate")
15
+
14
16
  migration_template(
15
- 'create_irontrail_changes.rb.erb',
16
- 'db/migrate/create_irontrail_changes.rb'
17
+ "create_irontrail_changes.rb.erb",
18
+ "db/migrate/create_irontrail_changes.rb"
17
19
  )
18
20
 
19
21
  migration_template(
20
- 'create_irontrail_support_tables.rb.erb',
21
- 'db/migrate/create_irontrail_support_tables.rb'
22
+ "create_irontrail_support_tables.rb.erb",
23
+ "db/migrate/create_irontrail_support_tables.rb"
22
24
  )
23
25
 
24
26
  migration_template(
25
- 'create_irontrail_trigger_function.rb.erb',
26
- 'db/migrate/create_irontrail_trigger_function.rb'
27
+ "create_irontrail_trigger_function.rb.erb",
28
+ "db/migrate/create_irontrail_trigger_function.rb"
27
29
  )
28
30
  end
29
31
 
@@ -3,7 +3,12 @@
3
3
  module IronTrail
4
4
  class Association < ::ActiveRecord::Associations::HasManyAssociation
5
5
  def association_scope
6
+ klass = self.klass
7
+ reflection = self.reflection
6
8
  scope = klass.unscoped
9
+ owner = self.owner
10
+
11
+ chain = [::ActiveRecord::Reflection::RuntimeReflection.new(reflection, self)]
7
12
 
8
13
  foreign_key = reflection.join_foreign_key
9
14
  pk_value = owner._read_attribute(foreign_key)
@@ -20,7 +20,7 @@ module IronTrail
20
20
 
21
21
  args.each do |col_name, value|
22
22
  scope.where!(
23
- ::Arel::Nodes::SqlLiteral.new("rec_delta->#{connection.quote(col_name)}->>#{Integer(ary_index)}").eq(
23
+ ::Arel::Nodes::SqlLiteral.new("rec_delta->#{connection.quote col_name}->>#{Integer(ary_index)}").eq(
24
24
  ::Arel::Nodes::BindParam.new(value)
25
25
  )
26
26
  )
@@ -28,7 +28,7 @@ module IronTrail
28
28
  # directly.
29
29
  # It is possible to call Array#clear to empty the array and remove default
30
30
  # should that be desired.
31
- def ignored_tables=(_v)
31
+ def ignored_tables=(v)
32
32
  raise 'Overwriting ignored_tables is not allow. Instead, add or remove to it explicitly.'
33
33
  end
34
34
  end
@@ -46,12 +46,12 @@ module IronTrail
46
46
  LIMIT 1;
47
47
  SQL
48
48
 
49
- connection.execute(stmt).to_a.count.positive?
49
+ connection.execute(stmt).to_a.count > 0
50
50
  end
51
51
 
52
52
  def remove_functions(cascade:)
53
- query = +'DROP FUNCTION irontrail_log_row'
54
- query << ' CASCADE' if cascade
53
+ query = +"DROP FUNCTION irontrail_log_row"
54
+ query << " CASCADE" if cascade
55
55
 
56
56
  connection.execute(query)
57
57
  end
@@ -83,6 +83,18 @@ module IronTrail
83
83
  end
84
84
  end
85
85
 
86
+ def disable_for_all_ignored_tables
87
+ affected_tables = collect_tracked_table_names & (
88
+ OWN_TABLES + (IronTrail.config.ignored_tables || [])
89
+ )
90
+
91
+ affected_tables.each do |table_name|
92
+ disable_tracking_for_table(table_name)
93
+ end
94
+
95
+ affected_tables
96
+ end
97
+
86
98
  def collect_tables_tracking_status
87
99
  ignored_tables = OWN_TABLES + (IronTrail.config.ignored_tables || [])
88
100
 
@@ -96,7 +108,7 @@ module IronTrail
96
108
  end
97
109
 
98
110
  def disable_tracking_for_table(table_name)
99
- # NOTE: will disable even if table is ignored as this allows
111
+ # Note: will disable even if table is ignored as this allows
100
112
  # one to fix ignored tables mnore easily. Since the table is already
101
113
  # ignored, it is an expected destructive operation.
102
114
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module IronTrail
4
4
  module Migration
5
- def method_missing(method, *args) # rubocop:disable Style/MissingRespondToMissing
5
+ def method_missing(method, *args)
6
6
  running_from_schema = is_a?(ActiveRecord::Schema) ||
7
7
  (defined?(ActiveRecord::Schema::Definition) && is_a?(ActiveRecord::Schema::Definition))
8
8
 
@@ -11,7 +11,9 @@ module IronTrail
11
11
  return result unless IronTrail.enabled? && method == :create_table
12
12
 
13
13
  start_at_version = IronTrail.config.track_migrations_starting_at_version
14
- return result if !running_from_schema && start_at_version && version < (Integer(start_at_version))
14
+ if !running_from_schema && start_at_version
15
+ return result if self.version < Integer(start_at_version)
16
+ end
15
17
 
16
18
  table_name = args.first.to_s
17
19
  return result if IronTrail.ignore_table?(table_name)
@@ -27,10 +29,7 @@ module IronTrail
27
29
  if db_fun.function_present?
28
30
  db_fun.enable_tracking_for_table(table_name)
29
31
  else
30
- Rails.logger.warn(
31
- "IronTrail will not create trigger for table #{table_name} " \
32
- 'because the trigger function does not exist in the database.'
33
- )
32
+ Rails.logger.warn("IronTrail will not create trigger for table #{table_name} because the trigger function does not exist in the database.")
34
33
  end
35
34
 
36
35
  result
@@ -8,7 +8,7 @@ module IronTrail
8
8
  # own AR reflection and association classes.
9
9
  module Model
10
10
  def self.included(mod)
11
- mod.include(ClassMethods)
11
+ mod.include ClassMethods
12
12
 
13
13
  ::ActiveRecord::Reflection.add_reflection(
14
14
  mod,
@@ -2,7 +2,7 @@
2
2
 
3
3
  module IronTrail
4
4
  class QueryTransformer
5
- METADATA_MAX_LENGTH = 1_048_576 # 1 MiB
5
+ METADATA_MAX_LENGTH = 1048576 # 1 MiB
6
6
 
7
7
  attr_reader :transformer_proc
8
8
 
@@ -24,10 +24,7 @@ module IronTrail
24
24
  metadata = JSON.dump(current_metadata)
25
25
 
26
26
  if metadata.length > METADATA_MAX_LENGTH
27
- Rails.logger.warn(
28
- "IronTrail metadata is longer than maximum length! #{metadata.length} > #{METADATA_MAX_LENGTH}"
29
- )
30
-
27
+ Rails.logger.warn("IronTrail metadata is longer than maximum length! #{metadata.length} > #{METADATA_MAX_LENGTH}")
31
28
  next query
32
29
  end
33
30
 
@@ -2,13 +2,13 @@
2
2
 
3
3
  module IronTrail
4
4
  class Reflection < ::ActiveRecord::Reflection::AssociationReflection
5
- def collection? = true
5
+ def collection?; true; end
6
6
 
7
7
  def association_class
8
8
  ::IronTrail::Association
9
9
  end
10
10
 
11
- def join_scope(table, foreign_table, _foreign_klass)
11
+ def join_scope(table, foreign_table, foreign_klass)
12
12
  scope = klass_join_scope(table, nil)
13
13
 
14
14
  foreign_key_column_names = Array(join_foreign_key)
@@ -26,7 +26,7 @@ module IronTrail
26
26
  ::Arel::Nodes::As.new(
27
27
  foreign_table[foreign_key_column_name],
28
28
  ::Arel::Nodes::SqlLiteral.new('text')
29
- )
29
+ ),
30
30
  ]
31
31
  )
32
32
 
@@ -1,3 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ if ENV['RAILS_ENV'] == 'production'
4
+ raise 'This file should not be required in production. ' \
5
+ 'Change the RAILS_ENV env var temporarily to override this.'
6
+ end
7
+
3
8
  require 'iron_trail'
9
+
10
+ module IronTrail
11
+ module Testing
12
+ class << self
13
+ attr_accessor :enabled
14
+
15
+ def enable!
16
+ DbFunctions.new(ActiveRecord::Base.connection).install_functions
17
+ @enabled = true
18
+ end
19
+
20
+ def disable!
21
+ # We "disable" it by replacing the trigger function by a no-op one.
22
+ # This should be faster than adding/removing triggers from several
23
+ # tables every time.
24
+ sql = <<~SQL
25
+ CREATE OR REPLACE FUNCTION irontrail_log_row()
26
+ RETURNS TRIGGER AS $$
27
+ BEGIN
28
+ RETURN NULL;
29
+ END;
30
+ $$ LANGUAGE plpgsql;
31
+ SQL
32
+
33
+ ActiveRecord::Base.connection.execute(sql)
34
+ @enabled = false
35
+ end
36
+
37
+ def with_iron_trail(want_enabled:, &block)
38
+ was_enabled = IronTrail::Testing.enabled
39
+
40
+ if want_enabled
41
+ ::IronTrail::Testing.enable! unless was_enabled
42
+ else
43
+ ::IronTrail::Testing.disable! if was_enabled
44
+ end
45
+
46
+ block.call
47
+ ensure
48
+ if want_enabled && !was_enabled
49
+ ::IronTrail::Testing.disable!
50
+ elsif !want_enabled && was_enabled
51
+ ::IronTrail::Testing.enable!
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ RSpec.configure do |config|
59
+ config.around(:each, iron_trail: true) do |example|
60
+ IronTrail::Testing.with_iron_trail(want_enabled: true) { example.run }
61
+ end
62
+ config.around(:each, iron_trail: false) do |example|
63
+ raise "Using iron_trail: false does not do what you might think it does. To disable iron_trail, " \
64
+ "use IronTrail::Testing.with_iron_trail(want_enabled: false) { ... } instead."
65
+ end
66
+ end
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
1
+ # frozen_literal_string: true
2
2
 
3
3
  module IronTrail
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
data/lib/iron_trail.rb CHANGED
@@ -29,9 +29,9 @@ module IronTrail
29
29
 
30
30
  module SchemaDumper
31
31
  def trailer(stream)
32
- stream.print("\n IronTrail.post_schema_load(self, missing_tracking: @irontrail_missing_track)\n")
32
+ stream.print "\n IronTrail.post_schema_load(self, missing_tracking: @irontrail_missing_track)\n"
33
33
 
34
- super
34
+ super(stream)
35
35
  end
36
36
  end
37
37
 
@@ -87,9 +87,11 @@ module IronTrail
87
87
  end
88
88
 
89
89
  def_delegators :store_instance,
90
- :store_metadata,
91
- :merge_metadata,
92
- :current_metadata
90
+ :store_metadata,
91
+ :merge_metadata,
92
+ :current_metadata
93
+
94
+
93
95
  end
94
96
  end
95
97
 
@@ -1,45 +1,76 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ module IronTrail::RakeHelper
4
+ class << self
5
+ def db_functions
6
+ IronTrail::DbFunctions.new(ActiveRecord::Base.connection)
7
+ end
8
+
9
+ def abort_when_unsafe!
10
+ run_unsafe = %w[true 1 yes].include?(ENV['IRONTRAIL_RUN_UNSAFE'])
11
+ return unless Rails.env.production? && !run_unsafe
12
+
13
+ puts "Aborting: operation is dangerous in a production environment. " + \
14
+ "Override this behavior by setting the IRONTRAIL_RUN_UNSAFE=1 env var."
15
+
16
+ exit(1)
17
+ end
18
+ end
19
+ end
20
+
3
21
  namespace :iron_trail do
4
22
  namespace :tracking do
5
23
  desc 'Enables tracking for all missing tables.'
6
24
  task enable: :environment do
7
- tables = db_functions.collect_tables_tracking_status[:missing]
8
- unless tables.length.positive?
9
- puts 'All tables are being tracked already (no missing tables found).'
10
- puts 'If you think this is wrong, check your ignored_tables list.'
25
+ tables = IronTrail::RakeHelper.db_functions.collect_tables_tracking_status[:missing]
26
+ unless tables.length > 0
27
+ puts "All tables are being tracked already (no missing tables found)."
28
+ puts "If you think this is wrong, check your ignored_tables list."
11
29
  return
12
30
  end
13
31
 
14
32
  puts "Will start tracking #{tables.length} tables."
15
33
  tables.each do |table_name|
16
- db_functions.enable_tracking_for_table(table_name)
34
+ IronTrail::RakeHelper.db_functions.enable_tracking_for_table(table_name)
35
+ end
36
+ end
37
+
38
+ desc 'Disabled tracking for any ignored table that might still have the trigger enabled.'
39
+ task disable_on_ignored: :environment do
40
+ affected_tables = IronTrail::RakeHelper.db_functions.disable_for_all_ignored_tables
41
+
42
+ unless affected_tables.empty?
43
+ puts "Removed tracking from #{affected_tables.length} tables:"
44
+
45
+ affected_tables.each do |table_name|
46
+ puts "\t#{table_name}"
47
+ end
17
48
  end
18
49
  end
19
50
 
20
51
  desc 'Disables tracking all tables. Dangerous!'
21
52
  task disable: :environment do
22
- abort_when_unsafe!
53
+ IronTrail::RakeHelper.abort_when_unsafe!
23
54
 
24
- tables = db_functions.collect_tables_tracking_status[:tracked]
55
+ tables = IronTrail::RakeHelper.db_functions.collect_tables_tracking_status[:tracked]
25
56
  puts "Will stop tracking #{tables.length} tables."
26
57
  tables.each do |table_name|
27
- db_functions.disable_tracking_for_table(table_name)
58
+ IronTrail::RakeHelper.db_functions.disable_tracking_for_table(table_name)
28
59
  end
29
60
 
30
- tables = db_functions.collect_tables_tracking_status[:tracked]
31
- if tables.length.positive?
32
- puts "WARNING: Something went wrong. There are still #{tables.length} " \
33
- 'tables being tracked.'
61
+ tables = IronTrail::RakeHelper.db_functions.collect_tables_tracking_status[:tracked]
62
+ if tables.length > 0
63
+ puts "WARNING: Something went wrong. There are still #{tables.length}" + \
64
+ " tables being tracked."
34
65
  else
35
- puts 'Done!'
66
+ puts "Done!"
36
67
  end
37
68
  end
38
69
 
39
70
  desc 'Shows which tables are tracking, missing and ignored.'
40
71
  task status: :environment do
41
- status = db_functions.collect_tables_tracking_status
42
- ignored = IronTrail.config.ignored_tables || []
72
+ status = IronTrail::RakeHelper.db_functions.collect_tables_tracking_status
73
+ ignored = (IronTrail.config.ignored_tables || [])
43
74
 
44
75
  # We likely want to keep this structure of text untouched as someone
45
76
  # could use it to perform automation (e.g. monitoring).
@@ -47,36 +78,20 @@ namespace :iron_trail do
47
78
  puts "Missing #{status[:missing].length} tables."
48
79
  puts "There are #{ignored.length} ignored tables."
49
80
 
50
- puts 'Tracked tables:'
81
+ puts "Tracked tables:"
51
82
  status[:tracked].sort.each do |table_name|
52
83
  puts "\t#{table_name}"
53
84
  end
54
85
 
55
- puts 'Missing tables:'
86
+ puts "Missing tables:"
56
87
  status[:missing].sort.each do |table_name|
57
88
  puts "\t#{table_name}"
58
89
  end
59
90
 
60
- puts 'Ignored tables:'
91
+ puts "Ignored tables:"
61
92
  ignored.sort.each do |table_name|
62
93
  puts "\t#{table_name}"
63
94
  end
64
95
  end
65
-
66
- private
67
-
68
- def db_functions
69
- @db_functions ||= IronTrail::DbFunctions.new(ActiveRecord::Base.connection)
70
- end
71
-
72
- def abort_when_unsafe!
73
- run_unsafe = %w[true 1 yes].include?(ENV['IRONTRAIL_RUN_UNSAFE'])
74
- return unless Rails.env.production? && !run_unsafe
75
-
76
- puts 'Aborting: operation is dangerous in a production environment. ' \
77
- 'Override this behavior by setting the IRONTRAIL_RUN_UNSAFE=1 env var.'
78
-
79
- exit(1)
80
- end
81
96
  end
82
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Diego Piske
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-26 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -39,61 +39,33 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
- name: appraisal
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '2.5'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '2.5'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
42
+ name: pg_party
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '1.69'
47
+ version: '1.8'
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '1.69'
69
- - !ruby/object:Gem::Dependency
70
- name: debug
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
54
+ version: '1.8'
83
55
  - !ruby/object:Gem::Dependency
84
- name: pg_party
56
+ name: appraisal
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: '1.8'
61
+ version: '2.5'
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: '1.8'
68
+ version: '2.5'
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -195,8 +167,7 @@ files:
195
167
  homepage: https://github.com/trusted/iron_trail
196
168
  licenses:
197
169
  - MIT
198
- metadata:
199
- rubygems_mfa_required: 'true'
170
+ metadata: {}
200
171
  post_install_message:
201
172
  rdoc_options: []
202
173
  require_paths: