mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 04:56:00 +00:00
archive - handle model sql files
This commit is contained in:
@@ -38,12 +38,25 @@ module.exports = {
|
|||||||
const dir = path.join(archivedir(), folder);
|
const dir = path.join(archivedir(), folder);
|
||||||
if (!(await fs.exists(dir))) return [];
|
if (!(await fs.exists(dir))) return [];
|
||||||
const files = await fs.readdir(dir);
|
const files = await fs.readdir(dir);
|
||||||
return files
|
|
||||||
.filter(name => name.endsWith('.jsonl'))
|
function fileType(ext, type) {
|
||||||
.map(name => ({
|
return files
|
||||||
name: name.slice(0, -'.jsonl'.length),
|
.filter(name => name.endsWith(ext))
|
||||||
type: 'jsonl',
|
.map(name => ({
|
||||||
}));
|
name: name.slice(0, -ext.length),
|
||||||
|
type,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...fileType('.jsonl', 'jsonl'),
|
||||||
|
...fileType('.table.yaml', 'table.yaml'),
|
||||||
|
...fileType('.view.sql', 'view.sql'),
|
||||||
|
...fileType('.proc.sql', 'proc.sql'),
|
||||||
|
...fileType('.func.sql', 'func.sql'),
|
||||||
|
...fileType('.trigger.sql', 'trigger.sql'),
|
||||||
|
...fileType('.matview.sql', 'matview.sql'),
|
||||||
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
refreshFiles_meta: 'post',
|
refreshFiles_meta: 'post',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { filesdir } = require('../utility/directories');
|
const { filesdir, archivedir } = require('../utility/directories');
|
||||||
const hasPermission = require('../utility/hasPermission');
|
const hasPermission = require('../utility/hasPermission');
|
||||||
const socket = require('../utility/socket');
|
const socket = require('../utility/socket');
|
||||||
const scheduler = require('./scheduler');
|
const scheduler = require('./scheduler');
|
||||||
@@ -58,23 +58,36 @@ module.exports = {
|
|||||||
|
|
||||||
load_meta: 'post',
|
load_meta: 'post',
|
||||||
async load({ folder, file, format }) {
|
async load({ folder, file, format }) {
|
||||||
if (!hasPermission(`files/${folder}/read`)) return null;
|
if (folder.startsWith('archive:')) {
|
||||||
const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
|
const text = await fs.readFile(path.join(archivedir(), folder.substring('archive:'.length), file), {
|
||||||
return deserialize(format, text);
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
return deserialize(format, text);
|
||||||
|
} else {
|
||||||
|
if (!hasPermission(`files/${folder}/read`)) return null;
|
||||||
|
const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
|
||||||
|
return deserialize(format, text);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
save_meta: 'post',
|
save_meta: 'post',
|
||||||
async save({ folder, file, data, format }) {
|
async save({ folder, file, data, format }) {
|
||||||
if (!hasPermission(`files/${folder}/write`)) return;
|
if (folder.startsWith('archive:')) {
|
||||||
const dir = path.join(filesdir(), folder);
|
const dir = path.join(archivedir(), folder.substring('archive:'.length));
|
||||||
if (!(await fs.exists(dir))) {
|
await fs.writeFile(path.join(dir, file), serialize(format, data));
|
||||||
await fs.mkdir(dir);
|
socket.emitChanged(`archive-files-changed-${folder.substring('archive:'.length)}`);
|
||||||
}
|
} else {
|
||||||
await fs.writeFile(path.join(dir, file), serialize(format, data));
|
if (!hasPermission(`files/${folder}/write`)) return;
|
||||||
socket.emitChanged(`files-changed-${folder}`);
|
const dir = path.join(filesdir(), folder);
|
||||||
socket.emitChanged(`all-files-changed`);
|
if (!(await fs.exists(dir))) {
|
||||||
if (folder == 'shell') {
|
await fs.mkdir(dir);
|
||||||
scheduler.reload();
|
}
|
||||||
|
await fs.writeFile(path.join(dir, file), serialize(format, data));
|
||||||
|
socket.emitChanged(`files-changed-${folder}`);
|
||||||
|
socket.emitChanged(`all-files-changed`);
|
||||||
|
if (folder == 'shell') {
|
||||||
|
scheduler.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -12,23 +12,66 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function openSqlFile(fileName, fileType, folderName) {
|
||||||
|
const connProps: any = {};
|
||||||
|
let tooltip = undefined;
|
||||||
|
|
||||||
|
const connection = _.get(getCurrentDatabase(), 'connection') || {};
|
||||||
|
const database = _.get(getCurrentDatabase(), 'name');
|
||||||
|
connProps.conid = connection._id;
|
||||||
|
connProps.database = database;
|
||||||
|
tooltip = `${getConnectionLabel(connection)}\n${database}`;
|
||||||
|
const resp = await axiosInstance.post('files/load', {
|
||||||
|
folder: 'archive:' + folderName,
|
||||||
|
file: fileName + '.' + fileType,
|
||||||
|
format: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
openNewTab(
|
||||||
|
{
|
||||||
|
title: fileName,
|
||||||
|
icon: 'img sql-file',
|
||||||
|
tabComponent: 'QueryTab',
|
||||||
|
tooltip,
|
||||||
|
props: {
|
||||||
|
savedFile: fileName + '.' + fileType,
|
||||||
|
savedFolder: 'archive:' + folderName,
|
||||||
|
savedFormat: 'text',
|
||||||
|
...connProps,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ editor: resp.data }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const extractKey = data => data.fileName;
|
export const extractKey = data => data.fileName;
|
||||||
export const createMatcher = ({ fileName }) => filter => filterName(filter, fileName);
|
export const createMatcher = ({ fileName }) => filter => filterName(filter, fileName);
|
||||||
|
const ARCHIVE_ICONS = {
|
||||||
|
jsonl: 'img archive',
|
||||||
|
'table.yaml': 'img table',
|
||||||
|
'view.sql': 'img view',
|
||||||
|
'proce.sql': 'img procedure',
|
||||||
|
'func.sql': 'img function',
|
||||||
|
'trigger.sql': 'img sql-file',
|
||||||
|
'matview.sql': 'img view',
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import _ from 'lodash';
|
||||||
import { filterName } from 'dbgate-tools';
|
import { filterName } from 'dbgate-tools';
|
||||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
|
|
||||||
import { currentArchive, extensions } from '../stores';
|
import { currentArchive, extensions, getCurrentDatabase } from '../stores';
|
||||||
|
|
||||||
import axiosInstance from '../utility/axiosInstance';
|
import axiosInstance from '../utility/axiosInstance';
|
||||||
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||||
import { exportElectronFile } from '../utility/exportElectronFile';
|
import { exportElectronFile } from '../utility/exportElectronFile';
|
||||||
|
import { openSqliteFile } from '../utility/openElectronFile';
|
||||||
import openNewTab from '../utility/openNewTab';
|
import openNewTab from '../utility/openNewTab';
|
||||||
import AppObjectCore from './AppObjectCore.svelte';
|
import AppObjectCore from './AppObjectCore.svelte';
|
||||||
|
import getConnectionLabel from '../utility/getConnectionLabel';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
@@ -57,28 +100,33 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
openArchive(data.fileName, data.folderName);
|
if (data.fileType == 'jsonl') openArchive(data.fileName, data.folderName);
|
||||||
|
if (data.fileType.endsWith('.sql')) openSqlFile(data.fileName, data.fileType, data.folderName);
|
||||||
|
};
|
||||||
|
const handleOpenSqlFile = () => {
|
||||||
|
openSqlFile(data.fileName, data.fileType, data.folderName);
|
||||||
};
|
};
|
||||||
|
|
||||||
function createMenu() {
|
function createMenu() {
|
||||||
return [
|
return [
|
||||||
{ text: 'Open (readonly)', onClick: handleOpenRead },
|
data.fileType == 'jsonl' && { text: 'Open (readonly)', onClick: handleOpenRead },
|
||||||
{ text: 'Open in free table editor', onClick: handleOpenWrite },
|
data.fileType == 'jsonl' && { text: 'Open in free table editor', onClick: handleOpenWrite },
|
||||||
{ text: 'Delete', onClick: handleDelete },
|
{ text: 'Delete', onClick: handleDelete },
|
||||||
createQuickExportMenu($extensions, fmt => async () => {
|
data.fileType == 'jsonl' &&
|
||||||
exportElectronFile(
|
createQuickExportMenu($extensions, fmt => async () => {
|
||||||
data.fileName,
|
exportElectronFile(
|
||||||
{
|
data.fileName,
|
||||||
functionName: 'archiveReader',
|
{
|
||||||
props: {
|
functionName: 'archiveReader',
|
||||||
fileName: data.fileName,
|
props: {
|
||||||
folderName: data.folderName,
|
fileName: data.fileName,
|
||||||
|
folderName: data.folderName,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
fmt
|
||||||
fmt
|
);
|
||||||
);
|
}),
|
||||||
}),
|
data.fileType == 'jsonl' && {
|
||||||
{
|
|
||||||
text: 'Export',
|
text: 'Export',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
showModal(ImportExportModal, {
|
showModal(ImportExportModal, {
|
||||||
@@ -90,16 +138,16 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AppObjectCore
|
<AppObjectCore
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
{data}
|
{data}
|
||||||
title={data.fileName}
|
title={data.fileName}
|
||||||
icon="img archive"
|
icon={ARCHIVE_ICONS[data.fileType]}
|
||||||
menu={createMenu}
|
menu={createMenu}
|
||||||
on:click={handleClick}
|
on:click={handleClick}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ export default function saveTabFile(editor, saveAs, folder, format, fileExtensio
|
|||||||
const tabs = get(openedTabs);
|
const tabs = get(openedTabs);
|
||||||
const tabid = editor.activator.tabid;
|
const tabid = editor.activator.tabid;
|
||||||
const data = editor.getData();
|
const data = editor.getData();
|
||||||
const { savedFile, savedFilePath } = tabs.find(x => x.tabid == tabid).props || {};
|
const { savedFile, savedFilePath, savedFolder } = tabs.find(x => x.tabid == tabid).props || {};
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (savedFile) {
|
if (savedFile) {
|
||||||
await axiosInstance.post('files/save', { folder, file: savedFile, data, format });
|
await axiosInstance.post('files/save', { folder: savedFolder || folder, file: savedFile, data, format });
|
||||||
}
|
}
|
||||||
if (savedFilePath) {
|
if (savedFilePath) {
|
||||||
await axiosInstance.post('files/save-as', { filePath: savedFilePath, data, format });
|
await axiosInstance.post('files/save-as', { filePath: savedFilePath, data, format });
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
const ARCHIVE_LABELS = {
|
||||||
|
jsonl: 'JSON table data',
|
||||||
|
'table.yaml': 'Tables',
|
||||||
|
'view.sql': 'Views',
|
||||||
|
'proce.sql': 'Procedures',
|
||||||
|
'func.sql': 'Functions',
|
||||||
|
'trigger.sql': 'Triggers',
|
||||||
|
'matview.sql': 'Materialized views',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
@@ -32,7 +44,9 @@
|
|||||||
list={($files || []).map(file => ({
|
list={($files || []).map(file => ({
|
||||||
fileName: file.name,
|
fileName: file.name,
|
||||||
folderName: folder,
|
folderName: folder,
|
||||||
|
fileType: file.type,
|
||||||
}))}
|
}))}
|
||||||
|
groupFunc={data => ARCHIVE_LABELS[data.fileType] || 'Archive'}
|
||||||
module={archiveFileAppObject}
|
module={archiveFileAppObject}
|
||||||
{filter}
|
{filter}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user