Skip to content

Commit

Permalink
Merge pull request #13 from spider-gazelle/feat/optional_array
Browse files Browse the repository at this point in the history
feat: Added support for nillable Array/Set/Enum
  • Loading branch information
naqvis authored Aug 6, 2024
2 parents 282c353 + 127c3d6 commit 015d8e2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
15 changes: 15 additions & 0 deletions spec/persistence_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,21 @@ describe "callbacks" do
model.name.should eq "bob"
end

it "test nillable array columns" do
model = Arrtest.where("arr2 @> ARRAY['three']").first?
model.should_not be_nil
model = model.not_nil!
model.arr1.should be_nil

model.try &.reload!
model.arr1.should be_nil

model = Arrtest.create!(arr1: ["one"])
model.id.should_not be_nil
model.arr1.should eq(["one"])
model.arr2.should eq([] of String)
end

it "test update fields on array columns" do
model = Tree.create
model.update_fields(roots: ["Node1", "Node2"])
Expand Down
13 changes: 13 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ Spec.before_suite do
starting_time TIME GENERATED ALWAYS AS ((TO_TIMESTAMP(ts::BIGINT) AT TIME ZONE 'UTC')::TIME) STORED
);
SQL

db.exec <<-SQL
CREATE TABLE IF NOT EXISTS arrtest (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
arr1 TEXT [],
arr2 TEXT[] NOT NULL DEFAULT '{}'
);
SQL

db.exec <<-SQL
INSERT INTO arrtest(arr2) values('{"three","four"}');
SQL
end

1.upto(2) do |_|
Expand Down Expand Up @@ -183,5 +195,6 @@ Spec.after_suite do
db.exec "DROP TABLE IF EXISTS root"
db.exec "DROP TABLE IF EXISTS enums"
db.exec "DROP TABLE IF EXISTS compute"
db.exec "DROP TABLE IF EXISTS arrtest"
end
end
5 changes: 5 additions & 0 deletions spec/spec_models.cr
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,8 @@ class ModelWithComputedFields < PgORM::Base
attribute ts : Int64
attribute description : String, read_only: true
end

class Arrtest < PgORM::Base
attribute arr1 : Array(String)? = nil
attribute arr2 : Array(String) = [] of String
end
10 changes: 5 additions & 5 deletions src/pg-orm/base.cr
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ module PgORM
var_{{key}} =
{% if opts[:converter] %}
{{opts[:converter]}}.from_rs(rs)
{% elsif opts[:klass] < Array %}
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Array %}
rs.read({{opts[:klass]}})
{% elsif opts[:klass] < Set %}
rs.read(Array({{opts[:klass].type_vars.join(' ').id}})).to_set
Expand Down Expand Up @@ -252,9 +252,9 @@ module PgORM
@{{key}} =
{% if opts[:converter] %}
{{opts[:converter]}}.from_rs(rs)
{% elsif opts[:klass] < Array %}
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Array %}
rs.read({{opts[:klass]}})
{% elsif opts[:klass] < Set %}
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Set %}
rs.read(Array({{opts[:klass].type_vars.join(' ').id}})).to_set
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Enum %}
{% if opts[:klass].nilable? %}
Expand Down Expand Up @@ -310,9 +310,9 @@ module PgORM
{
{% for name, opts in PERSIST %}
{% if !opts[:tags] || (tags = opts[:tags]) && (!tags[:read_only]) %}
{% if opts[:klass] < Array && !opts[:converter] %}
{% if opts[:klass].union_types.reject(&.==(Nil)).first < Array && !opts[:converter] %}
:{{name}} => PQ::Param.encode_array(@{{name}} || ([] of {{opts[:klass]}})),
{% elsif opts[:klass] < Set %}
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Set %}
:{{name}} => PQ::Param.encode_array((@{{name}} || (Set({{opts[:klass]}}).new)).to_a),
{% elsif opts[:klass].union_types.reject(&.==(Nil)).first < Enum && !opts[:converter] %}
:{{name}} => @{{name}}.try &.value,
Expand Down
10 changes: 5 additions & 5 deletions test
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ set -eu
# this function is called when Ctrl-C is sent
function trap_ctrlc ()
{
docker-compose down &> /dev/null
docker compose down &> /dev/null
exit 2
}

# initialise trap to call trap_ctrlc function
# when signal 2 (SIGINT) is received
trap "trap_ctrlc" 2

docker-compose pull -q
docker compose pull -q

docker-compose build -q
docker compose build -q

exit_code="0"

docker-compose run --rm pgorm "$@" || exit_code="$?"
docker compose run --rm pgorm "$@" || exit_code="$?"

docker-compose down &> /dev/null
docker compose down &> /dev/null

exit ${exit_code}

0 comments on commit 015d8e2

Please sign in to comment.