mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 01:33:59 +00:00
import-export - work with schema (mssql)
This commit is contained in:
@@ -89,6 +89,7 @@ DatabaseAnalyser.createEmptyStructure = () => ({
|
|||||||
functions: [],
|
functions: [],
|
||||||
procedures: [],
|
procedures: [],
|
||||||
triggers: [],
|
triggers: [],
|
||||||
|
schemas: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
DatabaseAnalyser.byTableFilter = (table) => (x) => x.pureName == table.pureName && x.schemaName == x.schemaName;
|
DatabaseAnalyser.byTableFilter = (table) => (x) => x.pureName == table.pureName && x.schemaName == x.schemaName;
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
if (this.singleObjectFilter) {
|
if (this.singleObjectFilter) {
|
||||||
const { typeField } = this.singleObjectFilter;
|
const { typeField } = this.singleObjectFilter;
|
||||||
if (!this.singleObjectId) return null;
|
if (!this.singleObjectId) return null;
|
||||||
if (!filterIdObjects.includes(typeField)) return null;
|
if (!filterIdObjects || !filterIdObjects.includes(typeField)) return null;
|
||||||
return res.replace('=[OBJECT_ID_CONDITION]', ` = ${this.singleObjectId}`);
|
return res.replace('=[OBJECT_ID_CONDITION]', ` = ${this.singleObjectId}`);
|
||||||
}
|
}
|
||||||
if (!this.modifications || !filterIdObjects || this.modifications.length == 0) {
|
if (!this.modifications || !filterIdObjects || this.modifications.length == 0) {
|
||||||
@@ -202,6 +202,9 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
const columnsRows = await this.driver.query(this.pool, this.createQuery('columns', ['tables']));
|
const columnsRows = await this.driver.query(this.pool, this.createQuery('columns', ['tables']));
|
||||||
const pkColumnsRows = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables']));
|
const pkColumnsRows = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables']));
|
||||||
const fkColumnsRows = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables']));
|
const fkColumnsRows = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables']));
|
||||||
|
const schemaRows = await this.driver.query(this.pool, this.createQuery('getSchemas'));
|
||||||
|
|
||||||
|
const schemas = schemaRows.rows;
|
||||||
|
|
||||||
const sqlCodeRows = await this.driver.query(
|
const sqlCodeRows = await this.driver.query(
|
||||||
this.pool,
|
this.pool,
|
||||||
@@ -265,6 +268,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
views,
|
views,
|
||||||
procedures,
|
procedures,
|
||||||
functions,
|
functions,
|
||||||
|
schemas,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
packages/engines/mssql/sql/getSchemas.js
Normal file
1
packages/engines/mssql/sql/getSchemas.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
module.exports = `select schema_id as objectId, name as schemaName from sys.schemas`;
|
||||||
@@ -7,6 +7,7 @@ const loadSqlCode = require('./loadSqlCode');
|
|||||||
const views = require('./views');
|
const views = require('./views');
|
||||||
const programmables = require('./programmables');
|
const programmables = require('./programmables');
|
||||||
const viewColumns = require('./viewColumns');
|
const viewColumns = require('./viewColumns');
|
||||||
|
const getSchemas = require('./getSchemas');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
columns,
|
columns,
|
||||||
@@ -18,4 +19,5 @@ module.exports = {
|
|||||||
views,
|
views,
|
||||||
programmables,
|
programmables,
|
||||||
viewColumns,
|
viewColumns,
|
||||||
|
getSchemas,
|
||||||
};
|
};
|
||||||
|
|||||||
6
packages/types/dbinfo.d.ts
vendored
6
packages/types/dbinfo.d.ts
vendored
@@ -71,10 +71,16 @@ export interface FunctionInfo extends SqlObjectInfo {}
|
|||||||
|
|
||||||
export interface TriggerInfo extends SqlObjectInfo {}
|
export interface TriggerInfo extends SqlObjectInfo {}
|
||||||
|
|
||||||
|
export interface SchemaInfo {
|
||||||
|
objectId?: string;
|
||||||
|
schemaName: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DatabaseInfo {
|
export interface DatabaseInfo {
|
||||||
tables: TableInfo[];
|
tables: TableInfo[];
|
||||||
views: ViewInfo[];
|
views: ViewInfo[];
|
||||||
procedures: ProcedureInfo[];
|
procedures: ProcedureInfo[];
|
||||||
functions: FunctionInfo[];
|
functions: FunctionInfo[];
|
||||||
triggers: TriggerInfo[];
|
triggers: TriggerInfo[];
|
||||||
|
schemas: SchemaInfo[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ function Menu({ data, makeAppObj, setOpenedTabs, showModal }) {
|
|||||||
sourceStorageType: 'database',
|
sourceStorageType: 'database',
|
||||||
sourceConnectionId: data.conid,
|
sourceConnectionId: data.conid,
|
||||||
sourceDatabaseName: data.database,
|
sourceDatabaseName: data.database,
|
||||||
sourceTables: [fullNameToString(data)],
|
sourceSchemaName: data.schemaName,
|
||||||
|
sourceTables: [data.pureName],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -604,7 +604,8 @@ export default function DataGridCore(props) {
|
|||||||
sourceStorageType: 'database',
|
sourceStorageType: 'database',
|
||||||
sourceConnectionId: conid,
|
sourceConnectionId: conid,
|
||||||
sourceDatabaseName: database,
|
sourceDatabaseName: database,
|
||||||
sourceTables: display.baseTable ? [fullNameToString(display.baseTable)] : [],
|
sourceSchemaName: display.baseTable && display.baseTable.schemaName,
|
||||||
|
sourceTables: display.baseTable ? [display.baseTable.pureName] : [],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ import {
|
|||||||
FormConnectionSelect,
|
FormConnectionSelect,
|
||||||
FormDatabaseSelect,
|
FormDatabaseSelect,
|
||||||
FormTablesSelect,
|
FormTablesSelect,
|
||||||
|
FormSelectField,
|
||||||
|
FormSchemaSelect,
|
||||||
} from '../utility/forms';
|
} from '../utility/forms';
|
||||||
import { useConnectionList, useDatabaseList } from '../utility/metadataLoaders';
|
import { useConnectionList, useDatabaseList } from '../utility/metadataLoaders';
|
||||||
import TableControl, { TableColumn } from '../utility/TableControl';
|
import TableControl, { TableColumn } from '../utility/TableControl';
|
||||||
|
import { TextField, SelectField } from '../utility/inputs';
|
||||||
|
|
||||||
const Container = styled.div``;
|
const Container = styled.div``;
|
||||||
|
|
||||||
@@ -66,9 +69,9 @@ function DatabaseSelector() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SourceTargetConfig({ direction, storageTypeField, connectionIdField, databaseNameField, tablesField }) {
|
function SourceTargetConfig({ direction, storageTypeField, connectionIdField, databaseNameField, schemaNameField,tablesField }) {
|
||||||
const types = [
|
const types = [
|
||||||
{ value: 'database', label: 'Database', directions: ['source'] },
|
{ value: 'database', label: 'Database', directions: ['source', 'target'] },
|
||||||
{ value: 'csv', label: 'CSV file(s)', directions: ['target'] },
|
{ value: 'csv', label: 'CSV file(s)', directions: ['target'] },
|
||||||
{ value: 'jsonl', label: 'JSON lines file(s)', directions: ['target'] },
|
{ value: 'jsonl', label: 'JSON lines file(s)', directions: ['target'] },
|
||||||
];
|
];
|
||||||
@@ -84,10 +87,12 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da
|
|||||||
<FormConnectionSelect name={connectionIdField} />
|
<FormConnectionSelect name={connectionIdField} />
|
||||||
<Label>Database</Label>
|
<Label>Database</Label>
|
||||||
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} />
|
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} />
|
||||||
|
<Label>Schema</Label>
|
||||||
|
<FormSchemaSelect conidName={connectionIdField} databaseName={databaseNameField} name={schemaNameField} />
|
||||||
{direction == 'source' && (
|
{direction == 'source' && (
|
||||||
<>
|
<>
|
||||||
<Label>Tables/views</Label>
|
<Label>Tables/views</Label>
|
||||||
<FormTablesSelect conidName={connectionIdField} databaseName={databaseNameField} name={tablesField} />
|
<FormTablesSelect conidName={connectionIdField} schemaName={schemaNameField} databaseName={databaseNameField} name={tablesField} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -99,6 +104,9 @@ function SourceTargetConfig({ direction, storageTypeField, connectionIdField, da
|
|||||||
export default function ImportExportConfigurator() {
|
export default function ImportExportConfigurator() {
|
||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
const sources = values.sourceTables;
|
const sources = values.sourceTables;
|
||||||
|
const getActionOptions = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
const actionOptions = [
|
const actionOptions = [
|
||||||
{
|
{
|
||||||
label: 'Create file',
|
label: 'Create file',
|
||||||
@@ -125,6 +133,7 @@ export default function ImportExportConfigurator() {
|
|||||||
storageTypeField="sourceStorageType"
|
storageTypeField="sourceStorageType"
|
||||||
connectionIdField="sourceConnectionId"
|
connectionIdField="sourceConnectionId"
|
||||||
databaseNameField="sourceDatabaseName"
|
databaseNameField="sourceDatabaseName"
|
||||||
|
schemaNameField="sourceSchemaName"
|
||||||
tablesField="sourceTables"
|
tablesField="sourceTables"
|
||||||
/>
|
/>
|
||||||
<SourceTargetConfig
|
<SourceTargetConfig
|
||||||
@@ -132,17 +141,15 @@ export default function ImportExportConfigurator() {
|
|||||||
storageTypeField="targetStorageType"
|
storageTypeField="targetStorageType"
|
||||||
connectionIdField="targetConnectionId"
|
connectionIdField="targetConnectionId"
|
||||||
databaseNameField="targetDatabaseName"
|
databaseNameField="targetDatabaseName"
|
||||||
|
schemaNameField="targetSchemaName"
|
||||||
tablesField="targetTables"
|
tablesField="targetTables"
|
||||||
/>
|
/>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
{/* <TableControl rows={sources || []}>
|
<TableControl rows={sources || []}>
|
||||||
<TableColumn fieldName="source" header="Source" formatter={(row) => row} />
|
<TableColumn fieldName="source" header="Source" formatter={(row) => row} />
|
||||||
<TableColumn
|
<TableColumn fieldName="action" header="Action" formatter={(row) => <SelectField options={actionOptions} />} />
|
||||||
fieldName="action"
|
<TableColumn fieldName="target" header="Target" formatter={(row) => <TextField />} />
|
||||||
header="Action"
|
</TableControl>
|
||||||
formatter={(row) => <FormReactSelect name={`action_${row}`} options={actionOptions} />}
|
|
||||||
/>
|
|
||||||
</TableControl> */}
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default async function createImpExpScript(values) {
|
|||||||
const connection = await getConnectionInfo({ conid: values.sourceConnectionId });
|
const connection = await getConnectionInfo({ conid: values.sourceConnectionId });
|
||||||
const driver = engines(connection);
|
const driver = engines(connection);
|
||||||
|
|
||||||
const fullName = fullNameFromString(table);
|
const fullName = { schemaName: values.sourceSchemaName, pureName: table };
|
||||||
script.assign(sourceVar, 'queryReader', {
|
script.assign(sourceVar, 'queryReader', {
|
||||||
connection: {
|
connection: {
|
||||||
..._.pick(connection, ['server', 'engine', 'user', 'password', 'port']),
|
..._.pick(connection, ['server', 'engine', 'user', 'password', 'port']),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function FormSelectFieldRaw({ children, ...other }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormSelectField({ label, children, ...other }) {
|
export function FormSelectField({ label, children = null, ...other }) {
|
||||||
return (
|
return (
|
||||||
<FormRow>
|
<FormRow>
|
||||||
<FormLabel>{label}</FormLabel>
|
<FormLabel>{label}</FormLabel>
|
||||||
@@ -138,16 +138,34 @@ export function FormDatabaseSelect({ conidName, name }) {
|
|||||||
return <FormReactSelect options={databaseOptions} name={name} />;
|
return <FormReactSelect options={databaseOptions} name={name} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormTablesSelect({ conidName, databaseName, name }) {
|
export function FormSchemaSelect({ conidName, databaseName, name }) {
|
||||||
|
const { values } = useFormikContext();
|
||||||
|
const dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
||||||
|
const schemaOptions = React.useMemo(
|
||||||
|
() =>
|
||||||
|
((dbinfo && dbinfo.schemas) || []).map((schema) => ({
|
||||||
|
value: schema.schemaName,
|
||||||
|
label: schema.schemaName,
|
||||||
|
})),
|
||||||
|
[dbinfo]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (schemaOptions.length == 0) return <div>Not available</div>;
|
||||||
|
return <FormReactSelect options={schemaOptions} name={name} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FormTablesSelect({ conidName, databaseName, schemaName, name }) {
|
||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
const dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
const dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
||||||
const tablesOptions = React.useMemo(
|
const tablesOptions = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
[...((dbinfo && dbinfo.tables) || []), ...((dbinfo && dbinfo.views) || [])].map((x) => ({
|
[...((dbinfo && dbinfo.tables) || []), ...((dbinfo && dbinfo.views) || [])]
|
||||||
value: fullNameToString(x),
|
.filter((x) => !values[schemaName] || x.schemaName == values[schemaName])
|
||||||
label: x.pureName,
|
.map((x) => ({
|
||||||
})),
|
value: x.pureName,
|
||||||
[dbinfo]
|
label: x.pureName,
|
||||||
|
})),
|
||||||
|
[dbinfo, values[schemaName]]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (tablesOptions.length == 0) return <div>Not available</div>;
|
if (tablesOptions.length == 0) return <div>Not available</div>;
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ export function TextField({ editorRef = undefined, ...other }) {
|
|||||||
return <input type="text" {...other} ref={editorRef}></input>;
|
return <input type="text" {...other} ref={editorRef}></input>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SelectField({ children, ...other }) {
|
export function SelectField({ children = null, options = [], ...other }) {
|
||||||
return <select {...other}>{children}</select>;
|
return (
|
||||||
|
<select {...other}>
|
||||||
|
{children}
|
||||||
|
{options.map((x) => (
|
||||||
|
<option value={x.value} key={x.value}>
|
||||||
|
{x.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user