archive - handle model sql files

This commit is contained in:
Jan Prochazka
2021-09-30 10:30:35 +02:00
parent 0be07ba093
commit c2feedac20
5 changed files with 130 additions and 42 deletions

View File

@@ -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);
function fileType(ext, type) {
return files return files
.filter(name => name.endsWith('.jsonl')) .filter(name => name.endsWith(ext))
.map(name => ({ .map(name => ({
name: name.slice(0, -'.jsonl'.length), name: name.slice(0, -ext.length),
type: 'jsonl', 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',

View File

@@ -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,13 +58,25 @@ module.exports = {
load_meta: 'post', load_meta: 'post',
async load({ folder, file, format }) { async load({ folder, file, format }) {
if (folder.startsWith('archive:')) {
const text = await fs.readFile(path.join(archivedir(), folder.substring('archive:'.length), file), {
encoding: 'utf-8',
});
return deserialize(format, text);
} else {
if (!hasPermission(`files/${folder}/read`)) return null; if (!hasPermission(`files/${folder}/read`)) return null;
const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' }); const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
return deserialize(format, text); return deserialize(format, text);
}
}, },
save_meta: 'post', save_meta: 'post',
async save({ folder, file, data, format }) { async save({ folder, file, data, format }) {
if (folder.startsWith('archive:')) {
const dir = path.join(archivedir(), folder.substring('archive:'.length));
await fs.writeFile(path.join(dir, file), serialize(format, data));
socket.emitChanged(`archive-files-changed-${folder.substring('archive:'.length)}`);
} else {
if (!hasPermission(`files/${folder}/write`)) return; if (!hasPermission(`files/${folder}/write`)) return;
const dir = path.join(filesdir(), folder); const dir = path.join(filesdir(), folder);
if (!(await fs.exists(dir))) { if (!(await fs.exists(dir))) {
@@ -76,6 +88,7 @@ module.exports = {
if (folder == 'shell') { if (folder == 'shell') {
scheduler.reload(); scheduler.reload();
} }
}
}, },
saveAs_meta: 'post', saveAs_meta: 'post',

View File

@@ -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,14 +100,19 @@
}); });
}; };
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 },
data.fileType == 'jsonl' &&
createQuickExportMenu($extensions, fmt => async () => { createQuickExportMenu($extensions, fmt => async () => {
exportElectronFile( exportElectronFile(
data.fileName, data.fileName,
@@ -78,7 +126,7 @@
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}
/> />

View File

@@ -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 });

View File

@@ -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}
/> />