nocobase/packages/core/database/src/query-interface/sqlite-query-interface.ts
ChengLei Shao 2063227f4a
refactor: export & import plugin (#4468)
* feat: chunk method in repository

* chore: xlsx export test

* chore: xlsx export

* chore: export action

* chore: export action

* chore: code

* feat: database interface manager

* feat: export with ui schema

* chore: console.log

* chore: export with china region field

* chore: export with attachments

* chore: export with multiple select

* chore: export with interface

* chore: export action

* fix: export with datetime file

* chore: limit export action running in same time

* chore: yarn.lock

* fix: render json value

* chore: chunk with limit

* feat: add EXPORT_LIMIT env config

* fix: typo

* fix: type

* chore: asyn mutex version

* chore: test

* chore: test

* fix: export null value

* chore: test

* chore: createdAt test

* fix: export with createdAt

* chore: import template

* chore: xlsx importer

* chore: import run

* chore: export with data source api

* chore: toValue api in interface

* fix: build

* chore: import with transaction

* fix: build database

* chore: many to one interface

* chore: code

* chore: import with associations

* chore: default toValue

* chore: import template with explain

* chore: import with explain template

* chore: reset id seq after import

* chore: download template action

* fix: database build

* fix: build

* fix: build

* fix: test

* chore: import with number field

* chore: import with boolean field

* chore: json interface

* chore: import action

* chore: typo

* chore: i18n

* chore: select interface

* chore: china region interface

* chore: datetiem field

* chore: cast to array

* fix: import tips

* chore: import await

* fix: test

* fix: test in mariadb

* chore: comments

* chore: comments

* fix: parse date with empty string

* fix: read import limit

* fix: type

* fix: test in mariadb

* chore: skip bigint test in sqlite

* chore: skip bigint test in sqlite

* chore: download tip i18n keys

* fix: download tips

* feat(client): add new variable named 'URL search params' and support link action (#4506)

* feat: support link action

* feat(client): add new variable named 'URL search params'

* chore: add translation

* fix: avoid crashing

* chore: fix failed test

* feat: link action

* feat: link action

* fix: remove filter parameters with undefined values

* feat: link action

* feat: add support for default values in filter form fields

* refactor: code improve

* refactor: locale improve

* refactor: locale improve

* test: add e2e test

* refactor: locale improve

* refactor: locale improve

* fix: resolve operation issues with variables

* refactor: code improve

* chore: enable direct selection of variables as default value

* chore: use qs to parse query string

* fix: menu selectKeys (T-4373)

* refactor: use qs to stringify search params

* refactor: locale improve

* refactor: locale improve

* chore: fix failed tests

* fix: resolve issue where setting Data scope is not work

* chore: fix failed e2e tests

* chore: make e2e tests more stable

* chore: add translation

* chore: make e2e tests more stable

* fix: resolve the issue of error when saving data scope

* feat: trigger variable parsing after context change

* test: add unit tests

* test: add e2e test

* refactor: extract template

* chore: fix failed unit tests

* chore: fix failed e2e test

* fix(Link): hide linkage rules in top link (T-4410)

* fix(permission): remove URL search params variable from data scope

* chore: make more stable

* chore: make e2e test more stable

* fix(Link): reduce size for variable

* fix: clear previous context (T-4449)

* fix(calendar, map): resolve initial data scope setting error (T-4450)

* fix: correct concatenation of query string (T-4453)

---------

Co-authored-by: katherinehhh <katherine_15995@163.com>
Co-authored-by: jack zhang <1098626505@qq.com>

* refactor(FormV2): add FormWithDataTemplates component (#4551)

* Revert "fix(client): fix data template style (#4536)"

This reverts commit db66090ab279508473e74803dbb8637341fa6f3f.

* refactor(FormV2): add FormWithDataTemplates component

* chore: fix failed e2e tests

* chore: make e2e test more stable

* chore: import warning i18n

* chore: import warning i18n

* fix: bug

* fix: export action loading

* fix: bug

* chore: map field interface

* fix: merge bug

---------

Co-authored-by: xilesun <2013xile@gmail.com>
Co-authored-by: Zeke Zhang <958414905@qq.com>
Co-authored-by: katherinehhh <katherine_15995@163.com>
Co-authored-by: jack zhang <1098626505@qq.com>
2024-06-05 17:52:43 +08:00

150 lines
3.8 KiB
TypeScript

/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
/* istanbul ignore file -- @preserve */
import { Collection } from '../collection';
import sqlParser from '../sql-parser';
import QueryInterface, { TableInfo } from './query-interface';
import { Transaction } from 'sequelize';
export default class SqliteQueryInterface extends QueryInterface {
constructor(db) {
super(db);
}
async collectionTableExists(collection: Collection, options?) {
const transaction = options?.transaction;
const tableName = collection.model.tableName;
const sql = `SELECT name
FROM sqlite_master
WHERE type = 'table'
AND name = '${tableName}';`;
const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
return results.length > 0;
}
async listViews() {
const sql = `
SELECT name, sql as definition
FROM sqlite_master
WHERE type = 'view'
ORDER BY name;
`;
return await this.db.sequelize.query(sql, {
type: 'SELECT',
});
}
async viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
[view_column_name: string]: {
column_name: string;
table_name: string;
table_schema?: string;
};
}> {
try {
const { ast } = this.parseSQL(await this.viewDef(options.viewName));
const columns = ast.columns;
const results = [];
for (const column of columns) {
if (column.expr.type === 'column_ref') {
results.push([
column.as || column.expr.column,
{
column_name: column.expr.column,
table_name: column.expr.table,
},
]);
}
}
return Object.fromEntries(results);
} catch (e) {
this.db.logger.warn(e);
return {};
}
}
parseSQL(sql: string): any {
return sqlParser.parse(sql);
}
async viewDef(viewName: string): Promise<string> {
const viewDefinition = await this.db.sequelize.query(
`SELECT sql
FROM sqlite_master
WHERE name = '${viewName}' AND type = 'view'`,
{
type: 'SELECT',
},
);
const createView = viewDefinition[0]['sql'];
const regex = /(?<=AS\s)([\s\S]*)/i;
const match = createView.match(regex);
const sql = match[0];
return sql;
}
showTableDefinition(tableInfo: TableInfo): Promise<any> {
return Promise.resolve(undefined);
}
async getAutoIncrementInfo(options: { tableInfo: TableInfo; fieldName: string; transaction: Transaction }): Promise<{
seqName?: string;
currentVal: number;
}> {
const { tableInfo, transaction } = options;
const tableName = tableInfo.tableName;
const sql = `SELECT seq
FROM sqlite_sequence
WHERE name = '${tableName}';`;
const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
const row = results[0];
if (!row) {
return {
currentVal: 0,
};
}
return {
currentVal: row['seq'],
};
}
async setAutoIncrementVal(options: {
tableInfo: TableInfo;
columnName: string;
seqName?: string;
currentVal: number;
transaction?: Transaction;
}): Promise<void> {
const { tableInfo, columnName, seqName, currentVal, transaction } = options;
const tableName = tableInfo.tableName;
const sql = `UPDATE sqlite_sequence
SET seq = ${currentVal}
WHERE name = '${tableName}';`;
await this.db.sequelize.query(sql, { transaction });
}
}