根据字符串 class 名称创建一条记录

Create a record based on the string class name

我正在尝试创建一个事件存储,其中我有一个 table 有点像这样:

CREATE TABLE domain_events (
  id serial PRIMARY KEY,
  timestamp timestamptz,
  entity_id int,
  type text,
  data jsonb
);

我有一个像

这样的命名空间
(ns my-domain.domain-events)

(defrecord PurchaseOrderCreated
  [id timestamp purchase-order-id created-by])

(defrecord PurchaseOrderCancelled
  [id timestamp purchase-order-id cancelled-by])

所以 type 是完全限定的 class 名称的字符串名称,类似于 my_domain.domain_events.PurchaseOrderCreated,它来自从记录中获取 type,例如(type (->PurchaseOrderCreated))。我应该注意到 (type the-event) 实际上会生成一个前缀为 class 的字符串,例如 class my_domain.domain_events.PurchaseOrderCreaated 所以我在存储到数据库之前将其删除。

我正在尝试弄清楚如何从数据库中检索这些事件行并将它们重新组合为领域事件。我觉得我已经接近了,但还没有得到所有的碎片。

我曾尝试使用 new 来构建新记录,但我似乎很难将字符串 classname 转换为记录。

(new (resolve (symbol "my_domain.domain_events.PurchaseOrderCreated")) prop1 prop2 ...)

另外,我不确定使用 new 会有多容易,因为我的 array-of-properties 需要按正确的顺序排列。使用 map->PurchaseOrderCreated 可能更好,但我仍然不确定如何根据字符串 classname.

动态解析此构造函数

谁能告诉我最好的方法是什么?

以下应该可行,但我不会展示是否有更惯用的方法:

((resolve (symbol "my_domain.domain_events"
                  (str "map->"
                       "PurchaseOrderCreated")))
 {:id 123})

symbol 可以拿一个ns: https://clojuredocs.org/clojure.core/symbol