带变压器的 TypeORM FindOperators

Ric*_*eak 1 postgresql typescript typeorm

我想使用我自己的自定义转换器方法来从数据库中编组/解组数据结构。

所以我的实体看起来像这样:

class EntityName {

  @Column({ type: `text`, transformer: { from: fromPostgres, to: toPostgres } })
  colName: CustomClass;

}
Run Code Online (Sandbox Code Playgroud)

然后我显然有一个自定义类,沿着这些思路:

class CustomClass {
  propertyA: string;
  propertyB: number;
}
Run Code Online (Sandbox Code Playgroud)

我的映射函数:

fromPostgres(value: any) : any {
  let c = new CustomClass();
  c.propertyA = value.split(" ")[0];
  c.propertyB = parseInt(value.split(" ")[1]);
  return c;
}

toPostres(value: any) : any {
  return `${value.propertyA} ${value.propertyB}`
}
Run Code Online (Sandbox Code Playgroud)

等等。显然这不是用例,但你明白了。

所以这一切都很好,没问题。除非您使用 FindOperators 进行查询。你知道,像这样:

let c = new CustomClass();
c.propertyA = "a";
c.propertyB = 12;
getRepository(EntityName).find({where: { colName: LessThan(c) } });
Run Code Online (Sandbox Code Playgroud)

当我检查 toPostgres 方法时,我传入的是 FindOperator 对象。这将底层 CustomClass 实例存储在 _value 属性中(可通过 get value() getter 访问)。这一切都很好,但我不确定如何将其解析为 SQL,因为无论我为 toPostgres 方法编写什么,例如提取 .value 并调用 toPostgres,生成的 SQL 查询都不会执行小于查询,它会查找正常的等于。

你知道,你会得到这样的东西:

WHERE "EntityName"."colName" = $1 -- PARAMETERS: ["a 12"]
Run Code Online (Sandbox Code Playgroud)

而不是我想要的,即:

WHERE "EntityName"."colName" < $1 -- PARAMETERS: ["a 12"]
Run Code Online (Sandbox Code Playgroud)

那么,我是否必须为我的自定义类实现整个 FindOperators 范围?(我真的希望不会!)。如果我这样做,我如何强制可能是更高级别的函数将 SQL 查询修改为小于而不是等于。

或者,我是否只是以某种方式修改 FindOperator,通过递归地将 toPostgres 应用于该值,然后让查询构建器完成其余的工作。这是我的偏好,但据我所知 _value 是私有财产,所以我不确定如何继续这种思路。

我真的希望 TypeORM 足够聪明,能够继续执行它已经使用 FindOperator 所做的任何事情,并将转换器函数应用于我的基础值,但情况似乎并非如此,除非我有其他一些配置错过了吗?

Ric*_*eak 6

好的,经过几个小时阅读代码以及如何在 TypeORM 中组装查询后,我提出了以下解决方案。

toPostgres(value : any) : any {
    let returnValue = null;
    if(! value) {
      return null;
    } else if(value instanceof CustomClass) {
      returnValue = `${value.propertyA} ${value.propertyB}`;
    } else {
      let findValue = value as FindOperator<CustomClass>;
      returnValue = new FindOperator<CustomClass>( findValue[`_type`] as FindOperatorType, toPostgres(findValue.value), findValue.useParameter, findValue.multipleParameters)
    }
    return returnValue;
  }
Run Code Online (Sandbox Code Playgroud)

换句话说,我必须递归地将转换器函数应用于所有 FindOperator 的 _value 属性。