mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 17:36:00 +00:00
sql generator
This commit is contained in:
@@ -15,13 +15,62 @@ export function addTableDependencies(db: DatabaseInfo): DatabaseInfo {
|
|||||||
function fillTableExtendedInfo(db: DatabaseInfo) {
|
function fillTableExtendedInfo(db: DatabaseInfo) {
|
||||||
return {
|
return {
|
||||||
...db,
|
...db,
|
||||||
tables: db.tables.map(table => ({
|
tables: (db.tables || []).map(obj => ({
|
||||||
...table,
|
...obj,
|
||||||
columns: (table.columns || []).map(column => ({
|
objectTypeField: 'tables',
|
||||||
pureName: table.pureName,
|
columns: (obj.columns || []).map(column => ({
|
||||||
schemaName: table.schemaName,
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
...column,
|
...column,
|
||||||
})),
|
})),
|
||||||
|
primaryKey: obj.primaryKey
|
||||||
|
? {
|
||||||
|
...obj.primaryKey,
|
||||||
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
|
constraintType: 'primaryKey',
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
foreignKeys: (obj.foreignKeys || []).map(cnt => ({
|
||||||
|
...cnt,
|
||||||
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
|
constraintType: 'foreignKey',
|
||||||
|
})),
|
||||||
|
indexes: (obj.indexes || []).map(cnt => ({
|
||||||
|
...cnt,
|
||||||
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
|
constraintType: 'index',
|
||||||
|
})),
|
||||||
|
checks: (obj.checks || []).map(cnt => ({
|
||||||
|
...cnt,
|
||||||
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
|
constraintType: 'check',
|
||||||
|
})),
|
||||||
|
uniques: (obj.uniques || []).map(cnt => ({
|
||||||
|
...cnt,
|
||||||
|
pureName: obj.pureName,
|
||||||
|
schemaName: obj.schemaName,
|
||||||
|
constraintType: 'unique',
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
views: (db.views || []).map(obj => ({
|
||||||
|
...obj,
|
||||||
|
objectTypeField: 'views',
|
||||||
|
})),
|
||||||
|
procedures: (db.procedures || []).map(obj => ({
|
||||||
|
...obj,
|
||||||
|
objectTypeField: 'procedures',
|
||||||
|
})),
|
||||||
|
functions: (db.functions || []).map(obj => ({
|
||||||
|
...obj,
|
||||||
|
objectTypeField: 'functions',
|
||||||
|
})),
|
||||||
|
triggers: (db.triggers || []).map(obj => ({
|
||||||
|
...obj,
|
||||||
|
objectTypeField: 'triggers',
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
1
packages/types/dbinfo.d.ts
vendored
1
packages/types/dbinfo.d.ts
vendored
@@ -70,6 +70,7 @@ export interface TableInfo extends DatabaseObjectInfo {
|
|||||||
foreignKeys: ForeignKeyInfo[];
|
foreignKeys: ForeignKeyInfo[];
|
||||||
dependencies?: ForeignKeyInfo[];
|
dependencies?: ForeignKeyInfo[];
|
||||||
indexes?: IndexInfo[];
|
indexes?: IndexInfo[];
|
||||||
|
uniques?: UniqueInfo[];
|
||||||
checks?: CheckInfo[];
|
checks?: CheckInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ body {
|
|||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
.flexcol {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
.nowrap {
|
.nowrap {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import Link from '../elements/Link.svelte';
|
||||||
|
|
||||||
import { plusExpandIcon } from '../icons/expandIcons';
|
import { plusExpandIcon } from '../icons/expandIcons';
|
||||||
|
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
@@ -6,6 +8,7 @@
|
|||||||
import AppObjectListItem from './AppObjectListItem.svelte';
|
import AppObjectListItem from './AppObjectListItem.svelte';
|
||||||
|
|
||||||
export let group;
|
export let group;
|
||||||
|
export let groupFunc;
|
||||||
export let items;
|
export let items;
|
||||||
export let module;
|
export let module;
|
||||||
export let checkedObjectsStore = null;
|
export let checkedObjectsStore = null;
|
||||||
@@ -14,6 +17,20 @@
|
|||||||
|
|
||||||
$: filtered = items.filter(x => x.isMatched);
|
$: filtered = items.filter(x => x.isMatched);
|
||||||
$: countText = filtered.length < items.length ? `${filtered.length}/${items.length}` : `${items.length}`;
|
$: countText = filtered.length < items.length ? `${filtered.length}/${items.length}` : `${items.length}`;
|
||||||
|
|
||||||
|
function handleCheckAll(isChecked) {
|
||||||
|
checkedObjectsStore.update(checkList => {
|
||||||
|
const res = isChecked
|
||||||
|
? [
|
||||||
|
...checkList,
|
||||||
|
...filtered
|
||||||
|
.filter(x => !checkList.find(y => module.extractKey(x.data) == module.extractKey(y)))
|
||||||
|
.map(x => x.data),
|
||||||
|
]
|
||||||
|
: checkList.filter(x => groupFunc(x) != group);
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="group" on:click={() => (isExpanded = !isExpanded)}>
|
<div class="group" on:click={() => (isExpanded = !isExpanded)}>
|
||||||
@@ -26,6 +43,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if isExpanded}
|
{#if isExpanded}
|
||||||
|
{#if checkedObjectsStore}
|
||||||
|
<div class="ml-2">
|
||||||
|
<Link onClick={() => handleCheckAll(true)}>Check all</Link>
|
||||||
|
|
|
||||||
|
<Link onClick={() => handleCheckAll(false)}>Uncheck all</Link>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#each filtered as item (module.extractKey(item.data))}
|
{#each filtered as item (module.extractKey(item.data))}
|
||||||
<AppObjectListItem {...$$restProps} {module} data={item.data} {checkedObjectsStore} on:objectClick />
|
<AppObjectListItem {...$$restProps} {module} data={item.data} {checkedObjectsStore} on:objectClick />
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
{isExpandable}
|
{isExpandable}
|
||||||
{subItemsComponent}
|
{subItemsComponent}
|
||||||
{checkedObjectsStore}
|
{checkedObjectsStore}
|
||||||
|
{groupFunc}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import getElectron from '../utility/getElectron';
|
import getElectron from '../utility/getElectron';
|
||||||
|
|
||||||
export let href;
|
export let href = undefined;
|
||||||
|
export let onClick = undefined;
|
||||||
|
|
||||||
const electron = getElectron();
|
const electron = getElectron();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if electron}
|
{#if onClick}
|
||||||
|
<a on:click={onClick}>
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
{:else if electron}
|
||||||
<a on:click={() => electron.shell.openExternal(href)}>
|
<a on:click={() => electron.shell.openExternal(href)}>
|
||||||
<slot />
|
<slot />
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="largeFormMarker" class:noMargin>
|
<div class="largeFormMarker" class:noMargin>
|
||||||
{#if type == 'checkbox'}
|
{#if type == 'checkbox'}
|
||||||
<slot />
|
<slot />
|
||||||
<span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span>
|
<span {...labelProps} on:click={labelProps.onClick} class:disabled class='checkLabel'>{label}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="label" {...labelProps} on:click={labelProps.onClick}>
|
<div class="label" {...labelProps} on:click={labelProps.onClick}>
|
||||||
<span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span>
|
<span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span>
|
||||||
@@ -23,6 +23,10 @@
|
|||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
color: var(--theme-font-3);
|
color: var(--theme-font-3);
|
||||||
}
|
}
|
||||||
|
.checkLabel {
|
||||||
|
cursor: default;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
.largeFormMarker:not(.noMargin) {
|
.largeFormMarker:not(.noMargin) {
|
||||||
margin: var(--dim-large-form-margin);
|
margin: var(--dim-large-form-margin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
{#if type == 'checkbox'}
|
{#if type == 'checkbox'}
|
||||||
<slot />
|
<slot />
|
||||||
<span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span>
|
<span {...labelProps} on:click={labelProps.onClick} class:disabled class="checkLabel">{label}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="label" {...labelProps} on:click={labelProps.onClick}>
|
<div class="label" {...labelProps} on:click={labelProps.onClick}>
|
||||||
<div class="label">
|
<div class="label">
|
||||||
@@ -30,6 +30,10 @@
|
|||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
color: var(--theme-font-3);
|
color: var(--theme-font-3);
|
||||||
}
|
}
|
||||||
|
.checkLabel {
|
||||||
|
cursor: default;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
.disabled {
|
.disabled {
|
||||||
color: var(--theme-font-3);
|
color: var(--theme-font-3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<ModalBase {...$$restProps}>
|
<ModalBase {...$$restProps}>
|
||||||
<svelte:fragment slot="header">About DbGate</svelte:fragment>
|
<svelte:fragment slot="header">About DbGate</svelte:fragment>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<img src="/logo192.png" />
|
<img src="logo192.png" />
|
||||||
<div>
|
<div>
|
||||||
<div class="m-1">
|
<div class="m-1">
|
||||||
Version: <span>{version}</span>
|
Version: <span>{version}</span>
|
||||||
|
|||||||
@@ -32,28 +32,44 @@
|
|||||||
export let conid;
|
export let conid;
|
||||||
export let database;
|
export let database;
|
||||||
|
|
||||||
|
export let initialConfig = {
|
||||||
|
checkIfTableExists: true,
|
||||||
|
disableConstraints: true,
|
||||||
|
createTables: true,
|
||||||
|
createForeignKeys: true,
|
||||||
|
createViews: true,
|
||||||
|
createProcedures: true,
|
||||||
|
createFunctions: true,
|
||||||
|
createTriggers: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export let initialObjects = null;
|
||||||
|
|
||||||
let busy = false;
|
let busy = false;
|
||||||
let managerSize;
|
let managerSize;
|
||||||
let objectsFilter = '';
|
let objectsFilter = '';
|
||||||
let sqlPreview = '';
|
let sqlPreview = '';
|
||||||
|
let initialized = false;
|
||||||
|
|
||||||
const checkedObjectsStore = writable([]);
|
$: dbinfo = useDatabaseInfo({ conid, database });
|
||||||
const valuesStore = writable({
|
|
||||||
checkIfTableExists: true,
|
const checkedObjectsStore = writable(initialObjects || ($dbinfo && $dbinfo.tables) || []);
|
||||||
disableConstraints: true,
|
const valuesStore = writable(initialConfig);
|
||||||
});
|
|
||||||
const loadRef = createRef(null);
|
const loadRef = createRef(null);
|
||||||
|
|
||||||
$: console.log('checkedObjectsStore', $checkedObjectsStore);
|
// $: console.log('checkedObjectsStore', $checkedObjectsStore);
|
||||||
|
|
||||||
$: objects = useDatabaseInfo({ conid, database });
|
$: if ($dbinfo && !initialized && !initialObjects) {
|
||||||
|
initialized = true;
|
||||||
|
$checkedObjectsStore = $dbinfo.tables;
|
||||||
|
}
|
||||||
|
|
||||||
$: generatePreview($valuesStore, $checkedObjectsStore);
|
$: generatePreview($valuesStore, $checkedObjectsStore);
|
||||||
|
|
||||||
$: objectList = _.flatten(
|
$: objectList = _.flatten(
|
||||||
['tables', 'views', 'procedures', 'functions'].map(objectTypeField =>
|
['tables', 'views', 'procedures', 'functions'].map(objectTypeField =>
|
||||||
_.sortBy(
|
_.sortBy(
|
||||||
(($objects || {})[objectTypeField] || []).map(obj => ({ ...obj, objectTypeField })),
|
(($dbinfo || {})[objectTypeField] || []).map(obj => ({ ...obj, objectTypeField })),
|
||||||
['schemaName', 'pureName']
|
['schemaName', 'pureName']
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -91,7 +107,7 @@
|
|||||||
|
|
||||||
<HorizontalSplitter initialValue="300px" bind:size={managerSize}>
|
<HorizontalSplitter initialValue="300px" bind:size={managerSize}>
|
||||||
<svelte:fragment slot="1">
|
<svelte:fragment slot="1">
|
||||||
<div>
|
<div class="flexcol flex1">
|
||||||
<WidgetTitle>Choose objects</WidgetTitle>
|
<WidgetTitle>Choose objects</WidgetTitle>
|
||||||
<SearchBoxWrapper>
|
<SearchBoxWrapper>
|
||||||
<SearchInput placeholder="Search tables or objects" bind:value={objectsFilter} />
|
<SearchInput placeholder="Search tables or objects" bind:value={objectsFilter} />
|
||||||
@@ -116,40 +132,54 @@
|
|||||||
<SqlEditor readOnly value={sqlPreview} />
|
<SqlEditor readOnly value={sqlPreview} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="2">
|
<svelte:fragment slot="2">
|
||||||
<WidgetsInnerContainer>
|
<div class="flexcol flex1">
|
||||||
<FormValues let:values>
|
<WidgetTitle>Generator settings</WidgetTitle>
|
||||||
<FormCheckboxField label="Drop tables" name="dropTables" />
|
<WidgetsInnerContainer>
|
||||||
{#if values.dropTables}
|
<FormValues let:values>
|
||||||
<div class="ml-2">
|
<div class="obj-heading">Tables</div>
|
||||||
<FormCheckboxField label="Test if exists" name="checkIfTableExists" />
|
<FormCheckboxField label="Drop tables" name="dropTables" />
|
||||||
</div>
|
{#if values.dropTables}
|
||||||
{/if}
|
<div class="ml-2">
|
||||||
<FormCheckboxField label="Drop references" name="dropReferences" />
|
<FormCheckboxField label="Test if exists" name="checkIfTableExists" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<FormCheckboxField label="Drop references" name="dropReferences" />
|
||||||
|
|
||||||
<FormCheckboxField label="Create tables" name="createTables" />
|
<FormCheckboxField label="Create tables" name="createTables" />
|
||||||
<FormCheckboxField label="Create references" name="createReferences" />
|
<FormCheckboxField label="Create references" name="createReferences" />
|
||||||
<FormCheckboxField label="Create foreign keys" name="createForeignKeys" />
|
<FormCheckboxField label="Create foreign keys" name="createForeignKeys" />
|
||||||
<FormCheckboxField label="Create indexes" name="createIndexes" />
|
<FormCheckboxField label="Create indexes" name="createIndexes" />
|
||||||
|
|
||||||
<FormCheckboxField label="Insert" name="insert" />
|
<FormCheckboxField label="Insert" name="insert" />
|
||||||
{#if values.insert}
|
{#if values.insert}
|
||||||
<div class="ml-2">
|
<div class="ml-2">
|
||||||
<FormCheckboxField label="Skip autoincrement column" name="skipAutoincrementColumn" />
|
<FormCheckboxField label="Skip autoincrement column" name="skipAutoincrementColumn" />
|
||||||
<FormCheckboxField label="Disable constraints" name="disableConstraints" />
|
<FormCheckboxField label="Disable constraints" name="disableConstraints" />
|
||||||
<FormCheckboxField label="Omit NULL values" name="omitNulls" />
|
<FormCheckboxField label="Omit NULL values" name="omitNulls" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<FormCheckboxField label="Truncate tables (delete all rows)" name="truncate" />
|
<FormCheckboxField label="Truncate tables (delete all rows)" name="truncate" />
|
||||||
|
|
||||||
<!-- <HashCheckBox label='Drop' hashName={`gensql.drop${objTypePascal}`} onChange={onChange} />
|
{#each ['View', 'Procedure', 'Function', 'Trigger'] as objtype}
|
||||||
|
<div class="obj-heading">{objtype}s</div>
|
||||||
|
<FormCheckboxField label="Create" name={`create${objtype}s`} />
|
||||||
|
<FormCheckboxField label="Drop" name={`drop${objtype}s`} />
|
||||||
|
{#if values[`drop${objtype}s`]}
|
||||||
|
<div class="ml-2">
|
||||||
|
<FormCheckboxField label="Check if exists" name={`checkIf${objtype}Exists`} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
<!-- <HashCheckBox label='Drop' hashName={`gensql.drop${objTypePascal}`} onChange={onChange} />
|
||||||
{
|
{
|
||||||
getHashValue(`gensql.drop${objTypePascal}`) == '1' &&
|
getHashValue(`gensql.drop${objTypePascal}`) == '1' &&
|
||||||
<HashCheckBox label='Test if exists' hashName={`gensql.checkIf${objTypePascal}Exists`} indent={1} onChange={onChange} defaultChecked />
|
<HashCheckBox label='Test if exists' hashName={`gensql.checkIf${objTypePascal}Exists`} indent={1} onChange={onChange} defaultChecked />
|
||||||
}
|
}
|
||||||
<HashCheckBox label='Create' hashName={`gensql.create${objTypePascal}`} onChange={onChange} /> -->
|
<HashCheckBox label='Create' hashName={`gensql.create${objTypePascal}`} onChange={onChange} /> -->
|
||||||
</FormValues>
|
</FormValues>
|
||||||
</WidgetsInnerContainer>
|
</WidgetsInnerContainer>
|
||||||
|
</div>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</HorizontalSplitter>
|
</HorizontalSplitter>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
@@ -162,3 +192,11 @@
|
|||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</ModalBase>
|
</ModalBase>
|
||||||
</FormProviderCore>
|
</FormProviderCore>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.obj-heading {
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user