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

rogerpadilla / uql / 20684188712

03 Jan 2026 11:05PM UTC coverage: 95.31% (-2.8%) from 98.157%
20684188712

push

github

rogerpadilla
refactor: Migrate testing infrastructure to Vitest, add new querier pools, and expand test coverage.

1250 of 1388 branches covered (90.06%)

Branch coverage included in aggregate %.

108 of 117 new or added lines in 14 files covered. (92.31%)

51 existing lines in 14 files now uncovered.

3383 of 3473 relevant lines covered (97.41%)

223.87 hits per line

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

86.32
/packages/core/src/postgres/postgresDialect.ts
1
import sqlstring from 'sqlstring-sqlite';
2
import { AbstractSqlDialect } from '../dialect/index.js';
3
import { getMeta } from '../entity/index.js';
4
import {
5
  type FieldKey,
6
  type FieldOptions,
7
  type NamingStrategy,
8
  type QueryComparisonOptions,
9
  type QueryConflictPaths,
10
  type QueryContext,
11
  type QueryOptions,
12
  QueryRaw,
13
  type QueryTextSearchOptions,
14
  type QueryWhereFieldOperatorMap,
15
  type QueryWhereMap,
16
  type Type,
17
} from '../type/index.js';
18

19
export class PostgresDialect extends AbstractSqlDialect {
20
  constructor(namingStrategy?: NamingStrategy) {
21
    super(namingStrategy, '"', 'BEGIN TRANSACTION');
42✔
22
  }
23

24
  override addValue(values: unknown[], value: unknown): string {
25
    values.push(value);
422✔
26
    return this.placeholder(values.length);
422✔
27
  }
28

29
  override placeholder(index: number): string {
30
    return `$${index}`;
422✔
31
  }
32

33
  override insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void {
34
    super.insert(ctx, entity, payload, opts);
59✔
35
    ctx.append(' ' + this.returningId(entity));
59✔
36
  }
37

38
  override upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): void {
39
    const meta = getMeta(entity);
10✔
40
    const update = this.getUpsertUpdateAssignments(ctx, meta, conflictPaths, payload, (name) => `EXCLUDED.${name}`);
15✔
41
    const keysStr = this.getUpsertConflictPathsStr(meta, conflictPaths);
10✔
42
    const onConflict = update ? `DO UPDATE SET ${update}` : 'DO NOTHING';
10✔
43
    super.insert(ctx, entity, payload);
10✔
44
    ctx.append(` ON CONFLICT (${keysStr}) ${onConflict} ${this.returningId(entity)}`);
10✔
45
  }
46

47
  override compare<E, K extends keyof QueryWhereMap<E>>(
48
    ctx: QueryContext,
49
    entity: Type<E>,
50
    key: K,
51
    val: QueryWhereMap<E>[K],
52
    opts: QueryComparisonOptions = {},
190✔
53
  ): void {
54
    if (key === '$text') {
190✔
55
      const meta = getMeta(entity);
2✔
56
      const search = val as QueryTextSearchOptions<E>;
2✔
57
      const fields = search.$fields
2✔
58
        .map((fKey) => {
59
          const field = meta.fields[fKey];
3✔
60
          const columnName = this.resolveColumnName(fKey as string, field);
3✔
61
          return this.escapeId(columnName);
3✔
62
        })
63
        .join(` || ' ' || `);
64
      ctx.append(`to_tsvector(${fields}) @@ to_tsquery(`);
2✔
65
      ctx.addValue(search.$value);
2✔
66
      ctx.append(')');
2✔
67
      return;
2✔
68
    }
69
    super.compare(ctx, entity, key, val, opts);
188✔
70
  }
71

72
  override compareFieldOperator<E, K extends keyof QueryWhereFieldOperatorMap<E>>(
73
    ctx: QueryContext,
74
    entity: Type<E>,
75
    key: FieldKey<E>,
76
    op: K,
77
    val: QueryWhereFieldOperatorMap<E>[K],
78
    opts: QueryOptions = {},
185✔
79
  ): void {
80
    switch (op) {
185!
81
      case '$istartsWith':
82
        this.getComparisonKey(ctx, entity, key, opts);
2✔
83
        ctx.append(' ILIKE ');
2✔
84
        ctx.addValue(`${val}%`);
2✔
85
        break;
2✔
86
      case '$iendsWith':
87
        this.getComparisonKey(ctx, entity, key, opts);
2✔
88
        ctx.append(' ILIKE ');
2✔
89
        ctx.addValue(`%${val}`);
2✔
90
        break;
2✔
91
      case '$iincludes':
92
        this.getComparisonKey(ctx, entity, key, opts);
2✔
93
        ctx.append(' ILIKE ');
2✔
94
        ctx.addValue(`%${val}%`);
2✔
95
        break;
2✔
96
      case '$ilike':
97
        this.getComparisonKey(ctx, entity, key, opts);
2✔
98
        ctx.append(' ILIKE ');
2✔
99
        ctx.addValue(val);
2✔
100
        break;
2✔
101
      case '$in':
102
        this.getComparisonKey(ctx, entity, key, opts);
57✔
103
        ctx.append(' = ANY(');
57✔
104
        ctx.addValue(val);
57✔
105
        ctx.append(')');
57✔
106
        break;
57✔
107
      case '$nin':
108
        this.getComparisonKey(ctx, entity, key, opts);
×
109
        ctx.append(' <> ALL(');
×
110
        ctx.addValue(val);
×
111
        ctx.append(')');
×
UNCOV
112
        break;
×
113
      case '$regex':
114
        this.getComparisonKey(ctx, entity, key, opts);
1✔
115
        ctx.append(' ~ ');
1✔
116
        ctx.addValue(val);
1✔
117
        break;
1✔
118
      default:
119
        super.compareFieldOperator(ctx, entity, key, op, val, opts);
119✔
120
    }
121
  }
122

123
  protected override formatPersistableValue<E>(ctx: QueryContext, field: FieldOptions, value: unknown): void {
124
    if (value instanceof QueryRaw) {
305✔
125
      super.formatPersistableValue(ctx, field, value);
1✔
126
      return;
1✔
127
    }
128
    if (field.type === 'json' || field.type === 'jsonb') {
304✔
129
      ctx.addValue(value ? JSON.stringify(value) : null);
1!
130
      ctx.append(`::${field.type}`);
1✔
131
      return;
1✔
132
    }
133
    if (field.type === 'vector' && Array.isArray(value)) {
303!
134
      ctx.addValue(`[${value.join(',')}]`);
×
135
      ctx.append('::vector');
×
136
      return;
×
137
    }
138
    super.formatPersistableValue(ctx, field, value);
303✔
139
  }
140

141
  override escape(value: unknown): string {
UNCOV
142
    return sqlstring.escape(value);
×
143
  }
144
}
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