mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-29 15:43:59 +00:00
import-export - work with schema (mssql)
This commit is contained in:
@@ -89,6 +89,7 @@ DatabaseAnalyser.createEmptyStructure = () => ({
|
||||
functions: [],
|
||||
procedures: [],
|
||||
triggers: [],
|
||||
schemas: [],
|
||||
});
|
||||
|
||||
DatabaseAnalyser.byTableFilter = (table) => (x) => x.pureName == table.pureName && x.schemaName == x.schemaName;
|
||||
|
||||
@@ -168,7 +168,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
||||
if (this.singleObjectFilter) {
|
||||
const { typeField } = this.singleObjectFilter;
|
||||
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}`);
|
||||
}
|
||||
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 pkColumnsRows = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['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(
|
||||
this.pool,
|
||||
@@ -265,6 +268,7 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
||||
views,
|
||||
procedures,
|
||||
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 programmables = require('./programmables');
|
||||
const viewColumns = require('./viewColumns');
|
||||
const getSchemas = require('./getSchemas');
|
||||
|
||||
module.exports = {
|
||||
columns,
|
||||
@@ -18,4 +19,5 @@ module.exports = {
|
||||
views,
|
||||
programmables,
|
||||
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 SchemaInfo {
|
||||
objectId?: string;
|
||||
schemaName: string;
|
||||
}
|
||||
|
||||
export interface DatabaseInfo {
|
||||
tables: TableInfo[];
|
||||
views: ViewInfo[];
|
||||
procedures: ProcedureInfo[];
|
||||
functions: FunctionInfo[];
|
||||
triggers: TriggerInfo[];
|
||||
schemas: SchemaInfo[];
|
||||
}
|
||||
|
||||
@@ -114,7 +114,8 @@ function Menu({ data, makeAppObj, setOpenedTabs, showModal }) {
|
||||
sourceStorageType: 'database',
|
||||
sourceConnectionId: data.conid,
|
||||
sourceDatabaseName: data.database,
|
||||
sourceTables: [fullNameToString(data)],
|
||||
sourceSchemaName: data.schemaName,
|
||||
sourceTables: [data.pureName],
|
||||
}}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -604,7 +604,8 @@ export default function DataGridCore(props) {
|
||||
sourceStorageType: 'database',
|
||||
sourceConnectionId: conid,
|
||||
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,
|
||||
FormDatabaseSelect,
|
||||
FormTablesSelect,
|
||||
FormSelectField,
|
||||
FormSchemaSelect,
|
||||
} from '../utility/forms';
|
||||
import { useConnectionList, useDatabaseList } from '../utility/metadataLoaders';
|
||||
import TableControl, { TableColumn } from '../utility/TableControl';
|
||||
import { TextField, SelectField } from '../utility/inputs';
|
||||
|
||||
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 = [
|
||||
{ value: 'database', label: 'Database', directions: ['source'] },
|
||||
{ value: 'database', label: 'Database', directions: ['source', 'target'] },
|
||||
{ value: 'csv', label: 'CSV 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} />
|
||||
<Label>Database</Label>
|
||||
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} />
|
||||
<Label>Schema</Label>
|
||||
<FormSchemaSelect conidName={connectionIdField} databaseName={databaseNameField} name={schemaNameField} />
|
||||
{direction == 'source' && (
|
||||
<>
|
||||
<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() {
|
||||
const { values } = useFormikContext();
|
||||
const sources = values.sourceTables;
|
||||
const getActionOptions = ()=>{
|
||||
|
||||
}
|
||||
const actionOptions = [
|
||||
{
|
||||
label: 'Create file',
|
||||
@@ -125,6 +133,7 @@ export default function ImportExportConfigurator() {
|
||||
storageTypeField="sourceStorageType"
|
||||
connectionIdField="sourceConnectionId"
|
||||
databaseNameField="sourceDatabaseName"
|
||||
schemaNameField="sourceSchemaName"
|
||||
tablesField="sourceTables"
|
||||
/>
|
||||
<SourceTargetConfig
|
||||
@@ -132,17 +141,15 @@ export default function ImportExportConfigurator() {
|
||||
storageTypeField="targetStorageType"
|
||||
connectionIdField="targetConnectionId"
|
||||
databaseNameField="targetDatabaseName"
|
||||
schemaNameField="targetSchemaName"
|
||||
tablesField="targetTables"
|
||||
/>
|
||||
</Wrapper>
|
||||
{/* <TableControl rows={sources || []}>
|
||||
<TableControl rows={sources || []}>
|
||||
<TableColumn fieldName="source" header="Source" formatter={(row) => row} />
|
||||
<TableColumn
|
||||
fieldName="action"
|
||||
header="Action"
|
||||
formatter={(row) => <FormReactSelect name={`action_${row}`} options={actionOptions} />}
|
||||
/>
|
||||
</TableControl> */}
|
||||
<TableColumn fieldName="action" header="Action" formatter={(row) => <SelectField options={actionOptions} />} />
|
||||
<TableColumn fieldName="target" header="Target" formatter={(row) => <TextField />} />
|
||||
</TableControl>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function createImpExpScript(values) {
|
||||
const connection = await getConnectionInfo({ conid: values.sourceConnectionId });
|
||||
const driver = engines(connection);
|
||||
|
||||
const fullName = fullNameFromString(table);
|
||||
const fullName = { schemaName: values.sourceSchemaName, pureName: table };
|
||||
script.assign(sourceVar, 'queryReader', {
|
||||
connection: {
|
||||
..._.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 (
|
||||
<FormRow>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
@@ -138,16 +138,34 @@ export function FormDatabaseSelect({ conidName, 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 dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
||||
const tablesOptions = React.useMemo(
|
||||
() =>
|
||||
[...((dbinfo && dbinfo.tables) || []), ...((dbinfo && dbinfo.views) || [])].map((x) => ({
|
||||
value: fullNameToString(x),
|
||||
label: x.pureName,
|
||||
})),
|
||||
[dbinfo]
|
||||
[...((dbinfo && dbinfo.tables) || []), ...((dbinfo && dbinfo.views) || [])]
|
||||
.filter((x) => !values[schemaName] || x.schemaName == values[schemaName])
|
||||
.map((x) => ({
|
||||
value: x.pureName,
|
||||
label: x.pureName,
|
||||
})),
|
||||
[dbinfo, values[schemaName]]
|
||||
);
|
||||
|
||||
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>;
|
||||
}
|
||||
|
||||
export function SelectField({ children, ...other }) {
|
||||
return <select {...other}>{children}</select>;
|
||||
export function SelectField({ children = null, options = [], ...other }) {
|
||||
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