logidze 1.1.0 → 1.2.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +46 -7
- data/lib/generators/logidze/install/functions/logidze_capture_exception.sql +23 -0
- data/lib/generators/logidze/install/functions/logidze_logger.sql +70 -17
- data/lib/generators/logidze/install/functions/logidze_snapshot.sql +2 -1
- data/lib/generators/logidze/install/functions/logidze_version.sql +2 -1
- data/lib/generators/logidze/model/model_generator.rb +4 -3
- data/lib/generators/logidze/model/templates/migration.rb.erb +13 -5
- data/lib/generators/logidze/model/triggers/logidze.sql +2 -2
- data/lib/logidze/history.rb +1 -1
- data/lib/logidze/model.rb +2 -2
- data/lib/logidze/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68d689e98373be99d5039ebc70fc05d369a75b94e20ef0bb9d0d9d43e70c3887
|
|
4
|
+
data.tar.gz: 3c3c24bd36f3af269d1443562f271ede71d222dfea5ad8d52c9199ca72d91244
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 78217c05e5bab5aa2ce2a865c1a9e84cdf76ceb56e52e951394c58e098f295732981fc911a499d6c6fd2fa81f3ea25636dcd1708f8940df068dfc37ca367cfac
|
|
7
|
+
data.tar.gz: 0e050d100d842aaeb75b9f7764d4ee5e862ace9cfe3a880f0538839898f87ebf317884d51136be8600e374f8ceeed38605aa44b0952b16f270df20b5017e99c2
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## master (unreleased)
|
|
4
4
|
|
|
5
|
+
## 1.2.2 (2022-07-13)
|
|
6
|
+
|
|
7
|
+
- [Fixes [#209](https://github.com/palkan/logidze/issues/209)] Fix tracking JSONB column changes. ([@baygeldin][])
|
|
8
|
+
|
|
9
|
+
## 1.2.1 (2022-01-13)
|
|
10
|
+
|
|
11
|
+
- [Fixes [#207](https://github.com/palkan/logidze/issues/207)] Add support for the use of `table_name_prefix` or `table_name_suffix`. ([@cavi21][])
|
|
12
|
+
|
|
13
|
+
- [Fixes [#205](https://github.com/palkan/logidze/issues/205)] Allow `rails destroy logidze:model SomeModel` to delete the migration file. ([@danielmklein][])
|
|
14
|
+
|
|
15
|
+
## 1.2.0 (2021-06-11)
|
|
16
|
+
|
|
17
|
+
- Add user-defined exception handling ([@skryukov][])
|
|
18
|
+
|
|
19
|
+
By default, Logidze raises an exception which causes the entire transaction to fail.
|
|
20
|
+
To change this behavior, it's now possible to override `logidze_capture_exception(error_data jsonb)` function.
|
|
21
|
+
|
|
22
|
+
- [Fixes [#69](https://github.com/palkan/logidze/issues/69)] Fallback on NUMERIC_VALUE_OUT_OF_RANGE exception ([@skryukov][])
|
|
23
|
+
|
|
24
|
+
- [Fixes [#192](https://github.com/palkan/logidze/issues/192)] Skip `log_data` column during `apply_column_diff` ([@skryukov][])
|
|
25
|
+
|
|
5
26
|
## 1.1.0 (2021-03-31)
|
|
6
27
|
|
|
7
28
|
- Add pending upgrade checks [Experimental]. ([@skryukov][])
|
|
@@ -347,3 +368,7 @@ This is a quick fix for a more general problem (see [#59](https://github.com/pal
|
|
|
347
368
|
[@duderman]: https://github.com/duderman
|
|
348
369
|
[@oleg-kiviljov]: https://github.com/oleg-kiviljov
|
|
349
370
|
[@skryukov]: https://github.com/skryukov
|
|
371
|
+
[@bf4]: https://github.com/bf4
|
|
372
|
+
[@cavi21]: https://github.com/cavi21
|
|
373
|
+
[@danielmklein]: https://github.com/danielmklein
|
|
374
|
+
[@baygeldin]: https://github.com/baygeldin
|
data/README.md
CHANGED
|
@@ -34,6 +34,7 @@ Other requirements:
|
|
|
34
34
|
- [Log size limits](#log-size-limits)
|
|
35
35
|
- [Tracking only selected columns](#tracking-only-selected-columns)
|
|
36
36
|
- [Logs timestamps](#logs-timestamps)
|
|
37
|
+
- [Undoing a Generated Invocation](#undoing-a-generated-invocation)
|
|
37
38
|
- [Usage](#usage)
|
|
38
39
|
- [Basic API](#basic-api)
|
|
39
40
|
- [Track meta information](#track-meta-information)
|
|
@@ -44,6 +45,7 @@ Other requirements:
|
|
|
44
45
|
- [Associations versioning](#associations-versioning)
|
|
45
46
|
- [Dealing with large logs](#dealing-with-large-logs)
|
|
46
47
|
- [Handling records deletion](#handling-records-deletion)
|
|
48
|
+
- [Handling PG exceptions](#handling-pg-exceptions)
|
|
47
49
|
- [Upgrading](#upgrading)
|
|
48
50
|
- [Log format](#log-format)
|
|
49
51
|
- [Troubleshooting 🚨](#troubleshooting)
|
|
@@ -54,7 +56,7 @@ Other requirements:
|
|
|
54
56
|
Add Logidze to your application's Gemfile:
|
|
55
57
|
|
|
56
58
|
```ruby
|
|
57
|
-
gem "logidze", "~> 1.
|
|
59
|
+
gem "logidze", "~> 1.1"
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
Install required DB extensions and create trigger function:
|
|
@@ -133,8 +135,8 @@ Model.create_logidze_snapshot
|
|
|
133
135
|
Model.create_logidze_snapshot(timestamp: :created_at)
|
|
134
136
|
|
|
135
137
|
# filter columns
|
|
136
|
-
Model.create_logidze_snapshot(only: %
|
|
137
|
-
Model.create_logidze_snapshot(except: %
|
|
138
|
+
Model.create_logidze_snapshot(only: %w[name])
|
|
139
|
+
Model.create_logidze_snapshot(except: %w[password])
|
|
138
140
|
|
|
139
141
|
# or call a similar method (but with !) on a record
|
|
140
142
|
|
|
@@ -177,6 +179,16 @@ bundle exec rails generate logidze:model Post --timestamp_column time
|
|
|
177
179
|
bundle exec rails generate logidze:model Post --timestamp_column nil # "null" and "false" will also work
|
|
178
180
|
```
|
|
179
181
|
|
|
182
|
+
### Undoing a Generated Invocation
|
|
183
|
+
|
|
184
|
+
If you would like to re-do your `rails generate` anew, as with other generators you can use `rails destroy` to revert it, which will delete the migration file and undo the injection of `has_logidze` into the model file:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
bundle exec rails destroy logidze:model Post
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**IMPORTANT**: If you use non-UTC time zone for Active Record (`config.active_record.default_timezone`), you MUST always infer log timestamps from a timestamp column (e.g., when back-filling data); otherwise, you may end up with inconsistent logs ([#199](https://github.com/palkan/logidze/issues/199)). In general, we recommend using UTC as the database time unless there is a very strong reason not to.
|
|
191
|
+
|
|
180
192
|
## Usage
|
|
181
193
|
|
|
182
194
|
### Basic API
|
|
@@ -273,11 +285,13 @@ Logidze.append_on_undo = true
|
|
|
273
285
|
You can store any meta information you want inside your version (it could be IP address, user agent, etc.). To add it you should wrap your code with a block:
|
|
274
286
|
|
|
275
287
|
```ruby
|
|
276
|
-
Logidze.with_meta(ip: request.ip) do
|
|
288
|
+
Logidze.with_meta({ip: request.ip}) do
|
|
277
289
|
post.save!
|
|
278
290
|
end
|
|
279
291
|
```
|
|
280
292
|
|
|
293
|
+
**NOTE:** You should pass metadata as a Hash; passing keyword arguments doesn't work in Ruby 3.0+.
|
|
294
|
+
|
|
281
295
|
Meta expects a hash to be passed so you won't need to encode and decode JSON manually.
|
|
282
296
|
|
|
283
297
|
By default `.with_meta` wraps the block into a DB transaction. That could lead to an unexpected behavior, especially, when using `.with_meta` within an around_action. To avoid wrapping the block into a DB transaction use `transactional: false` option.
|
|
@@ -434,6 +448,15 @@ If you want to keep changes history after records deletion as well, consider usi
|
|
|
434
448
|
|
|
435
449
|
See also the discussion: [#61](https://github.com/palkan/logidze/issues/61).
|
|
436
450
|
|
|
451
|
+
## Handling PG exceptions
|
|
452
|
+
|
|
453
|
+
By default, Logidze raises an exception which causes the entire transaction to fail.
|
|
454
|
+
To change this behavior, it's now possible to override `logidze_capture_exception(error_data jsonb)` function.
|
|
455
|
+
|
|
456
|
+
For example, you may want to raise a warning instead of an exception and complete the transaction without updating log_data.
|
|
457
|
+
|
|
458
|
+
Related issues: [#193](https://github.com/palkan/logidze/issues/193)
|
|
459
|
+
|
|
437
460
|
## Upgrading
|
|
438
461
|
|
|
439
462
|
We try to make an upgrade process as simple as possible. For now, the only required action is to create and run a migration:
|
|
@@ -462,7 +485,7 @@ $ bundle exec rails generate logidze:model Post --update --only=title,body,ratin
|
|
|
462
485
|
|
|
463
486
|
### Pending upgrade check [Experimental]
|
|
464
487
|
|
|
465
|
-
Logidze can check for a pending upgrade. Use `Logidze.
|
|
488
|
+
Logidze can check for a pending upgrade. Use `Logidze.on_pending_upgrade = :warn` to be notified by warning, or `Logidze.on_pending_upgrade = :error` if you want Logidze to raise an error.
|
|
466
489
|
|
|
467
490
|
### Upgrading from 0.x to 1.0 (edge)
|
|
468
491
|
|
|
@@ -544,11 +567,27 @@ First, when restoring data dumps you should consider using `--disable-triggers`
|
|
|
544
567
|
|
|
545
568
|
When restoring data dumps for a particular PostgreSQL schema (e.g., when using Apartment), you may encounter the issue with non-existent Logidze functions. That happens because `pg_dump` adds `SELECT pg_catalog.set_config('search_path', '', false);`, and, thus, breaks our existing triggers/functions, because they live either in "public" or in a tenant's namespace (see [this thread](https://postgrespro.com/list/thread-id/2448092)).
|
|
546
569
|
|
|
570
|
+
### `PG::NumericValueOutOfRange: ERROR: value overflows numeric format`
|
|
571
|
+
|
|
572
|
+
Due to the usage of `hstore_to_jsonb_loose` under the hood, there could be a situation when you have a string representing a number in the scientific notation (e.g., "557236406134e62000323100"). Postgres would try to convert it to a number (a pretty big one, for sure) and fail with the exception.
|
|
573
|
+
|
|
574
|
+
Related issues: [#69](https://github.com/palkan/logidze/issues/69).
|
|
575
|
+
|
|
547
576
|
## Development
|
|
548
577
|
|
|
549
|
-
|
|
578
|
+
This project requires a PostgreSQL instance running with the following setup:
|
|
579
|
+
|
|
580
|
+
```sh
|
|
581
|
+
# For testing
|
|
582
|
+
createdb -h postgres -U postgres logidze_test
|
|
583
|
+
|
|
584
|
+
# For benchmarks
|
|
585
|
+
createdb -h postgres -U postgres logidze_bench
|
|
586
|
+
createdb -h postgres -U postgres logidze_perf_bench
|
|
587
|
+
psql -d logidze_bench -c 'CREATE EXTENSION IF NOT EXISTS hstore;'
|
|
588
|
+
```
|
|
550
589
|
|
|
551
|
-
|
|
590
|
+
This project is compatible with [Reusable Docker environment](https://evilmartians.com/chronicles/reusable-development-containers-with-docker-compose-and-dip) setup.
|
|
552
591
|
|
|
553
592
|
## Contributing
|
|
554
593
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
CREATE OR REPLACE FUNCTION logidze_capture_exception(error_data jsonb) RETURNS boolean AS $body$
|
|
2
|
+
-- version: 1
|
|
3
|
+
BEGIN
|
|
4
|
+
-- Feel free to change this function to change Logidze behavior on exception.
|
|
5
|
+
--
|
|
6
|
+
-- Return `false` to raise exception or `true` to commit record changes.
|
|
7
|
+
--
|
|
8
|
+
-- `error_data` contains:
|
|
9
|
+
-- - returned_sqlstate
|
|
10
|
+
-- - message_text
|
|
11
|
+
-- - pg_exception_detail
|
|
12
|
+
-- - pg_exception_hint
|
|
13
|
+
-- - pg_exception_context
|
|
14
|
+
-- - schema_name
|
|
15
|
+
-- - table_name
|
|
16
|
+
-- Learn more about available keys:
|
|
17
|
+
-- https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html#PLPGSQL-EXCEPTION-DIAGNOSTICS-VALUES
|
|
18
|
+
--
|
|
19
|
+
|
|
20
|
+
return false;
|
|
21
|
+
END;
|
|
22
|
+
$body$
|
|
23
|
+
LANGUAGE plpgsql;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
2
|
-
-- version:
|
|
2
|
+
-- version: 3
|
|
3
3
|
DECLARE
|
|
4
4
|
changes jsonb;
|
|
5
5
|
version jsonb;
|
|
@@ -9,26 +9,32 @@ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
|
9
9
|
history_limit integer;
|
|
10
10
|
debounce_time integer;
|
|
11
11
|
current_version integer;
|
|
12
|
-
|
|
12
|
+
k text;
|
|
13
13
|
iterator integer;
|
|
14
14
|
item record;
|
|
15
15
|
columns text[];
|
|
16
16
|
include_columns boolean;
|
|
17
17
|
ts timestamp with time zone;
|
|
18
18
|
ts_column text;
|
|
19
|
+
err_sqlstate text;
|
|
20
|
+
err_message text;
|
|
21
|
+
err_detail text;
|
|
22
|
+
err_hint text;
|
|
23
|
+
err_context text;
|
|
24
|
+
err_table_name text;
|
|
25
|
+
err_schema_name text;
|
|
26
|
+
err_jsonb jsonb;
|
|
27
|
+
err_captured boolean;
|
|
19
28
|
BEGIN
|
|
20
29
|
ts_column := NULLIF(TG_ARGV[1], 'null');
|
|
21
30
|
columns := NULLIF(TG_ARGV[2], 'null');
|
|
22
31
|
include_columns := NULLIF(TG_ARGV[3], 'null');
|
|
23
32
|
|
|
24
33
|
IF TG_OP = 'INSERT' THEN
|
|
25
|
-
-- always exclude log_data column
|
|
26
|
-
changes := to_jsonb(NEW.*) - 'log_data';
|
|
27
|
-
|
|
28
34
|
IF columns IS NOT NULL THEN
|
|
29
|
-
snapshot = logidze_snapshot(
|
|
35
|
+
snapshot = logidze_snapshot(to_jsonb(NEW.*), ts_column, columns, include_columns);
|
|
30
36
|
ELSE
|
|
31
|
-
snapshot = logidze_snapshot(
|
|
37
|
+
snapshot = logidze_snapshot(to_jsonb(NEW.*), ts_column);
|
|
32
38
|
END IF;
|
|
33
39
|
|
|
34
40
|
IF snapshot#>>'{h, -1, c}' != '{}' THEN
|
|
@@ -38,13 +44,10 @@ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
|
38
44
|
ELSIF TG_OP = 'UPDATE' THEN
|
|
39
45
|
|
|
40
46
|
IF OLD.log_data is NULL OR OLD.log_data = '{}'::jsonb THEN
|
|
41
|
-
-- always exclude log_data column
|
|
42
|
-
changes := to_jsonb(NEW.*) - 'log_data';
|
|
43
|
-
|
|
44
47
|
IF columns IS NOT NULL THEN
|
|
45
|
-
snapshot = logidze_snapshot(
|
|
48
|
+
snapshot = logidze_snapshot(to_jsonb(NEW.*), ts_column, columns, include_columns);
|
|
46
49
|
ELSE
|
|
47
|
-
snapshot = logidze_snapshot(
|
|
50
|
+
snapshot = logidze_snapshot(to_jsonb(NEW.*), ts_column);
|
|
48
51
|
END IF;
|
|
49
52
|
|
|
50
53
|
IF snapshot#>>'{h, -1, c}' != '{}' THEN
|
|
@@ -67,7 +70,7 @@ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
|
67
70
|
END IF;
|
|
68
71
|
END IF;
|
|
69
72
|
|
|
70
|
-
IF NEW = OLD THEN
|
|
73
|
+
IF to_jsonb(NEW.*) = to_jsonb(OLD.*) THEN
|
|
71
74
|
RETURN NEW;
|
|
72
75
|
END IF;
|
|
73
76
|
|
|
@@ -89,11 +92,37 @@ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
|
89
92
|
changes := '{}';
|
|
90
93
|
|
|
91
94
|
IF (coalesce(current_setting('logidze.full_snapshot', true), '') = 'on') THEN
|
|
92
|
-
|
|
95
|
+
BEGIN
|
|
96
|
+
changes = hstore_to_jsonb_loose(hstore(NEW.*));
|
|
97
|
+
EXCEPTION
|
|
98
|
+
WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
|
|
99
|
+
changes = row_to_json(NEW.*)::jsonb;
|
|
100
|
+
FOR k IN (SELECT key FROM jsonb_each(changes))
|
|
101
|
+
LOOP
|
|
102
|
+
IF jsonb_typeof(changes->k) = 'object' THEN
|
|
103
|
+
changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
|
|
104
|
+
END IF;
|
|
105
|
+
END LOOP;
|
|
106
|
+
END;
|
|
93
107
|
ELSE
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
BEGIN
|
|
109
|
+
changes = hstore_to_jsonb_loose(
|
|
110
|
+
hstore(NEW.*) - hstore(OLD.*)
|
|
111
|
+
);
|
|
112
|
+
EXCEPTION
|
|
113
|
+
WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
|
|
114
|
+
changes = (SELECT
|
|
115
|
+
COALESCE(json_object_agg(key, value), '{}')::jsonb
|
|
116
|
+
FROM
|
|
117
|
+
jsonb_each(row_to_json(NEW.*)::jsonb)
|
|
118
|
+
WHERE NOT jsonb_build_object(key, value) <@ row_to_json(OLD.*)::jsonb);
|
|
119
|
+
FOR k IN (SELECT key FROM jsonb_each(changes))
|
|
120
|
+
LOOP
|
|
121
|
+
IF jsonb_typeof(changes->k) = 'object' THEN
|
|
122
|
+
changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
|
|
123
|
+
END IF;
|
|
124
|
+
END LOOP;
|
|
125
|
+
END;
|
|
97
126
|
END IF;
|
|
98
127
|
|
|
99
128
|
changes = changes - 'log_data';
|
|
@@ -145,6 +174,30 @@ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
|
|
|
145
174
|
END IF;
|
|
146
175
|
|
|
147
176
|
return NEW;
|
|
177
|
+
EXCEPTION
|
|
178
|
+
WHEN OTHERS THEN
|
|
179
|
+
GET STACKED DIAGNOSTICS err_sqlstate = RETURNED_SQLSTATE,
|
|
180
|
+
err_message = MESSAGE_TEXT,
|
|
181
|
+
err_detail = PG_EXCEPTION_DETAIL,
|
|
182
|
+
err_hint = PG_EXCEPTION_HINT,
|
|
183
|
+
err_context = PG_EXCEPTION_CONTEXT,
|
|
184
|
+
err_schema_name = SCHEMA_NAME,
|
|
185
|
+
err_table_name = TABLE_NAME;
|
|
186
|
+
err_jsonb := jsonb_build_object(
|
|
187
|
+
'returned_sqlstate', err_sqlstate,
|
|
188
|
+
'message_text', err_message,
|
|
189
|
+
'pg_exception_detail', err_detail,
|
|
190
|
+
'pg_exception_hint', err_hint,
|
|
191
|
+
'pg_exception_context', err_context,
|
|
192
|
+
'schema_name', err_schema_name,
|
|
193
|
+
'table_name', err_table_name
|
|
194
|
+
);
|
|
195
|
+
err_captured = logidze_capture_exception(err_jsonb);
|
|
196
|
+
IF err_captured THEN
|
|
197
|
+
return NEW;
|
|
198
|
+
ELSE
|
|
199
|
+
RAISE;
|
|
200
|
+
END IF;
|
|
148
201
|
END;
|
|
149
202
|
$body$
|
|
150
203
|
LANGUAGE plpgsql;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb, ts_column text DEFAULT NULL, columns text[] DEFAULT NULL, include_columns boolean DEFAULT false) RETURNS jsonb AS $body$
|
|
2
|
-
-- version:
|
|
2
|
+
-- version: 3
|
|
3
3
|
DECLARE
|
|
4
4
|
ts timestamp with time zone;
|
|
5
5
|
k text;
|
|
6
6
|
BEGIN
|
|
7
|
+
item = item - 'log_data';
|
|
7
8
|
IF ts_column IS NULL THEN
|
|
8
9
|
ts := statement_timestamp();
|
|
9
10
|
ELSE
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
CREATE OR REPLACE FUNCTION logidze_version(v bigint, data jsonb, ts timestamp with time zone) RETURNS jsonb AS $body$
|
|
2
|
-
-- version:
|
|
2
|
+
-- version: 2
|
|
3
3
|
DECLARE
|
|
4
4
|
buf jsonb;
|
|
5
5
|
BEGIN
|
|
6
|
+
data = data - 'log_data';
|
|
6
7
|
buf := jsonb_build_object(
|
|
7
8
|
'ts',
|
|
8
9
|
(extract(epoch from ts) * 1000)::bigint,
|
|
@@ -45,7 +45,7 @@ module Logidze
|
|
|
45
45
|
warn "Use only one: --only or --except"
|
|
46
46
|
exit(1)
|
|
47
47
|
end
|
|
48
|
-
migration_template "migration.rb.erb", "db/migrate/#{
|
|
48
|
+
migration_template "migration.rb.erb", "db/migrate/#{migration_name}.rb"
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def generate_fx_trigger
|
|
@@ -73,8 +73,9 @@ module Logidze
|
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
def
|
|
77
|
-
|
|
76
|
+
def full_table_name
|
|
77
|
+
config = ActiveRecord::Base
|
|
78
|
+
"#{config.table_name_prefix}#{table_name}#{config.table_name_suffix}"
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
def limit
|
|
@@ -12,14 +12,18 @@ class <%= @migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::M
|
|
|
12
12
|
dir.up do
|
|
13
13
|
<%- if update? -%>
|
|
14
14
|
# Drop legacy trigger if any (<1.0)
|
|
15
|
-
execute
|
|
15
|
+
execute <<~SQL
|
|
16
|
+
DROP TRIGGER IF EXISTS "logidze_on_<%= full_table_name %>" on "<%= full_table_name %>";
|
|
17
|
+
SQL
|
|
16
18
|
|
|
17
19
|
<%- end -%>
|
|
18
20
|
create_trigger :logidze_on_<%= table_name %>, on: :<%= table_name %>
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
dir.down do
|
|
22
|
-
execute
|
|
24
|
+
execute <<~SQL
|
|
25
|
+
DROP TRIGGER IF EXISTS "logidze_on_<%= full_table_name %>" on "<%= full_table_name %>";
|
|
26
|
+
SQL
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
<%- end -%>
|
|
@@ -27,7 +31,9 @@ class <%= @migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::M
|
|
|
27
31
|
reversible do |dir|
|
|
28
32
|
dir.up do
|
|
29
33
|
<%- if update? -%>
|
|
30
|
-
execute
|
|
34
|
+
execute <<~SQL
|
|
35
|
+
DROP TRIGGER IF EXISTS "logidze_on_<%= full_table_name %>" on "<%= full_table_name %>";
|
|
36
|
+
SQL
|
|
31
37
|
|
|
32
38
|
<%- end -%>
|
|
33
39
|
execute <<~SQL
|
|
@@ -44,7 +50,9 @@ class <%= @migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::M
|
|
|
44
50
|
# Uncomment this line if you want to raise an error.
|
|
45
51
|
# raise ActiveRecord::IrreversibleMigration
|
|
46
52
|
<%- else -%>
|
|
47
|
-
execute
|
|
53
|
+
execute <<~SQL
|
|
54
|
+
DROP TRIGGER IF EXISTS "logidze_on_<%= full_table_name %>" on "<%= full_table_name %>";
|
|
55
|
+
SQL
|
|
48
56
|
<%- end -%>
|
|
49
57
|
end
|
|
50
58
|
end
|
|
@@ -54,7 +62,7 @@ class <%= @migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::M
|
|
|
54
62
|
reversible do |dir|
|
|
55
63
|
dir.up do
|
|
56
64
|
execute <<~SQL
|
|
57
|
-
UPDATE <%=
|
|
65
|
+
UPDATE "<%= full_table_name %>" as t
|
|
58
66
|
SET log_data = logidze_snapshot(<%= logidze_snapshot_parameters %>);
|
|
59
67
|
SQL
|
|
60
68
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
CREATE TRIGGER
|
|
2
|
-
BEFORE UPDATE OR INSERT ON <%=
|
|
1
|
+
CREATE TRIGGER <%= %Q("logidze_on_#{full_table_name}") %>
|
|
2
|
+
BEFORE UPDATE OR INSERT ON <%= %Q("#{full_table_name}") %> FOR EACH ROW
|
|
3
3
|
WHEN (coalesce(current_setting('logidze.disabled', true), '') <> 'on')
|
|
4
4
|
-- Parameters: history_size_limit (integer), timestamp_column (text), filtered_columns (text[]),
|
|
5
5
|
-- include_columns (boolean), debounce_time_ms (integer)
|
data/lib/logidze/history.rb
CHANGED
|
@@ -48,7 +48,7 @@ module Logidze
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
# Return diff from the initial state to specified time or version.
|
|
51
|
-
# Optional `data`
|
|
51
|
+
# Optional `data` parameter can be used as initial diff state.
|
|
52
52
|
def changes_to(time: nil, version: nil, data: {}, from: 0)
|
|
53
53
|
raise ArgumentError, "Time or version must be specified" if time.nil? && version.nil?
|
|
54
54
|
|
data/lib/logidze/model.rb
CHANGED
|
@@ -213,7 +213,7 @@ module Logidze
|
|
|
213
213
|
|
|
214
214
|
# Loads log_data field from the database, stores to the attributes hash and returns it
|
|
215
215
|
def reload_log_data
|
|
216
|
-
self.log_data = self.class.where(self.class.primary_key => id).pluck("#{self.class.table_name}.log_data").first
|
|
216
|
+
self.log_data = self.class.where(self.class.primary_key => id).pluck("#{self.class.table_name}.log_data".to_sym).first
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
# Nullify log_data column for a single record
|
|
@@ -239,7 +239,7 @@ module Logidze
|
|
|
239
239
|
end
|
|
240
240
|
|
|
241
241
|
def apply_column_diff(column, value)
|
|
242
|
-
return if deleted_column?(column)
|
|
242
|
+
return if deleted_column?(column) || column == "log_data"
|
|
243
243
|
|
|
244
244
|
write_attribute column, deserialize_value(column, value)
|
|
245
245
|
end
|
data/lib/logidze/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logidze
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- palkan
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-07-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: railties
|
|
@@ -163,6 +163,7 @@ files:
|
|
|
163
163
|
- lib/generators/logidze/fx_helper.rb
|
|
164
164
|
- lib/generators/logidze/inject_sql.rb
|
|
165
165
|
- lib/generators/logidze/install/USAGE
|
|
166
|
+
- lib/generators/logidze/install/functions/logidze_capture_exception.sql
|
|
166
167
|
- lib/generators/logidze/install/functions/logidze_compact_history.sql
|
|
167
168
|
- lib/generators/logidze/install/functions/logidze_filter_keys.sql
|
|
168
169
|
- lib/generators/logidze/install/functions/logidze_logger.sql
|
|
@@ -200,7 +201,7 @@ metadata:
|
|
|
200
201
|
documentation_uri: http://github.com/palkan/logidze
|
|
201
202
|
homepage_uri: http://github.com/palkan/logidze
|
|
202
203
|
source_code_uri: http://github.com/palkan/logidze
|
|
203
|
-
post_install_message:
|
|
204
|
+
post_install_message:
|
|
204
205
|
rdoc_options: []
|
|
205
206
|
require_paths:
|
|
206
207
|
- lib
|
|
@@ -215,8 +216,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
216
|
- !ruby/object:Gem::Version
|
|
216
217
|
version: '0'
|
|
217
218
|
requirements: []
|
|
218
|
-
rubygems_version: 3.
|
|
219
|
-
signing_key:
|
|
219
|
+
rubygems_version: 3.3.7
|
|
220
|
+
signing_key:
|
|
220
221
|
specification_version: 4
|
|
221
222
|
summary: PostgreSQL JSONB-based model changes tracking
|
|
222
223
|
test_files: []
|