|
|
|
<template>
|
|
|
|
<div>
|
|
|
|
<div class="row py-1 q-col-gutter-sm">
|
|
|
|
<div class="col-2">
|
|
|
|
<q-select
|
|
|
|
v-model="valueReactive.datasource"
|
|
|
|
:label="$t('developer.backend.export.liquibase.datasource')"
|
|
|
|
outlined
|
|
|
|
dense
|
|
|
|
emit-value
|
|
|
|
map-options
|
|
|
|
:options="datasourceOptionsRef"
|
|
|
|
@update:model-value="
|
|
|
|
(value) => {
|
|
|
|
datasourceChanged(value);
|
|
|
|
}
|
|
|
|
"
|
|
|
|
></q-select>
|
|
|
|
</div>
|
|
|
|
<div class="col-2">
|
|
|
|
<q-select
|
|
|
|
v-model="valueReactive.schema"
|
|
|
|
:label="$t('developer.backend.export.liquibase.schema')"
|
|
|
|
outlined
|
|
|
|
dense
|
|
|
|
emit-value
|
|
|
|
map-options
|
|
|
|
:options="schemaOptionsRef"
|
|
|
|
@update:model-value="
|
|
|
|
(value) => {
|
|
|
|
schemaChanged(valueReactive.datasource, value);
|
|
|
|
}
|
|
|
|
"
|
|
|
|
></q-select>
|
|
|
|
</div>
|
|
|
|
<div class="col-8">
|
|
|
|
<q-select
|
|
|
|
v-model="valueReactive.tables"
|
|
|
|
:label="$t('developer.backend.export.liquibase.tables')"
|
|
|
|
outlined
|
|
|
|
dense
|
|
|
|
emit-value
|
|
|
|
map-options
|
|
|
|
multiple
|
|
|
|
use-chips
|
|
|
|
:options="tablesOptionsRef"
|
|
|
|
@update:model-value="
|
|
|
|
(value) => {
|
|
|
|
if (value) {
|
|
|
|
if (value.length > 1) {
|
|
|
|
valueReactive.sql = 'select * from ${table}';
|
|
|
|
} else {
|
|
|
|
valueReactive.sql = 'select * from ' + value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<template #append>
|
|
|
|
<q-btn
|
|
|
|
:title="$t('selectAll')"
|
|
|
|
icon="bi-check-square"
|
|
|
|
flat
|
|
|
|
dense
|
|
|
|
:disable="!(tablesOptionsRef?.length > 0)"
|
|
|
|
@click.stop.prevent="
|
|
|
|
() => {
|
|
|
|
const selecteds = [];
|
|
|
|
if (tablesOptionsRef) {
|
|
|
|
for (const table of tablesOptionsRef) {
|
|
|
|
selecteds.push(table.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
valueReactive.tables = selecteds;
|
|
|
|
}
|
|
|
|
"
|
|
|
|
/>
|
|
|
|
<q-btn
|
|
|
|
:title="$t('unSelectAll')"
|
|
|
|
icon="bi-square"
|
|
|
|
flat
|
|
|
|
dense
|
|
|
|
:disable="!(tablesOptionsRef?.length > 0)"
|
|
|
|
@click.stop.prevent="
|
|
|
|
() => {
|
|
|
|
valueReactive.tables = [];
|
|
|
|
}
|
|
|
|
"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
</q-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row py-1 q-col-gutter-sm">
|
|
|
|
<div class="col-12">
|
|
|
|
<w-code-mirror v-model="valueReactive.sql" label="SQL" :rows="5" lang="sql"></w-code-mirror>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="row justify-center q-gutter-md py-2">
|
|
|
|
<w-progress-btn
|
|
|
|
ref="progressBtnRef"
|
|
|
|
icon="bi-database-down"
|
|
|
|
:label="$t('export')"
|
|
|
|
data-url="/api/jdbc/data/traceExporterExecuteProgress"
|
|
|
|
@click="exportData"
|
|
|
|
@success="
|
|
|
|
(progressInfo) => {
|
|
|
|
Downloader.get(Environment.apiContextPath('/api/mvc/download?filePath=' + encodeURIComponent(progressInfo.result)));
|
|
|
|
}
|
|
|
|
"
|
|
|
|
></w-progress-btn>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { ref, reactive, onMounted, onUpdated } from 'vue';
|
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import { axios, Environment, DialogManager, Downloader } from 'platform-core';
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
|
const progressBtnRef = ref();
|
|
|
|
const datasourceOptionsRef = ref([]);
|
|
|
|
const schemaOptionsRef = ref([]);
|
|
|
|
const tablesOptionsRef = ref([]);
|
|
|
|
|
|
|
|
const valueReactive = reactive({
|
|
|
|
datasource: undefined,
|
|
|
|
schema: undefined,
|
|
|
|
tables: undefined,
|
|
|
|
sql: undefined,
|
|
|
|
});
|
|
|
|
|
|
|
|
const loadDatasource = () => {
|
|
|
|
axios.get(Environment.apiContextPath('/api/system/datasource?pageable=false&sortBy=name')).then((response) => {
|
|
|
|
const data = response?.data.content;
|
|
|
|
const datasourceOptions = [];
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
for (let item of data) {
|
|
|
|
datasourceOptions.push({ label: item.name, value: item.name });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
datasourceOptionsRef.value = datasourceOptions;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const datasourceChanged = (datasource: string) => {
|
|
|
|
datasource = datasource || '';
|
|
|
|
axios.get(Environment.apiContextPath('/api/jdbc/metadata/getSchemas?datasource=' + datasource)).then((response) => {
|
|
|
|
const data = response?.data;
|
|
|
|
const schemaOptions = [];
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
for (let item of data) {
|
|
|
|
schemaOptions.push({ label: item.name, value: item.name });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
schemaOptionsRef.value = schemaOptions;
|
|
|
|
tablesOptionsRef.value = [];
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const schemaChanged = (datasource: string, schema: string) => {
|
|
|
|
datasource = datasource || '';
|
|
|
|
schema = schema || '';
|
|
|
|
axios.get(Environment.apiContextPath('/api/jdbc/metadata/getTables?datasource=' + datasource + '&schema=' + schema)).then((response) => {
|
|
|
|
const data = response?.data;
|
|
|
|
const tablesOptions = [];
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
for (let item of data) {
|
|
|
|
tablesOptions.push({ label: item.name, value: item.name });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tablesOptionsRef.value = tablesOptions;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const exportData = (e) => {
|
|
|
|
DialogManager.confirm(t('developer.backend.export.liquibase.export.tip'), () => {
|
|
|
|
const data = valueReactive;
|
|
|
|
const config = {
|
|
|
|
datasource: data.datasource,
|
|
|
|
schema: data.schema,
|
|
|
|
tables: [],
|
|
|
|
};
|
|
|
|
const length = data.tables.length;
|
|
|
|
const sql = length === 1 ? data.sql : '';
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
|
config.tables[i] = { name: data.tables[i], sql: sql ? sql : 'select * from ' + data.tables[i] };
|
|
|
|
}
|
|
|
|
axios.post(Environment.apiContextPath('/api/jdbc/data/exportData'), config).then((response) => {
|
|
|
|
progressBtnRef.value.start();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
loadDatasource();
|
|
|
|
datasourceChanged('');
|
|
|
|
});
|
|
|
|
</script>
|