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

teableio / teable / 10160390019

30 Jul 2024 10:08AM CUT coverage: 81.98% (+64.3%) from 17.697%
10160390019

Pull #779

github

web-flow
Merge a160876c8 into 521460d76
Pull Request #779: fix: skip duplicate index

4272 of 4471 branches covered (95.55%)

28270 of 34484 relevant lines covered (81.98%)

1219.86 hits per line

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

5.56
/apps/nestjs-backend/src/db-provider/group-query/group-query.postgres.ts
1
import { TimeFormatting } from '@teable/core';
4✔
2
import type { INumberFieldOptions, IDateFieldOptions } from '@teable/core';
4✔
3
import type { Knex } from 'knex';
4✔
4
import type { IFieldInstance } from '../../features/field/model/factory';
4✔
5
import { AbstractGroupQuery } from './group-query.abstract';
4✔
6
import type { IGroupQueryExtra } from './group-query.interface';
4✔
7

4✔
8
export class GroupQueryPostgres extends AbstractGroupQuery {
4!
9
  constructor(
×
10
    protected readonly knex: Knex,
×
11
    protected readonly originQueryBuilder: Knex.QueryBuilder,
×
12
    protected readonly fieldMap?: { [fieldId: string]: IFieldInstance },
×
13
    protected readonly groupFieldIds?: string[],
×
14
    protected readonly extra?: IGroupQueryExtra
×
15
  ) {
×
16
    super(knex, originQueryBuilder, fieldMap, groupFieldIds, extra);
×
17
  }
×
18

×
19
  private get isDistinct() {
×
20
    const { isDistinct } = this.extra ?? {};
×
21
    return isDistinct;
×
22
  }
×
23

×
24
  string(field: IFieldInstance): Knex.QueryBuilder {
×
25
    const { dbFieldName } = field;
×
26
    const column = this.knex.ref(dbFieldName);
×
27

×
28
    if (this.isDistinct) {
×
29
      return this.originQueryBuilder.countDistinct(dbFieldName);
×
30
    }
×
31
    return this.originQueryBuilder.select(column).groupBy(dbFieldName);
×
32
  }
×
33

×
34
  number(field: IFieldInstance): Knex.QueryBuilder {
×
35
    const { dbFieldName, options } = field;
×
36
    const { precision } = (options as INumberFieldOptions).formatting;
×
37
    const column = this.knex.raw('ROUND(??::numeric, ?)::float as ??', [
×
38
      dbFieldName,
×
39
      precision,
×
40
      dbFieldName,
×
41
    ]);
×
42
    const groupByColumn = this.knex.raw('ROUND(??::numeric, ?)::float', [dbFieldName, precision]);
×
43

×
44
    if (this.isDistinct) {
×
45
      return this.originQueryBuilder.countDistinct(groupByColumn);
×
46
    }
×
47
    return this.originQueryBuilder.select(column).groupBy(groupByColumn);
×
48
  }
×
49

×
50
  date(field: IFieldInstance): Knex.QueryBuilder {
×
51
    const { dbFieldName, options } = field;
×
52
    const { date, time, timeZone } = (options as IDateFieldOptions).formatting;
×
53

×
54
    if (time !== TimeFormatting.None) {
×
55
      const column = this.knex.ref(dbFieldName);
×
56
      return this.isDistinct
×
57
        ? this.originQueryBuilder.countDistinct(dbFieldName)
×
58
        : this.originQueryBuilder.select(column).groupBy(dbFieldName);
×
59
    }
×
60

×
61
    const format = date;
×
62
    const column = this.knex.raw(`TO_CHAR(TIMEZONE(?, ??), '${format}') as ??`, [
×
63
      timeZone,
×
64
      dbFieldName,
×
65
      dbFieldName,
×
66
    ]);
×
67
    const groupByColumn = this.knex.raw(`TO_CHAR(TIMEZONE(?, ??), '${format}')`, [
×
68
      timeZone,
×
69
      dbFieldName,
×
70
    ]);
×
71

×
72
    if (this.isDistinct) {
×
73
      return this.originQueryBuilder.countDistinct(groupByColumn);
×
74
    }
×
75
    return this.originQueryBuilder.select(column).groupBy(groupByColumn);
×
76
  }
×
77

×
78
  json(field: IFieldInstance): Knex.QueryBuilder {
×
79
    const { dbFieldName } = field;
×
80
    const column = this.knex.raw(`CAST(?? as text)`, [dbFieldName]);
×
81

×
82
    if (this.isDistinct) {
×
83
      return this.originQueryBuilder.countDistinct(dbFieldName);
×
84
    }
×
85
    return this.originQueryBuilder.select(column).groupBy(dbFieldName);
×
86
  }
×
87

×
88
  multipleDate(field: IFieldInstance): Knex.QueryBuilder {
×
89
    const { dbFieldName, options } = field;
×
90
    const { date, time, timeZone } = (options as IDateFieldOptions).formatting;
×
91

×
92
    if (time !== TimeFormatting.None) {
×
93
      const column = this.knex.ref(dbFieldName);
×
94
      return this.isDistinct
×
95
        ? this.originQueryBuilder.countDistinct(dbFieldName)
×
96
        : this.originQueryBuilder.select(column).groupBy(dbFieldName);
×
97
    }
×
98

×
99
    const format = date;
×
100
    const column = this.knex.raw(
×
101
      `
×
102
      (SELECT to_jsonb(array_agg(TO_CHAR(TIMEZONE(?, CAST(elem AS timestamp with time zone)), '${format}')))
×
103
      FROM jsonb_array_elements_text(??::jsonb) as elem) as ??
×
104
      `,
×
105
      [timeZone, dbFieldName, dbFieldName]
×
106
    );
×
107
    const groupByColumn = this.knex.raw(
×
108
      `
×
109
      (SELECT to_jsonb(array_agg(TO_CHAR(TIMEZONE(?, CAST(elem AS timestamp with time zone)), '${format}')))
×
110
      FROM jsonb_array_elements_text(??::jsonb) as elem)
×
111
      `,
×
112
      [timeZone, dbFieldName]
×
113
    );
×
114

×
115
    if (this.isDistinct) {
×
116
      return this.originQueryBuilder.countDistinct(groupByColumn);
×
117
    }
×
118
    return this.originQueryBuilder.select(column).groupBy(groupByColumn);
×
119
  }
×
120

×
121
  multipleNumber(field: IFieldInstance): Knex.QueryBuilder {
×
122
    const { dbFieldName, options } = field;
×
123
    const { precision } = (options as INumberFieldOptions).formatting;
×
124
    const column = this.knex.raw(
×
125
      `
×
126
      (SELECT to_jsonb(array_agg(ROUND(elem::numeric, ?)))
×
127
      FROM jsonb_array_elements_text(??::jsonb) as elem) as ??
×
128
      `,
×
129
      [precision, dbFieldName, dbFieldName]
×
130
    );
×
131
    const groupByColumn = this.knex.raw(
×
132
      `
×
133
      (SELECT to_jsonb(array_agg(ROUND(elem::numeric, ?)))
×
134
      FROM jsonb_array_elements_text(??::jsonb) as elem)
×
135
      `,
×
136
      [precision, dbFieldName]
×
137
    );
×
138

×
139
    if (this.isDistinct) {
×
140
      return this.originQueryBuilder.countDistinct(groupByColumn);
×
141
    }
×
142
    return this.originQueryBuilder.select(column).groupBy(groupByColumn);
×
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

© 2025 Coveralls, Inc