mirror of
https://github.com/dbgate/dbgate
synced 2024-11-23 00:43:10 +00:00
This commit is contained in:
parent
ac9bd62ecf
commit
cecb88f024
@ -9,6 +9,7 @@
|
|||||||
"start:api:portal": "yarn workspace @dbgate/api start:portal",
|
"start:api:portal": "yarn workspace @dbgate/api start:portal",
|
||||||
"start:web": "yarn workspace @dbgate/web start",
|
"start:web": "yarn workspace @dbgate/web start",
|
||||||
"start:sqltree": "yarn workspace @dbgate/sqltree start",
|
"start:sqltree": "yarn workspace @dbgate/sqltree start",
|
||||||
|
"start:tools": "yarn workspace @dbgate/tools start",
|
||||||
"start:datalib": "yarn workspace @dbgate/datalib start",
|
"start:datalib": "yarn workspace @dbgate/datalib start",
|
||||||
"start:filterparser": "yarn workspace @dbgate/filterparser start",
|
"start:filterparser": "yarn workspace @dbgate/filterparser start",
|
||||||
"build:sqltree": "yarn workspace @dbgate/sqltree build",
|
"build:sqltree": "yarn workspace @dbgate/sqltree build",
|
||||||
@ -26,7 +27,7 @@
|
|||||||
|
|
||||||
"prepare": "yarn build:lib",
|
"prepare": "yarn build:lib",
|
||||||
"start": "concurrently --kill-others-on-fail \"yarn start:api\" \"yarn start:web\"",
|
"start": "concurrently --kill-others-on-fail \"yarn start:api\" \"yarn start:web\"",
|
||||||
"lib": "concurrently --kill-others-on-fail \"yarn start:sqltree\" \"yarn start:filterparser\" \"yarn start:datalib\"",
|
"lib": "concurrently --kill-others-on-fail \"yarn start:sqltree\" \"yarn start:filterparser\" \"yarn start:datalib\" \"yarn start:tools\"",
|
||||||
"ts:api": "yarn workspace @dbgate/api ts",
|
"ts:api": "yarn workspace @dbgate/api ts",
|
||||||
"ts:web": "yarn workspace @dbgate/web ts",
|
"ts:web": "yarn workspace @dbgate/web ts",
|
||||||
"ts": "yarn ts:api && yarn ts:web",
|
"ts": "yarn ts:api && yarn ts:web",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { GridConfig, GridCache, GridConfigColumns, createGridCache } from './GridConfig';
|
import { GridConfig, GridCache, GridConfigColumns, createGridCache } from './GridConfig';
|
||||||
import { ForeignKeyInfo, TableInfo, ColumnInfo, DbType, EngineDriver, NamedObjectInfo, DatabaseInfo } from '@dbgate/types';
|
import { ForeignKeyInfo, TableInfo, ColumnInfo, EngineDriver, NamedObjectInfo, DatabaseInfo } from '@dbgate/types';
|
||||||
import { parseFilter, getFilterType } from '@dbgate/filterparser';
|
import { parseFilter, getFilterType } from '@dbgate/filterparser';
|
||||||
import { filterName } from './filterName';
|
import { filterName } from './filterName';
|
||||||
import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
|
import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
|
||||||
@ -19,7 +19,7 @@ export interface DisplayColumn {
|
|||||||
foreignKey?: ForeignKeyInfo;
|
foreignKey?: ForeignKeyInfo;
|
||||||
isChecked?: boolean;
|
isChecked?: boolean;
|
||||||
hintColumnName?: string;
|
hintColumnName?: string;
|
||||||
commonType?: DbType;
|
dataType?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DisplayedColumnEx extends DisplayColumn {
|
export interface DisplayedColumnEx extends DisplayColumn {
|
||||||
@ -143,7 +143,7 @@ export abstract class GridDisplay {
|
|||||||
const column = displayedColumnInfo[uniqueName];
|
const column = displayedColumnInfo[uniqueName];
|
||||||
if (!column) continue;
|
if (!column) continue;
|
||||||
try {
|
try {
|
||||||
const condition = parseFilter(filter, getFilterType(column.commonType?.typeCode));
|
const condition = parseFilter(filter, getFilterType(column.dataType));
|
||||||
if (condition) {
|
if (condition) {
|
||||||
conditions.push(
|
conditions.push(
|
||||||
_.cloneDeepWith(condition, (expr: Expression) => {
|
_.cloneDeepWith(condition, (expr: Expression) => {
|
||||||
|
@ -24,136 +24,12 @@ function objectTypeToField(type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {import('@dbgate/types').DbType} */
|
function getColumnInfo({ isNullable, isIdentity, columnName, dataType }) {
|
||||||
function detectType(col) {
|
|
||||||
switch (col.dataType) {
|
|
||||||
case 'binary':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
isBinary: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'image':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
isBinary: true,
|
|
||||||
isBlob: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'timestamp':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
};
|
|
||||||
case 'varbinary':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
length: col.maxLength,
|
|
||||||
isBinary: true,
|
|
||||||
isVarLength: true,
|
|
||||||
};
|
|
||||||
case 'bit':
|
|
||||||
return {
|
|
||||||
typeCode: 'logical',
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'tinyint':
|
|
||||||
return {
|
|
||||||
typeCode: 'int',
|
|
||||||
bytes: 1,
|
|
||||||
};
|
|
||||||
case 'mediumint':
|
|
||||||
return {
|
|
||||||
typeCode: 'int',
|
|
||||||
bytes: 3,
|
|
||||||
};
|
|
||||||
case 'datetime':
|
|
||||||
return {
|
|
||||||
typeCode: 'datetime',
|
|
||||||
subType: 'datetime',
|
|
||||||
};
|
|
||||||
case 'time':
|
|
||||||
return {
|
|
||||||
typeCode: 'datetime',
|
|
||||||
subType: 'time',
|
|
||||||
};
|
|
||||||
case 'year':
|
|
||||||
return {
|
|
||||||
typeCode: 'datetime',
|
|
||||||
subType: 'year',
|
|
||||||
};
|
|
||||||
case 'date':
|
|
||||||
return {
|
|
||||||
typeCode: 'datetime',
|
|
||||||
subType: 'date',
|
|
||||||
};
|
|
||||||
case 'decimal':
|
|
||||||
case 'numeric':
|
|
||||||
return {
|
|
||||||
typeCode: 'numeric',
|
|
||||||
precision: col.precision,
|
|
||||||
scale: col.scale,
|
|
||||||
};
|
|
||||||
case 'float':
|
|
||||||
return { typeCode: 'float' };
|
|
||||||
case 'uniqueidentifier':
|
|
||||||
return { typeCode: 'string' };
|
|
||||||
case 'smallint':
|
|
||||||
return {
|
|
||||||
typeCode: 'int',
|
|
||||||
bytes: 2,
|
|
||||||
};
|
|
||||||
case 'int':
|
|
||||||
return {
|
|
||||||
typeCode: 'int',
|
|
||||||
bytes: 4,
|
|
||||||
};
|
|
||||||
case 'bigint':
|
|
||||||
return {
|
|
||||||
typeCode: 'int',
|
|
||||||
bytes: 8,
|
|
||||||
};
|
|
||||||
case 'real':
|
|
||||||
return { typeCode: 'float' };
|
|
||||||
case 'char':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
length: col.maxLength,
|
|
||||||
};
|
|
||||||
case 'nchar':
|
|
||||||
return { typeCode: 'string', length: col.maxLength, isUnicode: true };
|
|
||||||
case 'varchar':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
length: col.maxLength,
|
|
||||||
isVarLength: true,
|
|
||||||
};
|
|
||||||
case 'nvarchar':
|
|
||||||
return {
|
|
||||||
typeCode: 'string',
|
|
||||||
length: col.maxLength,
|
|
||||||
isVarLength: true,
|
|
||||||
isUnicode: true,
|
|
||||||
};
|
|
||||||
case 'text':
|
|
||||||
return {
|
|
||||||
typeCode: 'blob',
|
|
||||||
isText: true,
|
|
||||||
};
|
|
||||||
case 'ntext':
|
|
||||||
return {
|
|
||||||
typeCode: 'blob',
|
|
||||||
isText: true,
|
|
||||||
isUnicode: true,
|
|
||||||
};
|
|
||||||
case 'xml':
|
|
||||||
return {
|
|
||||||
typeCode: 'blob',
|
|
||||||
isXml: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
typeCode: 'generic',
|
columnName,
|
||||||
sql: col.dataType,
|
dataType,
|
||||||
|
notNull: !isNullable,
|
||||||
|
autoIncrement: !!isIdentity,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,14 +100,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
|
|
||||||
const tables = tablesRows.rows.map((row) => ({
|
const tables = tablesRows.rows.map((row) => ({
|
||||||
...row,
|
...row,
|
||||||
columns: columnsRows.rows
|
columns: columnsRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo),
|
||||||
.filter((col) => col.objectId == row.objectId)
|
|
||||||
.map(({ isNullable, isIdentity, ...col }) => ({
|
|
||||||
...col,
|
|
||||||
notNull: !isNullable,
|
|
||||||
autoIncrement: !!isIdentity,
|
|
||||||
commonType: detectType(col),
|
|
||||||
})),
|
|
||||||
primaryKey: DatabaseAnalyser.extractPrimaryKeys(row, pkColumnsRows.rows),
|
primaryKey: DatabaseAnalyser.extractPrimaryKeys(row, pkColumnsRows.rows),
|
||||||
foreignKeys: DatabaseAnalyser.extractForeignKeys(row, fkColumnsRows.rows),
|
foreignKeys: DatabaseAnalyser.extractForeignKeys(row, fkColumnsRows.rows),
|
||||||
}));
|
}));
|
||||||
@ -239,14 +108,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
const views = viewsRows.rows.map((row) => ({
|
const views = viewsRows.rows.map((row) => ({
|
||||||
...row,
|
...row,
|
||||||
createSql: getCreateSql(row),
|
createSql: getCreateSql(row),
|
||||||
columns: viewColumnRows.rows
|
columns: viewColumnRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo),
|
||||||
.filter((col) => col.objectId == row.objectId)
|
|
||||||
.map(({ isNullable, isIdentity, ...col }) => ({
|
|
||||||
...col,
|
|
||||||
notNull: !isNullable,
|
|
||||||
autoIncrement: !!isIdentity,
|
|
||||||
commonType: detectType(col),
|
|
||||||
})),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const procedures = programmableRows.rows
|
const procedures = programmableRows.rows
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/parsimmon": "^1.10.1",
|
"@types/parsimmon": "^1.10.1",
|
||||||
|
"@dbgate/tools": "^0.1.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"parsimmon": "^1.13.0"
|
"parsimmon": "^1.13.0"
|
||||||
|
@ -1,19 +1,11 @@
|
|||||||
import { DbTypeCode } from '@dbgate/types';
|
import { isTypeNumber, isTypeString, isTypeLogical, isTypeDateTime } from '@dbgate/tools';
|
||||||
import { FilterType } from './types';
|
import { FilterType } from './types';
|
||||||
|
|
||||||
export function getFilterType(typeCode?: DbTypeCode): FilterType {
|
export function getFilterType(dataType: string): FilterType {
|
||||||
if (!typeCode) return 'string';
|
if (!dataType) return 'string';
|
||||||
switch (typeCode) {
|
if (isTypeNumber(dataType)) return 'number';
|
||||||
case 'int':
|
if (isTypeString(dataType)) return 'string';
|
||||||
case 'numeric':
|
if (isTypeLogical(dataType)) return 'logical';
|
||||||
case 'float':
|
if (isTypeDateTime(dataType)) return 'datetime';
|
||||||
return 'number';
|
|
||||||
case 'string':
|
|
||||||
return 'string';
|
|
||||||
case 'datetime':
|
|
||||||
return 'datetime';
|
|
||||||
case 'logical':
|
|
||||||
return 'logical';
|
|
||||||
}
|
|
||||||
return 'string';
|
return 'string';
|
||||||
}
|
}
|
||||||
|
1
packages/tools/.gitignore
vendored
Normal file
1
packages/tools/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
lib
|
26
packages/tools/package.json
Normal file
26
packages/tools/package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": "0.1.0",
|
||||||
|
"name": "@dbgate/tools",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"typings": "lib/index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "yarn build",
|
||||||
|
"build": "tsc",
|
||||||
|
"start": "tsc --watch",
|
||||||
|
"test": "jest"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"devDependencies": {
|
||||||
|
"@dbgate/types": "^0.1.0",
|
||||||
|
"@types/node": "^13.7.0",
|
||||||
|
"jest": "^24.9.0",
|
||||||
|
"ts-jest": "^25.2.1",
|
||||||
|
"typescript": "^3.7.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.15",
|
||||||
|
"moment": "^2.24.0"
|
||||||
|
}
|
||||||
|
}
|
27
packages/tools/src/commonTypeParser.ts
Normal file
27
packages/tools/src/commonTypeParser.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
export function isTypeInteger(dataType) {
|
||||||
|
return dataType && /int/i.test(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeNumeric(dataType) {
|
||||||
|
return dataType && /numeric|decimal/i.test(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeFloat(dataType) {
|
||||||
|
return dataType && /float|single|double/i.test(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeNumber(dataType) {
|
||||||
|
return isTypeInteger(dataType) || isTypeFloat(dataType) || isTypeNumeric(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeString(dataType) {
|
||||||
|
return dataType && /char/i.test(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeLogical(dataType) {
|
||||||
|
return dataType && /bit|boolean/i.test(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTypeDateTime(dataType) {
|
||||||
|
return dataType && /date|time/i.test(dataType);
|
||||||
|
}
|
1
packages/tools/src/index.ts
Normal file
1
packages/tools/src/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './commonTypeParser';
|
14
packages/tools/tsconfig.json
Normal file
14
packages/tools/tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2015",
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"preserveWatchOutput": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
}
|
3
packages/types/dbinfo.d.ts
vendored
3
packages/types/dbinfo.d.ts
vendored
@ -1,5 +1,3 @@
|
|||||||
import { DbType } from './dbtypes';
|
|
||||||
|
|
||||||
export interface NamedObjectInfo {
|
export interface NamedObjectInfo {
|
||||||
pureName: string;
|
pureName: string;
|
||||||
schemaName: string;
|
schemaName: string;
|
||||||
@ -41,7 +39,6 @@ export interface ColumnInfo {
|
|||||||
isSparse: boolean;
|
isSparse: boolean;
|
||||||
defaultValue: string;
|
defaultValue: string;
|
||||||
defaultConstraint: string;
|
defaultConstraint: string;
|
||||||
commonType?: DbType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatabaseObjectInfo extends NamedObjectInfo {
|
export interface DatabaseObjectInfo extends NamedObjectInfo {
|
||||||
|
66
packages/types/dbtypes.d.ts
vendored
66
packages/types/dbtypes.d.ts
vendored
@ -1,66 +0,0 @@
|
|||||||
export type DbSizeType = 'small' | 'medium' | 'tiny' | 'long';
|
|
||||||
|
|
||||||
export interface DbTypeDatetime {
|
|
||||||
typeCode: 'datetime';
|
|
||||||
subType?: 'date' | 'datetime' | 'time' | 'year' | 'interval';
|
|
||||||
extendedPrecision?: boolean;
|
|
||||||
hasTimeZone?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeBlob {
|
|
||||||
typeCode: 'blob';
|
|
||||||
size?: DbSizeType;
|
|
||||||
isText?: boolean;
|
|
||||||
isUnicode?: boolean;
|
|
||||||
isXml?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeFloat {
|
|
||||||
typeCode: 'float';
|
|
||||||
bytes?: number;
|
|
||||||
isMoney?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeGeneric {
|
|
||||||
typeCode: 'generic';
|
|
||||||
sql: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeLogical {
|
|
||||||
typeCode: 'logical';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeNumeric {
|
|
||||||
typeCode: 'numeric';
|
|
||||||
precision?: number;
|
|
||||||
scale?: number;
|
|
||||||
autoIncrement?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeString {
|
|
||||||
typeCode: 'string';
|
|
||||||
length?: number;
|
|
||||||
isUnicode?: boolean;
|
|
||||||
isBinary?: boolean;
|
|
||||||
isBit?: boolean;
|
|
||||||
isVarLength?: boolean;
|
|
||||||
isBlob?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DbTypeInt {
|
|
||||||
typeCode: 'int';
|
|
||||||
bytes?: number;
|
|
||||||
autoIncrement?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DbType =
|
|
||||||
| DbTypeDatetime
|
|
||||||
| DbTypeBlob
|
|
||||||
| DbTypeFloat
|
|
||||||
| DbTypeGeneric
|
|
||||||
| DbTypeLogical
|
|
||||||
| DbTypeNumeric
|
|
||||||
| DbTypeString
|
|
||||||
| DbTypeInt;
|
|
||||||
|
|
||||||
export type DbTypeCode = DbType['typeCode'];
|
|
@ -1180,7 +1180,7 @@ export default function DataGridCore(props) {
|
|||||||
data-col={col.colIndex}
|
data-col={col.colIndex}
|
||||||
>
|
>
|
||||||
<DataFilterControl
|
<DataFilterControl
|
||||||
filterType={getFilterType(col.commonType ? col.commonType.typeCode : null)}
|
filterType={getFilterType(col.dataType)}
|
||||||
filter={display.getFilter(col.uniqueName)}
|
filter={display.getFilter(col.uniqueName)}
|
||||||
setFilter={(value) => display.setFilter(col.uniqueName, value)}
|
setFilter={(value) => display.setFilter(col.uniqueName, value)}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user