From b08a07c8a18d8c39602347ee664919b50f7164c3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kryukov Date: Sun, 10 Jan 2021 07:40:15 +0300 Subject: [PATCH 1/2] Stringify snapshot jsonb values --- .../logidze/install/functions/logidze_snapshot.sql | 8 ++++++++ spec/logidze/create_snapshot_spec.rb | 14 ++++++++++++-- spec/sql/snapshot_spec.rb | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/generators/logidze/install/functions/logidze_snapshot.sql b/lib/generators/logidze/install/functions/logidze_snapshot.sql index 14f4a79c..251c9ad8 100644 --- a/lib/generators/logidze/install/functions/logidze_snapshot.sql +++ b/lib/generators/logidze/install/functions/logidze_snapshot.sql @@ -2,6 +2,7 @@ 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$ DECLARE ts timestamp with time zone; + k text; BEGIN IF ts_column IS NULL THEN ts := statement_timestamp(); @@ -13,6 +14,13 @@ CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb, ts_column text DEFAULT N item := logidze_filter_keys(item, columns, include_columns); END IF; + FOR k IN (SELECT key FROM jsonb_each(item)) + LOOP + IF jsonb_typeof(item->k) = 'object' THEN + item := jsonb_set(item, ARRAY[k], to_jsonb(item->>k)); + END IF; + END LOOP; + return json_build_object( 'v', 1, 'h', jsonb_build_array( diff --git a/spec/logidze/create_snapshot_spec.rb b/spec/logidze/create_snapshot_spec.rb index 6628b97f..78256196 100644 --- a/spec/logidze/create_snapshot_spec.rb +++ b/spec/logidze/create_snapshot_spec.rb @@ -16,7 +16,11 @@ end let(:now) { Time.local(1989, 7, 10, 18, 23, 33) } - let(:user) { Logidze.without_logging { User.create!(time: now, name: "test", age: 10, active: false) } } + let(:user) do + Logidze.without_logging do + User.create!(time: now, name: "test", age: 10, active: false, extra: {gender: "X"}) + end + end describe "#create_logidze_snapshot!" do specify "without arguments" do @@ -27,7 +31,13 @@ expect(user.log_data).not_to be_nil expect(user.log_data.version).to eq 1 expect(Time.at(user.log_data.current_version.time / 1000) - now).to be > 1.year - expect(user.log_data.current_version.changes).to include({"name" => "test", "age" => 10, "active" => false}) + expect(user.log_data.current_version.changes) + .to include({ + "name" => "test", + "age" => 10, + "active" => false, + "extra" => '{"gender": "X"}' + }) end specify "timestamp column" do diff --git a/spec/sql/snapshot_spec.rb b/spec/sql/snapshot_spec.rb index bb755ffb..96541d2d 100644 --- a/spec/sql/snapshot_spec.rb +++ b/spec/sql/snapshot_spec.rb @@ -3,9 +3,9 @@ require "acceptance_helper" describe "logidze_snapshot" do - let(:now) { Time.local(1989, 7, 10, 18, 23, 33) } + let(:now) { Time.zone.local(1989, 7, 10, 18, 23, 33) } - let(:data) { %('{"title": "Feel me", "rating": 42, "name": "Jack", "updated_at": "#{now.to_s(:db)}"}'::jsonb) } + let(:data) { %('{"title": "Feel me", "rating": 42, "name": "Jack", "extra": {"gender": "X"}, "updated_at": "#{now.to_s(:db)}"}'::jsonb) } specify "without optional args" do res = sql "select logidze_snapshot(#{data})" @@ -20,7 +20,7 @@ expect(version).to match({ "ts" => an_instance_of(Integer), "v" => 1, - "c" => a_hash_including({"title" => "Feel me", "rating" => 42, "name" => "Jack"}) + "c" => a_hash_including({"title" => "Feel me", "rating" => 42, "name" => "Jack", "extra" => '{"gender": "X"}'}) }) expect(Time.at(version["ts"] / 1000) - now).to be > 1.year From a17d5f221f7e3e2a5bbfb69c7530debdff3ff40a Mon Sep 17 00:00:00 2001 From: Svyatoslav Kryukov Date: Mon, 11 Jan 2021 17:55:42 +0300 Subject: [PATCH 2/2] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bb82302..8f969818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change log +## master (unreleased) + +- [Fixes [#171](https://github.com/palkan/logidze/issues/171)] Stringify jsonb column values within snapshots. ([@skryukov][]) + ## 1.0.0 (2020-11-09) - Add `--name` option to model generator to specify the migration name. ([@palkan][]) @@ -332,3 +336,4 @@ This is a quick fix for a more general problem (see [#59](https://github.com/pal [@zocoi]: https://github.com/zocoi [@duderman]: https://github.com/duderman [@oleg-kiviljov]: https://github.com/oleg-kiviljov +[@skryukov]: https://github.com/skryukov