hoardable 0.13.0 → 0.14.0

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: 28edc85fff69a3851a5d2c653368d732bd9e6fe8ad5544bfa7f81147c6007aab
4
- data.tar.gz: 2d7c3abc9eedaddf3180b9f368c90fa25addaffa6c54bc76bf82880b54e7fc72
3
+ metadata.gz: 83017b15a9b37931d02d7f5d8b7b8d3e81cab4b4cc4691f522430ae2c9be77f8
4
+ data.tar.gz: 1774bb8cfe7628bbc2bdd8293928dac45dce20c4724aa5c4bc435a4c59a40f0d
5
5
  SHA512:
6
- metadata.gz: 76dfd695ad62332f876aad4d25e8d1b220970bcd8f2d2eeb69a91e4a441300fc356984dc5ef25be9dd01e745a305448a7f55b439199ef475932910bde02e8f9d
7
- data.tar.gz: '081e30627e731ed8d9b4f42536d9e67926bb37348075efa10d2ee3f5ee3eb37476ba3b0ecf1c6ac6fb4dfa7fa700e4d02fd10c3c3f537ef7ba433e605c9d1039'
6
+ metadata.gz: d0b7d0024a9b8eee5982ab92af174a9a7a134445108c1c3d97945c5ad967f234743fe047f0c42726366d38b7facacc44bac530a5de9a5369de0a9e7bc27342f9
7
+ data.tar.gz: fb4d0de48b7d798e70c948aea4ae8adb90eaa2836c4ca2d76e952e5c02d53951205f2628bc3e620cb1824f6ac49fcc692dc19130f907c932e0ed3b78fee217e8
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.6
2
+ TargetRubyVersion: 2.7
3
3
  NewCops: enable
4
4
  SuggestExtensions: false
5
5
 
data/.tool-versions CHANGED
@@ -1,2 +1,2 @@
1
- ruby 3.1.2
1
+ ruby 3.2.1
2
2
  postgres 14.4
data/CHANGELOG.md CHANGED
@@ -1,4 +1,6 @@
1
- ## [Unreleased]
1
+ ## 0.14.0
2
2
 
3
- - Stability is coming.
3
+ - *Breaking Change* - Support for Ruby 2.6 is dropped
4
+ - Adjusts the migration and install generators to use the `fx` gem so that Rails 7+ can use `schema.rb`
5
+ instead of `structure.sql`
4
6
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Hoardable ![gem version](https://img.shields.io/gem/v/hoardable?style=flat-square)
2
2
 
3
- Hoardable is an ActiveRecord extension for Ruby 2.6+, Rails 6.1+, and PostgreSQL that allows for versioning
3
+ Hoardable is an ActiveRecord extension for Ruby 2.7+, Rails 6.1+, and PostgreSQL that allows for versioning
4
4
  and soft-deletion of records through the use of _uni-temporal inherited tables_.
5
5
 
6
6
  [Temporal tables](https://en.wikipedia.org/wiki/Temporal_database) are a database design pattern where each
@@ -34,8 +34,8 @@ bin/rails g hoardable:install
34
34
  bin/rails db:migrate
35
35
  ```
36
36
 
37
- This will generate PostgreSQL functions, an initiailzer, and set `config.active_record.schema_format = :sql`
38
- in `application.rb`.
37
+ This will generate PostgreSQL functions, an enum and an initiailzer. It will also set
38
+ `config.active_record.schema_format = :sql` in `application.rb` if you are using Rails < 7.
39
39
 
40
40
  ### Model Installation
41
41
 
@@ -0,0 +1,8 @@
1
+ CREATE OR REPLACE FUNCTION hoardable_prevent_update_id() RETURNS trigger
2
+ LANGUAGE plpgsql AS
3
+ $$BEGIN
4
+ IF NEW.hoardable_id <> OLD.hoardable_id THEN
5
+ RAISE EXCEPTION 'hoardable id cannot be updated';
6
+ END IF;
7
+ RETURN NEW;
8
+ END;$$;
@@ -0,0 +1,18 @@
1
+ CREATE OR REPLACE FUNCTION hoardable_source_set_id() RETURNS trigger
2
+ LANGUAGE plpgsql AS
3
+ $$
4
+ DECLARE
5
+ _pk information_schema.constraint_column_usage.column_name%TYPE;
6
+ _id _pk%TYPE;
7
+ BEGIN
8
+ SELECT c.column_name
9
+ FROM information_schema.table_constraints t
10
+ JOIN information_schema.constraint_column_usage c
11
+ ON c.constraint_name = t.constraint_name
12
+ WHERE c.table_name = TG_TABLE_NAME AND t.constraint_type = 'PRIMARY KEY'
13
+ LIMIT 1
14
+ INTO _pk;
15
+ EXECUTE format('SELECT $1.%I', _pk) INTO _id USING NEW;
16
+ NEW.hoardable_id = _id;
17
+ RETURN NEW;
18
+ END;$$;
@@ -0,0 +1,6 @@
1
+ CREATE OR REPLACE FUNCTION hoardable_version_prevent_update() RETURNS trigger
2
+ LANGUAGE plpgsql AS
3
+ $$BEGIN
4
+ RAISE EXCEPTION 'updating a version is not allowed';
5
+ RETURN NEW;
6
+ END;$$;
@@ -8,6 +8,7 @@ module Hoardable
8
8
  class InstallGenerator < Rails::Generators::Base
9
9
  source_root File.expand_path('templates', __dir__)
10
10
  include Rails::Generators::Migration
11
+ delegate :supports_schema_enums?, to: :class
11
12
 
12
13
  def create_initializer_file
13
14
  create_file(
@@ -22,12 +23,25 @@ module Hoardable
22
23
  )
23
24
  end
24
25
 
26
+ def change_schema_format_to_sql
27
+ return if supports_schema_enums?
28
+
29
+ application 'config.active_record.schema_format = :sql'
30
+ end
31
+
25
32
  def create_migration_file
26
33
  migration_template 'install.rb.erb', 'db/migrate/install_hoardable.rb'
27
34
  end
28
35
 
29
- def change_schema_format_to_sql
30
- application 'config.active_record.schema_format = :sql'
36
+ def create_functions
37
+ Dir.glob(File.join(__dir__, 'functions', '*.sql')).each do |file_path|
38
+ file_name = file_path.match(%r{([^/]+)\.sql})[1]
39
+ template file_path, "db/functions/#{file_name}_v01.sql"
40
+ end
41
+ end
42
+
43
+ def self.supports_schema_enums?
44
+ ActiveRecord.version >= ::Gem::Version.new('7.0.0')
31
45
  end
32
46
 
33
47
  def self.next_migration_number(dir)
@@ -9,12 +9,30 @@ module Hoardable
9
9
  class MigrationGenerator < ActiveRecord::Generators::Base
10
10
  source_root File.expand_path('templates', __dir__)
11
11
  include Rails::Generators::Migration
12
- class_option :foreign_key_type, type: :string
12
+ class_option(
13
+ :foreign_key_type,
14
+ type: :string,
15
+ optional: true,
16
+ desc: 'explictly set / override the foreign key type of the versions table'
17
+ )
13
18
 
14
19
  def create_versions_table
15
20
  migration_template 'migration.rb.erb', "db/migrate/create_#{singularized_table_name}_versions.rb"
16
21
  end
17
22
 
23
+ def create_triggers
24
+ {
25
+ versions_prevent_update: singularized_table_name,
26
+ set_hoardable_id: table_name,
27
+ prevent_update_hoardable_id: table_name
28
+ }.each do |(trigger_name, trigger_table_name)|
29
+ template(
30
+ "../triggers/#{trigger_name}.sql",
31
+ "db/triggers/#{trigger_table_name}_#{trigger_name}_v01.sql"
32
+ )
33
+ end
34
+ end
35
+
18
36
  no_tasks do
19
37
  def foreign_key_type
20
38
  options[:foreign_key_type] ||
@@ -1,65 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class InstallHoardable < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
4
- def up
5
- execute(
6
- <<~SQL.squish
7
- DO $$
8
- BEGIN
9
- IF NOT EXISTS (
10
- SELECT 1 FROM pg_type t WHERE t.typname = 'hoardable_operation'
11
- ) THEN
12
- CREATE TYPE hoardable_operation AS ENUM ('update', 'delete', 'insert');
13
- END IF;
14
- END
15
- $$;
4
+ def change
5
+ create_function :hoardable_prevent_update_id
6
+ create_function :hoardable_source_set_id
7
+ create_function :hoardable_version_prevent_update
8
+ <% if supports_schema_enums? %>
9
+ create_enum :hoardable_operation, %w[update delete insert]
10
+ <% else %>
11
+ reversible do |dir|
12
+ dir.up do
13
+ execute(
14
+ <<~SQL.squish
15
+ DO $$
16
+ BEGIN
17
+ IF NOT EXISTS (
18
+ SELECT 1 FROM pg_type t WHERE t.typname = 'hoardable_operation'
19
+ ) THEN
20
+ CREATE TYPE hoardable_operation AS ENUM ('update', 'delete', 'insert');
21
+ END IF;
22
+ END
23
+ $$;
24
+ SQL
25
+ )
26
+ end
16
27
 
17
- CREATE OR REPLACE FUNCTION hoardable_source_set_id() RETURNS trigger
18
- LANGUAGE plpgsql AS
19
- $$
20
- DECLARE
21
- _pk information_schema.constraint_column_usage.column_name%TYPE;
22
- _id _pk%TYPE;
23
- BEGIN
24
- SELECT c.column_name
25
- FROM information_schema.table_constraints t
26
- JOIN information_schema.constraint_column_usage c
27
- ON c.constraint_name = t.constraint_name
28
- WHERE c.table_name = TG_TABLE_NAME AND t.constraint_type = 'PRIMARY KEY'
29
- LIMIT 1
30
- INTO _pk;
31
- EXECUTE format('SELECT $1.%I', _pk) INTO _id USING NEW;
32
- NEW.hoardable_id = _id;
33
- RETURN NEW;
34
- END;$$;
35
-
36
- CREATE OR REPLACE FUNCTION hoardable_prevent_update_id() RETURNS trigger
37
- LANGUAGE plpgsql AS
38
- $$BEGIN
39
- IF NEW.hoardable_id <> OLD.hoardable_id THEN
40
- RAISE EXCEPTION 'hoardable id cannot be updated';
41
- END IF;
42
- RETURN NEW;
43
- END;$$;
44
-
45
- CREATE OR REPLACE FUNCTION hoardable_version_prevent_update() RETURNS trigger
46
- LANGUAGE plpgsql AS
47
- $$BEGIN
48
- RAISE EXCEPTION 'updating a version is not allowed';
49
- RETURN NEW;
50
- END;$$;
51
- SQL
52
- )
53
- end
54
-
55
- def down
56
- execute(
57
- <<~SQL.squish
58
- DROP TYPE IF EXISTS hoardable_operation;
59
- DROP FUNCTION IF EXISTS hoardable_version_prevent_update();
60
- DROP FUNCTION IF EXISTS hoardable_source_set_id();
61
- DROP FUNCTION IF EXISTS hoardable_prevent_update_id();
62
- SQL
63
- )
28
+ dir.down do
29
+ execute('DROP TYPE IF EXISTS hoardable_operation;')
30
+ end
31
+ end
32
+ <% end %>
64
33
  end
65
34
  end
@@ -12,34 +12,15 @@ class Create<%= class_name.singularize.delete(':') %>Versions < ActiveRecord::Mi
12
12
  end
13
13
  reversible do |dir|
14
14
  dir.up do
15
- execute(
16
- <<~SQL
17
- UPDATE <%= table_name %> SET hoardable_id = <%= primary_key %>;
18
- CREATE TRIGGER <%= singularized_table_name %>_versions_prevent_update
19
- BEFORE UPDATE ON <%= singularized_table_name %>_versions FOR EACH ROW
20
- EXECUTE PROCEDURE hoardable_version_prevent_update();
21
- CREATE TRIGGER <%= table_name %>_set_hoardable_id
22
- BEFORE INSERT ON <%= table_name %> FOR EACH ROW
23
- EXECUTE PROCEDURE hoardable_source_set_id();
24
- CREATE TRIGGER <%= table_name %>_prevent_update_hoardable_id
25
- BEFORE UPDATE ON <%= table_name %> FOR EACH ROW
26
- EXECUTE PROCEDURE hoardable_prevent_update_id();
27
- SQL
28
- )
29
- end
30
- dir.down do
31
- execute(
32
- <<~SQL
33
- DROP TRIGGER <%= singularized_table_name %>_versions_prevent_update
34
- ON <%= singularized_table_name %>_versions;
35
- DROP TRIGGER <%= table_name %>_set_hoardable_id
36
- ON <%= table_name %>;
37
- DROP TRIGGER <%= table_name %>_prevent_update_hoardable_id
38
- ON <%= table_name %>;
39
- SQL
40
- )
15
+ execute('UPDATE <%= table_name %> SET hoardable_id = <%= primary_key %>;')
41
16
  end
42
17
  end
18
+ create_trigger(
19
+ :<%= singularized_table_name %>_versions_prevent_update,
20
+ on: :<%= singularized_table_name %>_versions
21
+ )
22
+ create_trigger :<%= table_name %>_set_hoardable_id, on: :<%= table_name %>
23
+ create_trigger :<%= table_name %>_prevent_update_hoardable_id, on: :<%= table_name %>
43
24
  change_column_null :<%= table_name %>, :hoardable_id, false
44
25
  add_index :<%= singularized_table_name %>_versions, :<%= primary_key %>, unique: true
45
26
  add_index :<%= singularized_table_name %>_versions, :hoardable_id
@@ -0,0 +1,3 @@
1
+ CREATE TRIGGER <%= table_name %>_prevent_update_hoardable_id
2
+ BEFORE UPDATE ON <%= table_name %> FOR EACH ROW
3
+ EXECUTE PROCEDURE hoardable_prevent_update_id();
@@ -0,0 +1,3 @@
1
+ CREATE TRIGGER <%= table_name %>_set_hoardable_id
2
+ BEFORE INSERT ON <%= table_name %> FOR EACH ROW
3
+ EXECUTE PROCEDURE hoardable_source_set_id();
@@ -0,0 +1,3 @@
1
+ CREATE TRIGGER <%= singularized_table_name %>_versions_prevent_update
2
+ BEFORE UPDATE ON <%= singularized_table_name %>_versions FOR EACH ROW
3
+ EXECUTE PROCEDURE hoardable_version_prevent_update();
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hoardable
4
- VERSION = '0.13.0'
4
+ VERSION = '0.14.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoardable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - justin talbott
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-09 00:00:00.000000000 Z
11
+ date: 2023-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -70,6 +70,26 @@ dependencies:
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
72
  version: '8'
73
+ - !ruby/object:Gem::Dependency
74
+ name: fx
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0.8'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '1'
73
93
  - !ruby/object:Gem::Dependency
74
94
  name: pg
75
95
  requirement: !ruby/object:Gem::Requirement
@@ -104,10 +124,16 @@ files:
104
124
  - LICENSE.txt
105
125
  - README.md
106
126
  - Rakefile
127
+ - lib/generators/hoardable/functions/hoardable_prevent_update_id.sql
128
+ - lib/generators/hoardable/functions/hoardable_source_set_id.sql
129
+ - lib/generators/hoardable/functions/hoardable_version_prevent_update.sql
107
130
  - lib/generators/hoardable/install_generator.rb
108
131
  - lib/generators/hoardable/migration_generator.rb
109
132
  - lib/generators/hoardable/templates/install.rb.erb
110
133
  - lib/generators/hoardable/templates/migration.rb.erb
134
+ - lib/generators/hoardable/triggers/prevent_update_hoardable_id.sql
135
+ - lib/generators/hoardable/triggers/set_hoardable_id.sql
136
+ - lib/generators/hoardable/triggers/versions_prevent_update.sql
111
137
  - lib/hoardable.rb
112
138
  - lib/hoardable/associations.rb
113
139
  - lib/hoardable/belongs_to.rb
@@ -141,14 +167,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
167
  requirements:
142
168
  - - ">="
143
169
  - !ruby/object:Gem::Version
144
- version: 2.6.0
170
+ version: 2.7.0
145
171
  required_rubygems_version: !ruby/object:Gem::Requirement
146
172
  requirements:
147
173
  - - ">="
148
174
  - !ruby/object:Gem::Version
149
175
  version: '0'
150
176
  requirements: []
151
- rubygems_version: 3.3.7
177
+ rubygems_version: 3.4.6
152
178
  signing_key:
153
179
  specification_version: 4
154
180
  summary: An ActiveRecord extension for versioning and soft-deletion of records in