• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rogerpadilla / nukak / #405

12 Aug 2024 09:07PM UTC coverage: 97.342% (-0.08%) from 97.422%
#405

push

rogerpadilla
v1.2.0

364 of 389 branches covered (93.57%)

Branch coverage included in aggregate %.

1504 of 1530 relevant lines covered (98.3%)

97.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.2
/packages/nukak-postgres/src/postgresDialect.ts
1
import {
1✔
2
  type QueryComparisonOptions,
3
  type QueryWhereMap,
4
  type QueryOptions,
5
  type QueryWhereFieldOperatorMap,
6
  type QueryTextSearchOptions,
7
  type Type,
8
  type FieldKey,
9
  type Scalar,
10
  type QueryConflictPaths,
11
  QueryRaw,
12
} from 'nukak/type';
13
import { AbstractSqlDialect } from 'nukak/dialect';
1✔
14
import { getMeta } from 'nukak/entity';
1✔
15
import { quoteLiteral } from 'node-pg-format';
1✔
16
import { getKeys, getPersistable, getRawValue } from 'nukak/util';
1✔
17

18
export class PostgresDialect extends AbstractSqlDialect {
1✔
19
  constructor() {
20
    super('"', 'BEGIN TRANSACTION');
1✔
21
  }
22

23
  override insert<E>(entity: Type<E>, payload: E | E[]): string {
24
    const sql = super.insert(entity, payload);
3✔
25
    const returning = this.returningId(entity);
3✔
26
    return `${sql} ${returning}`;
3✔
27
  }
28

29
  override upsert<E>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): string {
30
    const meta = getMeta(entity);
1✔
31
    const insert = super.insert(entity, payload);
1✔
32
    const record = getPersistable(meta, payload, 'onInsert');
1✔
33
    const columns = getKeys(record);
1✔
34
    const update = columns
1✔
35
      .filter((col) => !conflictPaths[col])
3✔
36
      .map((col) => `${this.escapeId(col)} = EXCLUDED.${this.escapeId(col)}`)
2✔
37
      .join(', ');
38
    const keysStr = getKeys(conflictPaths)
1✔
39
      .map((key) => this.escapeId(key))
1✔
40
      .join(', ');
41
    const returning = this.returningId(entity);
1✔
42
    return `${insert} ON CONFLICT (${keysStr}) DO UPDATE SET ${update} ${returning}`;
1✔
43
  }
44

45
  override compare<E, K extends keyof QueryWhereMap<E>>(
46
    entity: Type<E>,
47
    key: K,
48
    val: QueryWhereMap<E>[K],
49
    opts: QueryComparisonOptions = {},
×
50
  ): string {
51
    if (key === '$text') {
14✔
52
      const meta = getMeta(entity);
2✔
53
      const search = val as QueryTextSearchOptions<E>;
2✔
54
      const fields = search.$fields
2✔
55
        .map((field) => this.escapeId(meta.fields[field]?.name ?? field))
3!
56
        .join(` || ' ' || `);
57
      return `to_tsvector(${fields}) @@ to_tsquery(${this.escape(search.$value)})`;
2✔
58
    }
59
    return super.compare(entity, key, val, opts);
12✔
60
  }
61

62
  override compareFieldOperator<E, K extends keyof QueryWhereFieldOperatorMap<E>>(
63
    entity: Type<E>,
64
    key: FieldKey<E>,
65
    op: K,
66
    val: QueryWhereFieldOperatorMap<E>[K],
67
    opts: QueryOptions = {},
×
68
  ): string {
69
    const comparisonKey = this.getComparisonKey(entity, key, opts);
16✔
70
    switch (op) {
16✔
71
      case '$istartsWith':
72
        return `${comparisonKey} ILIKE ${this.escape(`${val}%`)}`;
2✔
73
      case '$iendsWith':
74
        return `${comparisonKey} ILIKE ${this.escape(`%${val}`)}`;
2✔
75
      case '$iincludes':
76
        return `${comparisonKey} ILIKE ${this.escape(`%${val}%`)}`;
2✔
77
      case '$ilike':
78
        return `${comparisonKey} ILIKE ${this.escape(val)}`;
2✔
79
      case '$regex':
80
        return `${comparisonKey} ~ ${this.escape(val)}`;
1✔
81
      default:
82
        return super.compareFieldOperator(entity, key, op, val, opts);
7✔
83
    }
84
  }
85

86
  override escape(value: any): Scalar {
87
    if (value instanceof QueryRaw) {
36!
88
      return getRawValue({ value, dialect: this });
×
89
    }
90
    return quoteLiteral(value);
36✔
91
  }
92
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc