hoardable 0.16.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +15 -0
- data/lib/generators/hoardable/functions/set_hoardable_id.sql +7 -0
- data/lib/generators/hoardable/install_generator.rb +1 -1
- data/lib/generators/hoardable/migration_generator.rb +8 -0
- data/lib/generators/hoardable/templates/install.rb.erb +0 -1
- data/lib/generators/hoardable/templates/migration.rb.erb +2 -1
- data/lib/generators/hoardable/triggers/set_hoardable_id.sql +1 -1
- data/lib/hoardable/database_client.rb +8 -1
- data/lib/hoardable/engine.rb +11 -1
- data/lib/hoardable/error.rb +10 -0
- data/lib/hoardable/version.rb +1 -1
- metadata +7 -7
- data/lib/generators/hoardable/functions/hoardable_source_set_id.sql +0 -18
- /data/lib/generators/hoardable/{functions → install_functions}/hoardable_prevent_update_id.sql +0 -0
- /data/lib/generators/hoardable/{functions → install_functions}/hoardable_version_prevent_update.sql +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 888659d9c6655e69c72fd8cf5b10b3697d5a81f432a44c8fa39984a05f4b23d9
|
4
|
+
data.tar.gz: ba850c1bf2363dd965a6e7780435d4feaf2ad417f2712f5f4635398ad5e9913d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 851d039e113df11834b18bb69edf786ba1d91598e408a45fab6ae7bb65efbc37264e4b803b8c8335f6839784f964f20d29c4c94b02aa6b994a21f3fd346ec162
|
7
|
+
data.tar.gz: 022a7ada38d996f8116a7ab8ed3d671e29055a8c75cc4155789ea3be135d87f24625ab67311c22f3b89b172320a973cbf203586407c6788750443bec90b461be
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -235,6 +235,21 @@ version.changes # => { "title"=> ["Title", "New Title"] }
|
|
235
235
|
version.hoardable_operation # => "update"
|
236
236
|
```
|
237
237
|
|
238
|
+
### Overriding the temporal range
|
239
|
+
|
240
|
+
When calculating the temporal range for a given version, the default upper bound is `Time.now.utc`.
|
241
|
+
|
242
|
+
You can, however, use the `Hoardable.travel_to` class method to specify a custom upper bound for the time range. This allows
|
243
|
+
you to specify the datetime that a particular change should be recorded at by passing a block:
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
Hoardable.travel_to(2.weeks.ago) do
|
247
|
+
post.destroy!
|
248
|
+
end
|
249
|
+
```
|
250
|
+
|
251
|
+
Note: If the provided datetime pre-dates the calculated lower bound then an `InvalidTemporalUpperBoundError` will be raised.
|
252
|
+
|
238
253
|
### Model Callbacks
|
239
254
|
|
240
255
|
Sometimes you might want to do something with a version after it gets inserted to the database. You
|
@@ -25,7 +25,7 @@ module Hoardable
|
|
25
25
|
|
26
26
|
def create_functions
|
27
27
|
Dir
|
28
|
-
.glob(File.join(__dir__, "
|
28
|
+
.glob(File.join(__dir__, "install_functions", "*.sql"))
|
29
29
|
.each do |file_path|
|
30
30
|
file_name = file_path.match(%r{([^/]+)\.sql})[1]
|
31
31
|
template file_path, "db/functions/#{file_name}_v01.sql"
|
@@ -36,7 +36,15 @@ module Hoardable
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def create_function
|
40
|
+
template("../functions/set_hoardable_id.sql", "db/functions/#{function_name}_v01.sql")
|
41
|
+
end
|
42
|
+
|
39
43
|
no_tasks do
|
44
|
+
def function_name
|
45
|
+
"hoardable_set_hoardable_id_from_#{primary_key}"
|
46
|
+
end
|
47
|
+
|
40
48
|
def table_name
|
41
49
|
class_name.singularize.constantize.table_name
|
42
50
|
rescue StandardError
|
@@ -4,7 +4,6 @@ class InstallHoardable < ActiveRecord::Migration[<%= ActiveRecord::Migration.cur
|
|
4
4
|
def change
|
5
5
|
<% if postgres_version < 13 %>enable_extension :pgcrypto
|
6
6
|
<% end %>create_function :hoardable_prevent_update_id
|
7
|
-
create_function :hoardable_source_set_id
|
8
7
|
create_function :hoardable_version_prevent_update
|
9
8
|
create_enum :hoardable_operation, %w[update delete insert]
|
10
9
|
end
|
@@ -6,7 +6,7 @@ class Create<%= class_name.singularize.delete(':') %>Versions < ActiveRecord::Mi
|
|
6
6
|
add_index :<%= table_name %>, :hoardable_id
|
7
7
|
create_table(
|
8
8
|
:<%= singularized_table_name %>_versions,
|
9
|
-
id: false,
|
9
|
+
id: false,
|
10
10
|
options: 'INHERITS (<%= table_name %>)',
|
11
11
|
) do |t|
|
12
12
|
t.jsonb :_data
|
@@ -25,6 +25,7 @@ class Create<%= class_name.singularize.delete(':') %>Versions < ActiveRecord::Mi
|
|
25
25
|
:<%= singularized_table_name %>_versions_prevent_update,
|
26
26
|
on: :<%= singularized_table_name %>_versions
|
27
27
|
)
|
28
|
+
create_function :<%= function_name %>
|
28
29
|
create_trigger :<%= table_name %>_set_hoardable_id, on: :<%= table_name %>
|
29
30
|
create_trigger :<%= table_name %>_prevent_update_hoardable_id, on: :<%= table_name %>
|
30
31
|
change_column_null :<%= table_name %>, :hoardable_id, false
|
@@ -93,7 +93,14 @@ module Hoardable
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def initialize_temporal_range
|
96
|
-
(
|
96
|
+
upper_bound = Hoardable.instance_variable_get("@travel_to") || Time.now.utc
|
97
|
+
lower_bound = (previous_temporal_tsrange_end || hoardable_source_epoch)
|
98
|
+
|
99
|
+
if upper_bound < lower_bound
|
100
|
+
raise InvalidTemporalUpperBoundError.new(upper_bound, lower_bound)
|
101
|
+
end
|
102
|
+
|
103
|
+
(lower_bound..upper_bound)
|
97
104
|
end
|
98
105
|
|
99
106
|
def initialize_hoardable_data
|
data/lib/hoardable/engine.rb
CHANGED
@@ -81,6 +81,16 @@ module Hoardable
|
|
81
81
|
@at = nil
|
82
82
|
end
|
83
83
|
|
84
|
+
# Allows calling code to set the upper bound for the temporal range for recorded audits.
|
85
|
+
#
|
86
|
+
# @param datetime [DateTime] the datetime to temporally record versions at
|
87
|
+
def travel_to(datetime)
|
88
|
+
@travel_to = datetime
|
89
|
+
yield
|
90
|
+
ensure
|
91
|
+
@travel_to = nil
|
92
|
+
end
|
93
|
+
|
84
94
|
# @!visibility private
|
85
95
|
def logger
|
86
96
|
@logger ||= ActiveSupport::TaggedLogging.new(Logger.new($stdout))
|
@@ -101,7 +111,7 @@ module Hoardable
|
|
101
111
|
initializer "hoardable.schema_statements" do
|
102
112
|
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
103
113
|
# We need to control the table dumping order of tables, so revert these to just +super+
|
104
|
-
Fx::SchemaDumper
|
114
|
+
Fx::SchemaDumper.module_eval("def tables(streams); super; end")
|
105
115
|
|
106
116
|
ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper.prepend(SchemaDumper)
|
107
117
|
ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(SchemaStatements)
|
data/lib/hoardable/error.rb
CHANGED
@@ -24,4 +24,14 @@ module Hoardable
|
|
24
24
|
LOG
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
# An error to be raised when the provided temporal upper bound is before the calcualated lower bound.
|
29
|
+
class InvalidTemporalUpperBoundError < Error
|
30
|
+
def initialize(upper, lower)
|
31
|
+
super(<<~LOG)
|
32
|
+
'The supplied value to `Hoardable.travel_to` (#{upper}) is before the calculated lower bound (#{lower}).
|
33
|
+
You must provide a datetime > the lower bound.
|
34
|
+
LOG
|
35
|
+
end
|
36
|
+
end
|
27
37
|
end
|
data/lib/hoardable/version.rb
CHANGED
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.
|
4
|
+
version: 0.17.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: 2024-
|
11
|
+
date: 2024-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.9'
|
62
62
|
- - "<"
|
63
63
|
- !ruby/object:Gem::Version
|
64
64
|
version: '1'
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
requirements:
|
69
69
|
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: '0.
|
71
|
+
version: '0.9'
|
72
72
|
- - "<"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '1'
|
@@ -106,9 +106,9 @@ files:
|
|
106
106
|
- LICENSE.txt
|
107
107
|
- README.md
|
108
108
|
- Rakefile
|
109
|
-
- lib/generators/hoardable/functions/
|
110
|
-
- lib/generators/hoardable/
|
111
|
-
- lib/generators/hoardable/
|
109
|
+
- lib/generators/hoardable/functions/set_hoardable_id.sql
|
110
|
+
- lib/generators/hoardable/install_functions/hoardable_prevent_update_id.sql
|
111
|
+
- lib/generators/hoardable/install_functions/hoardable_version_prevent_update.sql
|
112
112
|
- lib/generators/hoardable/install_generator.rb
|
113
113
|
- lib/generators/hoardable/migration_generator.rb
|
114
114
|
- lib/generators/hoardable/templates/install.rb.erb
|
@@ -1,18 +0,0 @@
|
|
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;$$;
|
/data/lib/generators/hoardable/{functions → install_functions}/hoardable_prevent_update_id.sql
RENAMED
File without changes
|
/data/lib/generators/hoardable/{functions → install_functions}/hoardable_version_prevent_update.sql
RENAMED
File without changes
|