Skip to content

Commit bdb52f4

Browse files
committed
add support for db.list values with include_in to match many rows together
1 parent 827c2c3 commit bdb52f4

File tree

3 files changed

+399
-60
lines changed

3 files changed

+399
-60
lines changed

lapis/db/base_model.lua

Lines changed: 116 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -744,71 +744,71 @@ do
744744
source_key = _memoize1(source_key)
745745
computed_source_key = true
746746
end
747-
local include_ids
748-
do
749-
local _accum_0 = { }
750-
local _len_0 = 1
751-
for _index_0 = 1, #other_records do
752-
local _continue_0 = false
753-
repeat
754-
local record = other_records[_index_0]
755-
if skip_included then
756-
if for_relation then
757-
if relation_is_loaded(record, for_relation) then
758-
_continue_0 = true
759-
break
760-
end
761-
else
762-
if record[field_name] ~= nil then
763-
_continue_0 = true
764-
break
765-
end
766-
end
767-
end
768-
local _value_0
769-
if composite_foreign_key then
770-
local tuple
771-
do
772-
local _accum_1 = { }
773-
local _len_1 = 1
774-
for _index_1 = 1, #source_key do
775-
local k = source_key[_index_1]
776-
if type(k) == "function" then
777-
_accum_1[_len_1] = k(record) or self.db.NULL
778-
else
779-
_accum_1[_len_1] = record[k] or self.db.NULL
780-
end
781-
_len_1 = _len_1 + 1
782-
end
783-
tuple = _accum_1
784-
end
785-
if _all_same(tuple, self.db.NULL) then
747+
local include_ids = { }
748+
for _index_0 = 1, #other_records do
749+
local _continue_0 = false
750+
repeat
751+
local record = other_records[_index_0]
752+
if skip_included then
753+
if for_relation then
754+
if relation_is_loaded(record, for_relation) then
786755
_continue_0 = true
787756
break
788757
end
789-
_value_0 = self.db.list(tuple)
790758
else
791-
local id
792-
if computed_source_key then
793-
id = source_key(record)
794-
else
795-
id = record[source_key]
796-
end
797-
if not (id) then
759+
if record[field_name] ~= nil then
798760
_continue_0 = true
799761
break
800762
end
801-
_value_0 = id
802763
end
803-
_accum_0[_len_0] = _value_0
804-
_len_0 = _len_0 + 1
805-
_continue_0 = true
806-
until true
807-
if not _continue_0 then
808-
break
809764
end
765+
if composite_foreign_key then
766+
local tuple
767+
do
768+
local _accum_0 = { }
769+
local _len_0 = 1
770+
for _index_1 = 1, #source_key do
771+
local k = source_key[_index_1]
772+
if type(k) == "function" then
773+
_accum_0[_len_0] = k(record) or self.db.NULL
774+
else
775+
_accum_0[_len_0] = record[k] or self.db.NULL
776+
end
777+
_len_0 = _len_0 + 1
778+
end
779+
tuple = _accum_0
780+
end
781+
if _all_same(tuple, self.db.NULL) then
782+
_continue_0 = true
783+
break
784+
end
785+
table.insert(include_ids, self.db.list(tuple))
786+
else
787+
local id
788+
if computed_source_key then
789+
id = source_key(record)
790+
else
791+
id = record[source_key]
792+
end
793+
if not (id) then
794+
_continue_0 = true
795+
break
796+
end
797+
if self.db.is_list(id) then
798+
local _list_0 = id[1]
799+
for _index_1 = 1, #_list_0 do
800+
local item = _list_0[_index_1]
801+
table.insert(include_ids, item)
802+
end
803+
else
804+
table.insert(include_ids, id)
805+
end
806+
end
807+
_continue_0 = true
808+
until true
809+
if not _continue_0 then
810+
break
810811
end
811-
include_ids = _accum_0
812812
end
813813
if next(include_ids) then
814814
if composite_foreign_key then
@@ -918,7 +918,67 @@ do
918918
else
919919
ref_value = other[source_key]
920920
end
921-
other[field_name] = records[ref_value]
921+
if self.db.is_list(ref_value) then
922+
local list_value_set
923+
do
924+
local _tbl_0 = { }
925+
local _list_0 = ref_value[1]
926+
for _index_1 = 1, #_list_0 do
927+
local k = _list_0[_index_1]
928+
if k ~= nil then
929+
_tbl_0[k] = true
930+
end
931+
end
932+
list_value_set = _tbl_0
933+
end
934+
if many then
935+
local matched_results
936+
do
937+
local _accum_0 = { }
938+
local _len_0 = 1
939+
for _index_1 = 1, #res do
940+
local _continue_0 = false
941+
repeat
942+
local row = res[_index_1]
943+
if not (list_value_set[row[dest_key]]) then
944+
_continue_0 = true
945+
break
946+
end
947+
local _value_0 = row
948+
_accum_0[_len_0] = _value_0
949+
_len_0 = _len_0 + 1
950+
_continue_0 = true
951+
until true
952+
if not _continue_0 then
953+
break
954+
end
955+
end
956+
matched_results = _accum_0
957+
end
958+
other[field_name] = matched_results
959+
else
960+
for _index_1 = 1, #res do
961+
local _continue_0 = false
962+
repeat
963+
do
964+
local row = res[_index_1]
965+
if not (list_value_set[row[dest_key]]) then
966+
_continue_0 = true
967+
break
968+
end
969+
other[field_name] = row
970+
break
971+
end
972+
_continue_0 = true
973+
until true
974+
if not _continue_0 then
975+
break
976+
end
977+
end
978+
end
979+
else
980+
other[field_name] = records[ref_value]
981+
end
922982
if many and not other[field_name] then
923983
other[field_name] = { }
924984
end

lapis/db/base_model.moon

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,10 @@ class BaseModel
338338
source_key = _memoize1 source_key
339339
true
340340

341-
include_ids = for record in *other_records
341+
include_ids = {} -- field value to match on model
342+
-- NOTE: when dealing with composite keys, db.list() tuples are put in this array
343+
344+
for record in *other_records
342345
if skip_included
343346
if for_relation
344347
continue if relation_is_loaded record, for_relation
@@ -353,14 +356,20 @@ class BaseModel
353356
record[k] or @db.NULL
354357

355358
continue if _all_same tuple, @db.NULL
356-
@db.list tuple
359+
table.insert include_ids, @db.list tuple
357360
else
358361
id = if computed_source_key
359362
source_key record
360363
else
361364
record[source_key]
362365
continue unless id
363-
id
366+
367+
-- if the value is a list, then we want to select everything that matches
368+
if @db.is_list id
369+
for item in *id[1]
370+
table.insert include_ids, item
371+
else
372+
table.insert include_ids, id
364373

365374
if next include_ids
366375
if composite_foreign_key
@@ -464,7 +473,24 @@ class BaseModel
464473
else
465474
other[source_key]
466475

467-
other[field_name] = records[ref_value]
476+
477+
if @db.is_list ref_value
478+
-- NOTE: we iterate through the the whole query result to keep the ordering across multiple values
479+
list_value_set = {k, true for k in *ref_value[1] when k != nil}
480+
if many
481+
matched_results = for row in *res
482+
continue unless list_value_set[row[dest_key]]
483+
row
484+
485+
other[field_name] = matched_results
486+
else
487+
-- take the first value found
488+
for row in *res
489+
continue unless list_value_set[row[dest_key]]
490+
other[field_name] = row
491+
break
492+
else
493+
other[field_name] = records[ref_value]
468494

469495
if many and not other[field_name]
470496
other[field_name] = {}

0 commit comments

Comments
 (0)