From 4fbbb2114788cc68b631924a38e75a285471e0e3 Mon Sep 17 00:00:00 2001 From: eliasjpr Date: Sat, 14 Sep 2024 08:50:23 -0400 Subject: [PATCH] Support JSON::Any type in database operations - Updated `json` method in `src/table.cr` to use `JSON::Any` type for columns. - Modified `src/insert.cr` and `src/update.cr` to handle `JSON::Any` type correctly during insert and update operations. - Added `JSON::Any` to the list of supported types in `src/cql.cr`. - Enhanced test in `spec/adapters/postgres_schema_spec.cr` to validate JSON::Any handling in insert and update operations. --- spec/adapters/postgres_schema_spec.cr | 16 +++++++++++++++- src/cql.cr | 3 ++- src/insert.cr | 8 +++++++- src/table.cr | 2 +- src/update.cr | 7 ++++++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/spec/adapters/postgres_schema_spec.cr b/spec/adapters/postgres_schema_spec.cr index 9093579..bbbf979 100644 --- a/spec/adapters/postgres_schema_spec.cr +++ b/spec/adapters/postgres_schema_spec.cr @@ -25,13 +25,27 @@ describe Cql::Schema do # end it "fetches user preferences" do + payload_json = %({"theme": "dark"}) + json_any = JSON.parse(payload_json) + Example .insert .into(:user_pref) - .values(preferences: %({"theme": "dark"})) + .values(preferences: json_any) .commit result = Example.query.from(:user_pref).limit(1).first!(UserPref) result.preferences.should be_a(JSON::Any) + result.preferences.should eq(json_any) + + Example + .update + .table(:user_pref) + .set(preferences: json_any) + .where { user_pref.id.eq(1_i64) } + .commit + + result.preferences.should be_a(JSON::Any) + result.preferences.should eq(json_any) end end diff --git a/src/cql.cr b/src/cql.cr index 57fbfe0..e59667c 100644 --- a/src/cql.cr +++ b/src/cql.cr @@ -37,7 +37,8 @@ module Cql String.class | Time.class | UUID.class | - Nil.class + Nil.class | + JSON::Any.class # :nodoc: DB_TYPE_MAPPING = { diff --git a/src/insert.cr b/src/insert.cr index 02ae6ff..73fa05e 100644 --- a/src/insert.cr +++ b/src/insert.cr @@ -231,7 +231,13 @@ module Cql @columns = keys if @columns.empty? - vals = fields.values.map { |v| v.as(DB::Any) } + vals = fields.values.map do |v| + if v.is_a?(JSON::Any) + v.to_json.as(DB::Any) + else + v.as(DB::Any) + end + end @values << vals.to_a end diff --git a/src/table.cr b/src/table.cr index 4fe2221..352e4e0 100644 --- a/src/table.cr +++ b/src/table.cr @@ -302,7 +302,7 @@ module Cql end def json(name : Symbol, as as_name : String? = nil, null : Bool = false, default : DB::Any = nil, unique : Bool = false, index : Bool = false) - col = Column(String).new(name, String, as_name, null, default, unique) + col = Column(JSON::Any).new(name, JSON::Any, as_name, null, default, unique) col.table = self @columns[name] = col col.index = index ? add_index(columns: [name], unique: unique) : nil diff --git a/src/update.cr b/src/update.cr index 3f264a5..bbbc538 100644 --- a/src/update.cr +++ b/src/update.cr @@ -255,7 +255,12 @@ module Cql setters.each do |k, v| column = find_column(k) column.validate!(v) - @setters << Expression::Setter.new(Expression::Column.new(column), v) + val = if v.is_a?(JSON::Any) + v.to_json.as(DB::Any) + else + v.as(DB::Any) + end + @setters << Expression::Setter.new(Expression::Column.new(column), val) end end