Q查询泛型中的条目会导致类型不匹配的编译错误



我用nim编程语言编写了一个web应用程序,并使用norm作为我的ORM。

在那里,我遵循标准的存储库模式,这意味着您已经与给定的URL关联了一个控制器,该控制器调用包含关于数据库上应该发生的事情的业务逻辑的服务,该服务调用存储库来执行实际查询。

我有一个通用存储库,它为我执行各种非常重复的查询;"运动";有一个特定的名称:

import norm/[model, sqlite]
import <path to the file with the definitions of the used Model and newModel>

proc getCampaignList*[M: Model](connection: DbConn, campaignName: string, modelType: typedesc[M]): seq[M] =
##[ Retrieves all rows/entries for a campaign with the given name and 
returns them as Model M. 

``campaignName`` must be exactly equal to the name of the targetted campaign,
the comparison is case-sensitive.]##
mixin newModel
var entries: seq[M] = @[]
entries.add(newModel(M))

connection.select(entries, "campaign_id.name = ?", campaignName)
result = entries

如果我直接调用proc,这会很好。然而,我也一直在编写通用的proc,为我构建控制器proc,因为我的应用程序非常CRUD繁重,因此非常重复。所以我有一个generalService和更多。

当在这几层泛型中使用时,proc会神秘地中断:

type mismatch: got <DbConn, seq[DiaryEntryRead], string, DbValue>
but expected one of:
...
<Unnecessary examples>
...
proc select[T: Model](dbConn; objs: var seq[T]; cond: string;
params: varargs[DbValue, dbValue])
first type mismatch at position: 4
required type for params: varargs[DbValue]
but expression 'dbValue(campaignName)' is of type: DbValue
expression: select(connection, entries, "campaign_id.name = ?", dbValue(campaignName))

我不知道为什么在以前工作得很好的情况下突然发生这种情况。我的问题可能是什么?

问题似乎出现在nim泛型和将类型正确转换为varargs之间的交互中(感谢来自nim的discord服务器的"Solitude"one_answers"Rika"的帮助!(。我还没有深入研究为什么会发生这种情况,但至少它是可以修复的。

作为位置4及以后的参数,可以将参数转换为DbValue并填充到数组或seq中。下面是我解决这个问题的方法;万无一失的";proc(我使用了一个数组,因为当参数的数量是静态的,并且你提前知道它时,为什么要使用seq(:

proc getCampaignList*[M: Model](connection: MyDbConn, campaignName: string, modelType: typedesc[M]): seq[M] =
##[ Retrieves all rows/entries of a campaign with the given name and 
returns them as Model M. 

``campaignName`` must be exactly equal to the name of the targetted campaign,
the comparison is case-sensitive.]##
mixin newModel
var entries: seq[M] = @[]
entries.add(newModel(M))

let queryParams: array[1, DbValue] = [campaignName.dbValue()]
connection.select(entries, "campaign_id.name = ?", queryParams)
result = entries