lucky_migrator icon indicating copy to clipboard operation
lucky_migrator copied to clipboard

Add support for JSON::Any columns

Open mikeeus opened this issue 6 years ago • 2 comments

crystal-pg already has support for json and jsonb types using JSON::Any. Adding support for this would be a useful feature for some people.

class Post < BaseModel
  table :posts do
    column title : JSON::Any
    column author : JSON::Any
  end
end

Querying is very powerful and allowing json operators on these columns would be pretty amazing. But this would be a lot of work and I don't think it's priority, I just want to leave it here for consideration.

-> | int | Get JSON array element (indexed from zero, negative integers count from the end) | '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 | {"c":"baz"}
-- | -- | -- | -- | --
-> | text | Get JSON object field by key | '{"a": {"b":"foo"}}'::json->'a' | {"b":"foo"}
->> | int | Get JSON array element as text | '[1,2,3]'::json->>2 | 3
->> | text | Get JSON object field as text | '{"a":1,"b":2}'::json->>'b' | 2
#> | text[] | Get JSON object at specified path | '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}' | {"c": "foo"}
#>> | text[] | Get JSON object at specified path as text | '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}' | 3

And jsonb operators

@>	jsonb	Does the left JSON value contain the right JSON path/value entries at the top level?
<@	jsonb	Are the left JSON path/value entries contained at the top level within the right JSON value?
?	text	Does the string exist as a top-level key within the JSON value?
?|	text[]	Do any of these array strings exist as top-level keys?
?&	text[]	Do all of these array strings exist as top-level keys?
||	jsonb	Concatenate two jsonb values into a new jsonb value
-	text	Delete key/value pair or string element from left operand. Key/value pairs are matched based on their key value.
-	integer	Delete the array element with specified index (Negative integers count from the end). Throws an error if top level container is not an array.
#-	text[]	Delete the field or element with specified path (for JSON arrays, negative integers count from the end)

mikeeus avatar Jul 26 '18 06:07 mikeeus

This is a fantastic idea. I also agree that at first it can be added w/o any special methods for querying, but eventually I'd love to be able to do something like this:

PostQuery.new.author.has(:email. "[email protected]") 

Because I find the symbols they use super hard to understand :P

paulcsmith avatar Jul 26 '18 15:07 paulcsmith

I agree the operators are cryptic, and I like the has operation, it reads nice. I'll see if I can get time this weekend to start on this because I could actually use it in one of my projects

mikeeus avatar Jul 26 '18 15:07 mikeeus