Browse Source

fix(nocodb): mysql xcdb api response logic

pull/5642/head
Wing-Kam Wong 1 year ago
parent
commit
89bcccac3a
  1. 67
      packages/nocodb/src/db/BaseModelSqlv2.ts

67
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -1,6 +1,8 @@
import autoBind from 'auto-bind';
import groupBy from 'lodash/groupBy';
import DataLoader from 'dataloader';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc.js';
import { nocoExecute } from 'nc-help';
import {
AuditOperationSubTypes,
@ -64,6 +66,8 @@ import type {
import type { Knex } from 'knex';
import type { SortType } from 'nocodb-sdk';
dayjs.extend(utc);
const GROUP_COL = '__nc_group_id';
const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14);
@ -1949,6 +1953,11 @@ class BaseModelSqlv2 {
};
}
private async isXcdbBase() {
const base = await Base.get(this.model.base_id);
return base.is_meta;
}
get isSqlite() {
return this.clientType === 'sqlite3';
}
@ -3147,16 +3156,24 @@ class BaseModelSqlv2 {
} else {
query = sanitize(query);
}
return this.convertAttachmentType(
let data =
this.isPg || this.isSnowflake
? (await this.dbDriver.raw(query))?.rows
: query.slice(0, 6) === 'select' && !this.isMssql
? await this.dbDriver.from(
this.dbDriver.raw(query).wrap('(', ') __nc_alias'),
)
: await this.dbDriver.raw(query),
childTable,
);
: await this.dbDriver.raw(query);
// update attachment fields
data = this.convertAttachmentType(data, childTable);
// update date time fields
if (this.isMySQL && !(await this.isXcdbBase())) {
data = this.convertDateFormat(data, childTable);
}
return data;
}
private _convertAttachmentType(
@ -3195,9 +3212,47 @@ class BaseModelSqlv2 {
return data;
}
private _convertDateFormat(
dateTimeColumns: Record<string, any>[],
d: Record<string, any>,
) {
try {
if (d) {
dateTimeColumns.forEach((col) => {
if (d[col.title] && typeof d[col.title] === 'string') {
// e.g. 2022-01-01 04:30:00+00:00
d[col.title] = dayjs(d[col.title])
.utc()
.format('YYYY-MM-DD HH:mm:ssZ');
}
});
}
} catch {}
return d;
}
private convertDateFormat(data: Record<string, any>, childTable?: Model) {
// MySQL converts TIMESTAMP values from the current time zone to UTC for storage.
// Then, MySQL converts those values back from UTC to the current time zone for retrieval.
// For xcdb base, to make it consistent with other DB types, we show the result in UTC instead
// e.g. 2022-01-01 04:30:00+00:00
if (data) {
const dateTimeColumns = (
childTable ? childTable.columns : this.model.columns
).filter((c) => c.uidt === UITypes.DateTime);
if (dateTimeColumns.length) {
if (Array.isArray(data)) {
data = data.map((d) => this._convertDateFormat(dateTimeColumns, d));
} else {
this._convertDateFormat(dateTimeColumns, data);
}
}
}
return data;
}
private async setUtcTimezoneForPg() {
const base = await Base.get(this.model.base_id);
if (this.isPg && base.is_meta) {
if (this.isPg && (await this.isXcdbBase())) {
await this.dbDriver.raw(`SET TIME ZONE 'UTC'`);
}
}

Loading…
Cancel
Save