Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking changes on JSONB column #171

Closed
edymerchk opened this issue Jan 4, 2021 · 1 comment · Fixed by #173
Closed

Tracking changes on JSONB column #171

edymerchk opened this issue Jan 4, 2021 · 1 comment · Fixed by #173

Comments

@edymerchk
Copy link

edymerchk commented Jan 4, 2021

Tell us about your environment

Ruby Version: 2.6.3p62

Rails Version: 6.0.3

PostgreSQL Version: 11.8

Logidze Version: 1.0.0

What did you do?

Tried to use logidze tracking a JSONB column

I have a table like:

create_table :users do |t|
  t.jsonb :data

  t.timestamps
end

and a trigger (generated by gem) like:

CREATE TRIGGER logidze_on_users
BEFORE UPDATE OR INSERT ON users FOR EACH ROW
WHEN (coalesce(current_setting('logidze.disabled', true), '') <> 'on')
-- Parameters: history_size_limit (integer), timestamp_column (text), filtered_columns (text[]),
-- include_columns (boolean), debounce_time_ms (integer)
EXECUTE PROCEDURE logidze_logger(null, 'updated_at', '{data}', true);

What did you expect to happen?

Store always the changes in the same format

What actually happened?

First change is stored as JSON, but subsequent are Stringify

u = User.create!(data: {hello: 1})
u.update!(data: {hello: 2})
u.update!(data: {hello: 3})
u.reload.log_data =>

 #<Logidze::History:0x00007f956b5d2908 @data={"h"=>[
   {"c"=>{"data"=>{"hello"=>1}}, "v"=>1, "ts"=>1609790311222}, 
   {"c"=>{"data"=>"{\"hello\": 2}"}, "v"=>2, "ts"=>1609790311226}, 
   {"c"=>{"data"=>"{\"hello\": 3}"}, "v"=>3, "ts"=>1609790381173}],
"v"=>3}>

BTW! Thank you for this amazing gem!

@palkan
Copy link
Owner

palkan commented Jan 5, 2021

Thanks for the report!

That's what happening here (a note to everyone who would like to pick this issue while I'm enjoying New Year holidays 🎄):

  • We use hstore_to_jsonb_loose to efficiently calculate diffs between two JSONB objects—that happens only on UPDATE.
  • Initial snapshot doesn't use hstore, thus, we store JSONB as as.

To fix this we need to ensure that snapshots also stringify values.

P.S. @edymerchk except from the format difference, does it cause any issues? I guess, we handle this at the Ruby side correctly, i.e., both strings and Hashes are deserialized into Hashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants