1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-01-18 13:07:58 +00:00

dump/export (wip)

This commit is contained in:
Romein van Buren 2023-01-28 13:25:14 +01:00
parent 634a655b5f
commit 2d33c6f2ab
Signed by: romein
GPG Key ID: 0EFF8478ADDF6C49
11 changed files with 248 additions and 16 deletions

View File

@ -13,6 +13,7 @@
export let level = 0;
export let striped = true;
export let hideObjectIndicators = false;
export let hideChildrenToggles = false;
const dispatch = createEventDispatcher();
let childrenOpen = {};
@ -105,17 +106,19 @@
class:selected={!activePath[level + 1] && activePath.every(k => path.includes(k) || k === item[key]) && (activePath[level] === item[key])}
class:striped
>
<td class="has-toggle">
{#if item.children?.length}
<button
class="toggle"
on:click={evt => toggleChildren(item[key], evt.shiftKey)}
style:transform="translateX({level * 10}px)"
>
<Icon name={childrenOpen[item[key]] ? 'chev-d' : 'chev-r'} />
</button>
{/if}
</td>
{#if !hideChildrenToggles}
<td class="has-toggle">
{#if item.children?.length}
<button
class="toggle"
on:click={evt => toggleChildren(item[key], evt.shiftKey)}
style:transform="translateX({level * 10}px)"
>
<Icon name={childrenOpen[item[key]] ? 'chev-d' : 'chev-r'} />
</button>
{/if}
</td>
{/if}
<td class="has-icon">
<div style:margin-left="{level * 10}px">

View File

@ -8,8 +8,9 @@
export let key = 'id';
export let activePath = [];
export let striped = true;
export let hideObjectIndicators = false;
export let showHeaders = false;
export let hideObjectIndicators = false;
export let hideChildrenToggles = false;
</script>
<div class="grid">
@ -28,8 +29,12 @@
{#if showHeaders && columns.some(col => col.title)}
<thead>
<tr>
<th class="has-toggle"></th>
{#if !hideChildrenToggles}
<th class="has-toggle"></th>
{/if}
<th class="has-icon"></th>
{#each columns as column}
<th scope="col">{column.title || ''}</th>
{/each}
@ -44,6 +49,7 @@
{key}
{striped}
{hideObjectIndicators}
{hideChildrenToggles}
bind:activePath
on:select
on:trigger

View File

@ -0,0 +1,129 @@
<script>
import { busy, connections } from '../../../stores';
import Grid from '../../../components/grid.svelte';
import Modal from '../../../components/modal.svelte';
import { OpenConnection, OpenDatabase } from '../../../../wailsjs/go/app/App';
export let info;
export let hosts = {};
$: console.log(info);
async function selectHost(hostKey) {
info.hostKey = hostKey;
info.dbKey = undefined;
info.collKeys = [];
if (hostKey) {
busy.start();
const databases = await OpenConnection(hostKey);
if (databases && !$connections[hostKey]) {
$connections[hostKey] = { databases: {} };
databases.sort().forEach(dbKey => {
$connections[hostKey].databases[dbKey] = $connections[hostKey].databases[dbKey] || { collections: {} };
});
}
busy.end();
}
}
async function selectDatabase(dbKey) {
info.collKeys = [];
info.dbKey = dbKey;
if (dbKey) {
busy.start();
const collections = await OpenDatabase(info.hostKey, dbKey);
for (const collKey of collections?.sort() || []) {
$connections[info.hostKey].databases[dbKey].collections[collKey] = {};
}
busy.end();
}
}
function selectCollection(collKey) {
info.collKeys = [ collKey ];
}
</script>
<Modal bind:show={info} title="Dump database data">
<div class="info">
<div class="meta">
<label class="field">
<span class="label">Output filename</span>
<input type="text">
</label>
</div>
<div class="location">
<div class="grid">
<Grid
key="id"
columns={[ { title: 'Host', key: 'name' } ]}
activePath={info ? [ info.hostKey ] : []}
showHeaders
hideChildrenToggles
items={[
{ id: undefined, name: '(localhost)' },
...Object.keys(hosts).map(id => ({ id, name: hosts[id]?.name })),
]}
on:select={e => selectHost(e.detail?.itemKey)}
/>
</div>
<div class="grid">
<Grid
key="id"
columns={[ { title: 'Database', key: 'name' } ]}
activePath={info ? [ info.dbKey ] : []}
showHeaders
hideChildrenToggles
items={[
{ id: undefined, name: '(all databases)' },
...($connections[info.hostKey]?.databases
? Object.keys($connections[info.hostKey].databases).map(id => ({ id, name: id }))
: []
),
]}
on:select={e => selectDatabase(e.detail?.itemKey)}
/>
</div>
<div class="grid">
<Grid
key="id"
columns={[ { title: 'Collection', key: 'name' } ]}
activePath={info?.collKeys ? [ info.collKeys[0] ] : []}
showHeaders
hideChildrenToggles
items={[
{ id: undefined, name: '(all collections)' },
...($connections[info.hostKey]?.databases[info.dbKey]?.collections
? Object.keys($connections[info.hostKey].databases[info.dbKey].collections).map(id => ({ id, name: id }))
: []
),
]}
on:select={e => selectCollection(e.detail?.itemKey)}
/>
</div>
</div>
</div>
</Modal>
<style>
.info {
display: grid;
grid-template: auto / 1fr;
}
.location {
display: grid;
grid-template: 1fr / repeat(3, 1fr);
gap: 1rem;
}
.location .grid {
border: 1px solid #ccc;
padding: 0.3rem;
overflow-y: auto;
}
</style>

View File

@ -0,0 +1,3 @@
<script>
export let info;
</script>

View File

@ -101,6 +101,9 @@
name: collKey,
icon: 'list',
menu: [
{ label: 'Export collection (JSON/CSV, mongoexport)…', fn: () => dispatch('exportCollection', collKey) },
{ label: 'Dump collection (BSON, mongodump)…', fn: () => dispatch('dumpCollection', collKey) },
{ separator: true },
{ label: 'Rename collection…', fn: () => dispatch('renameCollection', collKey) },
{ label: 'Truncate collection…', fn: () => truncateCollection(dbKey, collKey) },
{ label: 'Drop collection…', fn: () => dropCollection(dbKey, collKey) },

View File

@ -9,6 +9,8 @@
import HostDetail from './hostdetail.svelte';
import Icon from '../../components/icon.svelte';
import { EventsOn } from '../../../wailsjs/runtime/runtime';
import ExportInfo from './export/exportinfo.svelte';
import DumpInfo from './export/dumpinfo.svelte';
export let hosts = {};
export let activeHostKey = '';
@ -25,6 +27,9 @@
let collToRename = '';
let newCollKey = '';
let exportInfo;
let dumpInfo;
async function getHosts() {
hosts = await Hosts();
}
@ -54,7 +59,6 @@
async function renameCollection() {
busy.start();
console.log(newCollKey);
const ok = await RenameCollection(activeHostKey, activeDbKey, collToRename, newCollKey);
if (ok) {
activeCollKey = newCollKey;
@ -73,6 +77,22 @@
busy.end();
}
function exportCollection(collKey) {
exportInfo = {
hostKey: activeHostKey,
dbKey: activeDbKey,
collKeys: [ collKey ],
};
}
function dumpCollection(collKey) {
dumpInfo = {
hostKey: activeHostKey,
dbKey: activeDbKey,
collKeys: [ collKey ],
};
}
EventsOn('CreateHost', createHost);
EventsOn('CreateDatabase', () => newDb = {});
EventsOn('CreateCollection', () => newColl = {});
@ -91,6 +111,8 @@
on:newCollection={() => newColl = {}}
on:editHost={e => editHost(e.detail)}
on:renameCollection={e => openEditCollModal(e.detail)}
on:exportCollection={e => exportCollection(e.detail)}
on:dumpCollection={e => dumpCollection(e.detail)}
/>
</div>
@ -108,6 +130,9 @@
{hosts}
/>
<ExportInfo bind:info={exportInfo} {hosts} />
<DumpInfo bind:info={dumpInfo} {hosts} />
{#if newDb}
<Modal bind:show={newDb}>
<p><strong>Create a database</strong></p>

View File

@ -1,6 +1,5 @@
import { writable } from 'svelte/store';
import { Environment } from '../wailsjs/runtime/runtime';
import { Settings, UpdateSettings, UpdateViewStore, Views } from '../wailsjs/go/app/App';
import { Environment, Settings, UpdateSettings, UpdateViewStore, Views } from '../wailsjs/go/app/App';
export const busy = (() => {
const { update, subscribe } = writable(0);
@ -57,6 +56,7 @@ export const environment = (() => {
const reload = async() => {
const newEnv = await Environment();
set(newEnv);
console.log(newEnv);
return newEnv;
};

View File

@ -15,6 +15,8 @@ export function DropDatabase(arg1:string,arg2:string):Promise<boolean>;
export function DropIndex(arg1:string,arg2:string,arg3:string,arg4:string):Promise<boolean>;
export function Environment():Promise<app.EnvironmentInfo>;
export function FindItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise<app.findResult>;
export function GetIndexes(arg1:string,arg2:string,arg3:string):Promise<Array<primitive.M>>;

View File

@ -22,6 +22,10 @@ export function DropIndex(arg1, arg2, arg3, arg4) {
return window['go']['app']['App']['DropIndex'](arg1, arg2, arg3, arg4);
}
export function Environment() {
return window['go']['app']['App']['Environment']();
}
export function FindItems(arg1, arg2, arg3, arg4) {
return window['go']['app']['App']['FindItems'](arg1, arg2, arg3, arg4);
}

View File

@ -1,5 +1,25 @@
export namespace app {
export class EnvironmentInfo {
arch: string;
buildType: string;
platform: string;
hasMongoExport: boolean;
hasMongoDump: boolean;
static createFrom(source: any = {}) {
return new EnvironmentInfo(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.arch = source["arch"];
this.buildType = source["buildType"];
this.platform = source["platform"];
this.hasMongoExport = source["hasMongoExport"];
this.hasMongoDump = source["hasMongoDump"];
}
}
export class Settings {
defaultLimit: number;
defaultSort: string;

View File

@ -0,0 +1,37 @@
package app
import (
"os/exec"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
type EnvironmentInfo struct {
Arch string `json:"arch"`
BuildType string `json:"buildType"`
Platform string `json:"platform"`
HasMongoExport bool `json:"hasMongoExport"`
HasMongoDump bool `json:"hasMongoDump"`
}
var env EnvironmentInfo
var envKnown = false
func (a *App) Environment() EnvironmentInfo {
if !envKnown {
wailsEnv := runtime.Environment(a.ctx)
env.Arch = wailsEnv.Arch
env.BuildType = wailsEnv.BuildType
env.Platform = wailsEnv.Platform
_, err := exec.LookPath("mongodump")
env.HasMongoDump = err == nil
_, err = exec.LookPath("mongoexport")
env.HasMongoExport = err == nil
envKnown = true
}
return env
}