Merge pull request #1349 from dbgate/feature/mysql-indexes
MySQL FULLTEXT support #1305
This commit is contained in:
@@ -544,9 +544,14 @@ export class SqlDumper implements AlterProcessor {
|
||||
}
|
||||
this.endCommand();
|
||||
}
|
||||
indexType(ix: IndexInfo) {
|
||||
if (ix.isUnique) {
|
||||
this.put(' ^unique');
|
||||
}
|
||||
}
|
||||
createIndex(ix: IndexInfo) {
|
||||
this.put('^create');
|
||||
if (ix.isUnique) this.put(' ^unique');
|
||||
this.indexType(ix);
|
||||
this.put(' ^index %i &n^on %f (&>&n', ix.constraintName, ix);
|
||||
this.putCollection(',&n', ix.columns, col => {
|
||||
this.put('%i %k', col.columnName, col.isDescending == true ? 'DESC' : 'ASC');
|
||||
|
||||
Vendored
+6
@@ -50,6 +50,12 @@ export interface SqlDialect {
|
||||
multipleSchema?: boolean;
|
||||
filteredIndexes?: boolean;
|
||||
namedDefaultConstraint?: boolean;
|
||||
indexTypes?: {
|
||||
value: string;
|
||||
label: string;
|
||||
isUnique?: boolean;
|
||||
indexType?: string;
|
||||
}[];
|
||||
|
||||
specificNullabilityImplementation?: boolean;
|
||||
implicitNullDeclaration?: boolean;
|
||||
|
||||
@@ -12,9 +12,41 @@
|
||||
export let tableInfo;
|
||||
export let driver;
|
||||
|
||||
function getIndexTypeValue(constraintInfo, indexTypeOptions) {
|
||||
if (!indexTypeOptions?.length) return null;
|
||||
const indexType = constraintInfo?.indexType?.toString()?.toUpperCase();
|
||||
if (indexType === 'FULLTEXT') {
|
||||
return indexTypeOptions.find(option => option.indexType?.toString()?.toUpperCase() === 'FULLTEXT')?.value;
|
||||
}
|
||||
if (constraintInfo?.isUnique) {
|
||||
return indexTypeOptions.find(option => option.isUnique)?.value || indexTypeOptions[0].value;
|
||||
}
|
||||
return indexTypeOptions[0].value;
|
||||
}
|
||||
|
||||
let isUnique = constraintInfo?.isUnique;
|
||||
let indexTypeValue = getIndexTypeValue(constraintInfo, driver?.dialect?.indexTypes);
|
||||
|
||||
function getExtractConstraintProps() {
|
||||
const indexTypeOptions = driver?.dialect?.indexTypes;
|
||||
if (indexTypeOptions?.length) {
|
||||
const selected = indexTypeOptions.find(option => option.value === indexTypeValue) || indexTypeOptions[0];
|
||||
let nextIndexType = selected?.indexType;
|
||||
if (selected?.isUnique) {
|
||||
nextIndexType = undefined;
|
||||
} else if (!nextIndexType) {
|
||||
const currentIndexType = constraintInfo?.indexType?.toString()?.toUpperCase();
|
||||
if (currentIndexType && currentIndexType !== 'FULLTEXT') {
|
||||
nextIndexType = constraintInfo?.indexType;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isUnique: !!selected?.isUnique,
|
||||
indexType: nextIndexType,
|
||||
filterDefinition,
|
||||
};
|
||||
}
|
||||
return {
|
||||
isUnique,
|
||||
filterDefinition,
|
||||
@@ -24,6 +56,10 @@
|
||||
let filterDefinition = constraintInfo?.filterDefinition;
|
||||
|
||||
$: isReadOnly = !setTableInfo;
|
||||
$: indexTypeOptions = driver?.dialect?.indexTypes;
|
||||
$: if (!indexTypeValue && indexTypeOptions?.length) {
|
||||
indexTypeValue = getIndexTypeValue(constraintInfo, indexTypeOptions);
|
||||
}
|
||||
</script>
|
||||
|
||||
<ColumnsConstraintEditorModal
|
||||
@@ -61,9 +97,29 @@
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="constraintProps">
|
||||
<div class="largeFormMarker">
|
||||
<div class="row">
|
||||
<CheckboxField checked={isUnique} on:change={e => (isUnique = e.target.checked)} disabled={isReadOnly} /> {_t('indexEditor.isUnique', { defaultMessage: 'Is unique index' })}
|
||||
</div>
|
||||
{#if indexTypeOptions?.length}
|
||||
<div class="row">
|
||||
<div class="label col-3">{_t('indexEditor.indexType', { defaultMessage: 'Index type' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={indexTypeValue}
|
||||
isNative
|
||||
disabled={isReadOnly}
|
||||
options={indexTypeOptions.map(option => ({
|
||||
label: option.label,
|
||||
value: option.value,
|
||||
}))}
|
||||
on:change={e => {
|
||||
if (e.detail) indexTypeValue = e.detail;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="row">
|
||||
<CheckboxField checked={isUnique} on:change={e => (isUnique = e.target.checked)} disabled={isReadOnly} /> {_t('indexEditor.isUnique', { defaultMessage: 'Is unique index' })}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="largeFormMarker">
|
||||
|
||||
@@ -154,6 +154,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
function getIndexTypeLabel(row) {
|
||||
const indexType = row?.indexType?.toString()?.toUpperCase();
|
||||
if (indexType === 'FULLTEXT') return 'FULLTEXT';
|
||||
if (row?.isUnique) return 'UNIQUE';
|
||||
if (indexType) return indexType;
|
||||
return 'INDEX';
|
||||
}
|
||||
|
||||
$: columns = tableInfo?.columns;
|
||||
$: foreignKeys = tableInfo?.foreignKeys;
|
||||
$: dependencies = tableInfo?.dependencies;
|
||||
@@ -357,10 +365,9 @@
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
fieldName: 'unique',
|
||||
header: _t('tableEditor.unique', { defaultMessage: 'Unique' }),
|
||||
fieldName: 'indexType',
|
||||
header: _t('tableEditor.indexType', { defaultMessage: 'Type' }),
|
||||
slot: 1,
|
||||
sortable: true,
|
||||
},
|
||||
isWritable
|
||||
? {
|
||||
@@ -372,11 +379,7 @@
|
||||
>
|
||||
<svelte:fragment slot="name" let:row><ConstraintLabel {...row} /></svelte:fragment>
|
||||
<svelte:fragment slot="0" let:row>{row?.columns.map(x => x.columnName).join(', ')}</svelte:fragment>
|
||||
<svelte:fragment slot="1" let:row
|
||||
>{row?.isUnique
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="1" let:row>{getIndexTypeLabel(row)}</svelte:fragment>
|
||||
<svelte:fragment slot="2" let:row
|
||||
><Link
|
||||
onClick={e => {
|
||||
|
||||
@@ -100,6 +100,17 @@ class Dumper extends SqlDumper {
|
||||
this.put('^select ^last_insert_id()');
|
||||
}
|
||||
|
||||
indexType(ix) {
|
||||
if (ix.isUnique) {
|
||||
this.put(' ^unique');
|
||||
return;
|
||||
}
|
||||
if (ix.indexType?.toLowerCase() == 'fulltext') {
|
||||
this.put(' ^fulltext');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
callableTemplate(func) {
|
||||
const parameters = (func.parameters || []).filter(x => x.parameterMode != 'RETURN');
|
||||
|
||||
|
||||
@@ -88,6 +88,12 @@ const dialect = {
|
||||
'year',
|
||||
],
|
||||
|
||||
indexTypes: [
|
||||
{ value: 'normal', label: 'Normal' },
|
||||
{ value: 'unique', label: 'Unique', isUnique: true },
|
||||
{ value: 'fulltext', label: 'Fulltext', indexType: 'FULLTEXT' },
|
||||
],
|
||||
|
||||
createColumnViewExpression(columnName, dataType, source, alias) {
|
||||
if (dataType && spatialTypes.includes(dataType.toUpperCase())) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user