diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d89914..a26ae38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added meaningful window titles, and actually show these in the title bar (macOS). * Corrected link to documentation in the about box (#30). * Fixed host/database selection bug in grid (#31, #32), involving a frontend refactoring. +* Replaced (some) harsh loading dialogs with smooth spinners, and replaced (some) capricious error dialogs with friendly error messages. ## [v0.2.0] diff --git a/frontend/src/components/blankstate.svelte b/frontend/src/components/blankstate.svelte index 8f00f45..d4463ce 100644 --- a/frontend/src/components/blankstate.svelte +++ b/frontend/src/components/blankstate.svelte @@ -1,14 +1,25 @@
- + {#if icon} + + {:else if image} + + {/if} + +

{title}

{label}

+
@@ -27,12 +38,20 @@ height: 150px; width: auto; } + .content :global(svg) { + height: 40px; + width: auto; + } p { margin: 2.85rem 0; font-size: 1.25rem; line-height: 1.25rem; } + p.title { + font-weight: 700; + margin-bottom: -1.85rem; + } .blankstate :global(.btn) { font-size: 1.35rem; @@ -48,7 +67,7 @@ filter: grayscale(1); opacity: 0.4; } - .pale p { + .pale { color: #777; } diff --git a/frontend/src/components/grid.svelte b/frontend/src/components/grid.svelte index 7d3d9a4..879e6bb 100644 --- a/frontend/src/components/grid.svelte +++ b/frontend/src/components/grid.svelte @@ -1,4 +1,5 @@
@@ -27,45 +30,51 @@
{/if} --> - - {#if showHeaders && columns.some(col => col.title)} - - - {#if !hideChildrenToggles} - - {/if} + {#if busy} + + {:else if errorTitle || errorDescription} + + {:else} +
+ {#if showHeaders && columns.some(col => col.title)} + + + {#if !hideChildrenToggles} + + {/if} - + - {#each columns as column} - - {/each} + {#each columns as column} + + {/each} - {#if canRemoveItems} - - {/if} - - - {/if} + {#if canRemoveItems} + + {/if} + + + {/if} - - - -
{column.title || ''}{column.title || ''}
+ + + + + {/if} diff --git a/frontend/src/components/icon.svelte b/frontend/src/components/icon.svelte index 3a3e742..5a024b0 100644 --- a/frontend/src/components/icon.svelte +++ b/frontend/src/components/icon.svelte @@ -14,9 +14,19 @@ width: auto; vertical-align: bottom; } + + @keyframes spinning { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + svg.spinning { + animation: spinning 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + } - + stroke-linejoin="round" + class:spinning={name === 'loading'} +> {#if name === 'radio'} {:else if name === 'chev-l'} @@ -126,5 +138,9 @@ {:else if name === '?'} + {:else if name === '!'} + + {:else if name === 'loading'} + {/if} diff --git a/frontend/src/components/objectgrid.svelte b/frontend/src/components/objectgrid.svelte index ea681a4..288463f 100644 --- a/frontend/src/components/objectgrid.svelte +++ b/frontend/src/components/objectgrid.svelte @@ -8,6 +8,9 @@ export let activePath = []; export let hideObjectIndicators = false; export let getRootMenu = () => undefined; + export let errorTitle = ''; + export let errorDescription = ''; + export let busy = false; const columns = [ { key: 'key', label: 'Key' }, @@ -116,4 +119,7 @@ {columns} {items} {hideObjectIndicators} + {errorTitle} + {errorDescription} + {busy} /> diff --git a/frontend/src/dialogs/input.svelte b/frontend/src/dialogs/input.svelte index b6f75d2..2cb990c 100644 --- a/frontend/src/dialogs/input.svelte +++ b/frontend/src/dialogs/input.svelte @@ -36,3 +36,9 @@ + + diff --git a/frontend/src/lib/stores/hosttree.js b/frontend/src/lib/stores/hosttree.js index adc8ea1..c5c08d1 100644 --- a/frontend/src/lib/stores/hosttree.js +++ b/frontend/src/lib/stores/hosttree.js @@ -44,10 +44,11 @@ async function refresh() { host.uri = hostDetails.uri; host.open = async function() { - const progress = startProgress(`Connecting to "${hostKey}"…`); - const { databases: dbNames, status, systemInfo } = await OpenConnection(hostKey); + const { databases: dbNames, status, statusError, systemInfo, systemInfoError } = await OpenConnection(hostKey); host.status = status; + host.statusError = statusError; host.systemInfo = systemInfo; + host.systemInfoError = systemInfoError; host.databases = host.databases || {}; if (!dbNames) { @@ -71,9 +72,9 @@ async function refresh() { delete database.new; database.open = async function() { - const progress = startProgress(`Opening database "${dbKey}"…`); - const { collections: collNames, stats } = await OpenDatabase(hostKey, dbKey); + const { collections: collNames, stats, statsError } = await OpenDatabase(hostKey, dbKey); database.stats = stats; + database.statsError = statsError; if (!collNames) { return; @@ -97,11 +98,12 @@ async function refresh() { delete collection.new; collection.open = async function() { - const progress = startProgress(`Opening database "${dbKey}"…`); - const stats = await OpenCollection(hostKey, dbKey, collKey); + const { stats, statsError } = await OpenCollection(hostKey, dbKey, collKey); + collection.stats = stats; + collection.statsError = statsError; + await refresh(); - progress.end(); }; collection.rename = async function() { @@ -168,7 +170,12 @@ async function refresh() { collection.getIndexes = async function() { const progress = startProgress(`Retrieving indexes of "${collKey}"…`); collection.indexes = []; - const indexes = await GetIndexes(hostKey, dbKey, collKey); + const { indexes, error } = await GetIndexes(hostKey, dbKey, collKey); + + if (error) { + progress.end(); + return error; + } for (const indexDetails of indexes) { const index = { @@ -190,7 +197,6 @@ async function refresh() { } progress.end(); - return collection.indexes; }; collection.getIndexByName = function(indesName) { @@ -236,7 +242,6 @@ async function refresh() { } await refresh(); - progress.end(); windowTitle.setSegments(dbKey, host.name, 'Rolens'); }; @@ -283,7 +288,6 @@ async function refresh() { }; await refresh(); - progress.end(); }; host.remove = async function() { diff --git a/frontend/src/organisms/connection/collection/find.svelte b/frontend/src/organisms/connection/collection/find.svelte index 1da82fd..6d9de76 100644 --- a/frontend/src/organisms/connection/collection/find.svelte +++ b/frontend/src/organisms/connection/collection/find.svelte @@ -46,8 +46,7 @@ return; } - querying = true; - const progress = startProgress('Performing query…'); + querying = `Querying ${collection.key}…`; activePath = []; const newResult = await FindItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(form)); @@ -57,7 +56,6 @@ submittedForm = deepClone(form); } - progress.end(); resetFocus(); querying = false; } @@ -231,6 +229,9 @@ hideObjectIndicators={$views[collection.viewKey]?.hideObjectIndicators} bind:activePath on:trigger={e => openJson(e.detail?.index)} + errorTitle={result.errorTitle} + errorDescription={result.errorDescription} + busy={querying} /> {:else} EJSON.deserialize(r)) : []} bind:activePath on:trigger={e => openJson(e.detail?.index)} + errorTitle={result.errorTitle} + errorDescription={result.errorDescription} + busy={querying} /> {/if} {/key} diff --git a/frontend/src/organisms/connection/collection/indexes.svelte b/frontend/src/organisms/connection/collection/indexes.svelte index 18131d5..2aec5f8 100644 --- a/frontend/src/organisms/connection/collection/indexes.svelte +++ b/frontend/src/organisms/connection/collection/indexes.svelte @@ -7,18 +7,21 @@ let activePath = []; let _indexes = []; + let error = ''; async function refresh() { - await collection.getIndexes(); - _indexes = collection.indexes.map(idx => { - return { - name: idx.name, - background: idx.background || false, - unique: idx.unique || false, - sparse: idx.sparse || false, - model: idx.model, - }; - }); + error = await collection.getIndexes(); + if (!error) { + _indexes = collection.indexes.map(idx => { + return { + name: idx.name, + background: idx.background || false, + unique: idx.unique || false, + sparse: idx.sparse || false, + model: idx.model, + }; + }); + } } async function createIndex() { @@ -50,6 +53,8 @@ key="name" data={_indexes} getRootMenu={(_, idx) => [ { label: 'Drop this index', fn: () => dropIndex(idx.name) } ]} + errorTitle={error ? 'Error while getting indexes' : ''} + errorDescription={error} bind:activePath /> diff --git a/frontend/src/organisms/connection/collection/stats.svelte b/frontend/src/organisms/connection/collection/stats.svelte index 3bf8e83..36aaac9 100644 --- a/frontend/src/organisms/connection/collection/stats.svelte +++ b/frontend/src/organisms/connection/collection/stats.svelte @@ -18,11 +18,16 @@
- +
- diff --git a/frontend/src/organisms/connection/database/stats.svelte b/frontend/src/organisms/connection/database/stats.svelte index 032b7bd..8caaad3 100644 --- a/frontend/src/organisms/connection/database/stats.svelte +++ b/frontend/src/organisms/connection/database/stats.svelte @@ -18,11 +18,16 @@
- +
- diff --git a/frontend/src/organisms/connection/host/status.svelte b/frontend/src/organisms/connection/host/status.svelte index 033344b..b5af594 100644 --- a/frontend/src/organisms/connection/host/status.svelte +++ b/frontend/src/organisms/connection/host/status.svelte @@ -18,11 +18,16 @@
- +
- diff --git a/frontend/src/organisms/connection/host/systeminfo.svelte b/frontend/src/organisms/connection/host/systeminfo.svelte index d47c45b..3dac86f 100644 --- a/frontend/src/organisms/connection/host/systeminfo.svelte +++ b/frontend/src/organisms/connection/host/systeminfo.svelte @@ -18,11 +18,16 @@
- +
- diff --git a/frontend/wailsjs/go/app/App.d.ts b/frontend/wailsjs/go/app/App.d.ts index b035d38..9e3dd2c 100755 --- a/frontend/wailsjs/go/app/App.d.ts +++ b/frontend/wailsjs/go/app/App.d.ts @@ -1,7 +1,6 @@ // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT import {app} from '../models'; -import {primitive} from '../models'; import {map[string]app} from '../models'; import {menu} from '../models'; import {context} from '../models'; @@ -21,9 +20,9 @@ export function DropIndex(arg1:string,arg2:string,arg3:string,arg4:string):Promi export function Environment():Promise; -export function FindItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise; +export function FindItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise; -export function GetIndexes(arg1:string,arg2:string,arg3:string):Promise>; +export function GetIndexes(arg1:string,arg2:string,arg3:string):Promise; export function Hosts():Promise; @@ -31,11 +30,11 @@ export function InsertItems(arg1:string,arg2:string,arg3:string,arg4:string):Pro export function Menu():Promise; -export function OpenCollection(arg1:string,arg2:string,arg3:string):Promise; +export function OpenCollection(arg1:string,arg2:string,arg3:string):Promise; -export function OpenConnection(arg1:string):Promise; +export function OpenConnection(arg1:string):Promise; -export function OpenDatabase(arg1:string,arg2:string):Promise; +export function OpenDatabase(arg1:string,arg2:string):Promise; export function PerformDump(arg1:string):Promise; diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts deleted file mode 100755 index 679a460..0000000 --- a/frontend/wailsjs/go/models.ts +++ /dev/null @@ -1,97 +0,0 @@ -export namespace app { - - export class DatabaseInfo { - collections: string[]; - stats: {[key: string]: any}; - - static createFrom(source: any = {}) { - return new DatabaseInfo(source); - } - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.collections = source["collections"]; - this.stats = source["stats"]; - } - } - export class EnvironmentInfo { - arch: string; - buildType: string; - platform: string; - version: string; - hasMongoExport: boolean; - hasMongoDump: boolean; - homeDirectory: string; - dataDirectory: string; - logDirectory: string; - downloadDirectory: string; - - 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.version = source["version"]; - this.hasMongoExport = source["hasMongoExport"]; - this.hasMongoDump = source["hasMongoDump"]; - this.homeDirectory = source["homeDirectory"]; - this.dataDirectory = source["dataDirectory"]; - this.logDirectory = source["logDirectory"]; - this.downloadDirectory = source["downloadDirectory"]; - } - } - export class HostInfo { - databases: string[]; - status: {[key: string]: any}; - systemInfo: {[key: string]: any}; - - static createFrom(source: any = {}) { - return new HostInfo(source); - } - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.databases = source["databases"]; - this.status = source["status"]; - this.systemInfo = source["systemInfo"]; - } - } - export class QueryResult { - total: number; - results: string[]; - - static createFrom(source: any = {}) { - return new QueryResult(source); - } - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.total = source["total"]; - this.results = source["results"]; - } - } - export class Settings { - defaultLimit: number; - defaultSort: string; - autosubmitQuery: boolean; - defaultExportDirectory: string; - - static createFrom(source: any = {}) { - return new Settings(source); - } - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.defaultLimit = source["defaultLimit"]; - this.defaultSort = source["defaultSort"]; - this.autosubmitQuery = source["autosubmitQuery"]; - this.defaultExportDirectory = source["defaultExportDirectory"]; - } - } - -} - diff --git a/internal/app/collection.go b/internal/app/collection.go index b0c97fe..ae4180c 100644 --- a/internal/app/collection.go +++ b/internal/app/collection.go @@ -8,23 +8,27 @@ import ( "go.mongodb.org/mongo-driver/bson" ) -func (a *App) OpenCollection(hostKey, dbKey, collKey string) (result bson.M) { +type OpenCollectionResult struct { + Stats bson.M `json:"stats"` + StatsError string `json:"statsError"` +} + +func (a *App) OpenCollection(hostKey, dbKey, collKey string) (result OpenCollectionResult) { client, ctx, close, err := a.connectToHost(hostKey) if err != nil { - return nil + return } + defer close() command := bson.M{"collStats": collKey} - err = client.Database(dbKey).RunCommand(ctx, command).Decode(&result) + err = client.Database(dbKey).RunCommand(ctx, command).Decode(&result.Stats) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve collection stats for "+collKey) runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not get stats"), zenity.ErrorIcon) - return nil + result.StatsError = err.Error() } - defer close() - return result + return } func (a *App) RenameCollection(hostKey, dbKey, collKey, newCollKey string) bool { @@ -32,6 +36,7 @@ func (a *App) RenameCollection(hostKey, dbKey, collKey, newCollKey string) bool if err != nil { return false } + defer close() var result bson.M command := bson.D{ @@ -46,7 +51,6 @@ func (a *App) RenameCollection(hostKey, dbKey, collKey, newCollKey string) bool return false } - defer close() return true } @@ -60,6 +64,7 @@ func (a *App) TruncateCollection(hostKey, dbKey, collKey string) bool { if err != nil { return false } + defer close() _, err = client.Database(dbKey).Collection(collKey).DeleteMany(ctx, bson.D{}) if err != nil { @@ -69,7 +74,6 @@ func (a *App) TruncateCollection(hostKey, dbKey, collKey string) bool { return false } - defer close() return true } @@ -83,6 +87,7 @@ func (a *App) DropCollection(hostKey, dbKey, collKey string) bool { if err != nil { return false } + defer close() err = client.Database(dbKey).Collection(collKey).Drop(ctx) if err != nil { @@ -92,6 +97,5 @@ func (a *App) DropCollection(hostKey, dbKey, collKey string) bool { return false } - defer close() return true } diff --git a/internal/app/collection_find.go b/internal/app/collection_find.go index 4e441bd..f643983 100644 --- a/internal/app/collection_find.go +++ b/internal/app/collection_find.go @@ -17,13 +17,14 @@ type Query struct { Sort string `json:"sort"` } -type QueryResult struct { - Total int64 `json:"total"` - Results []string `json:"results"` +type FindItemsResult struct { + Total int64 `json:"total"` + Results []string `json:"results"` + ErrorTitle string `json:"errorTitle"` + ErrorDescription string `json:"errorDescription"` } -func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { - var out QueryResult +func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) (result FindItemsResult) { var form Query err := json.Unmarshal([]byte(formJson), &form) @@ -31,15 +32,15 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { runtime.LogError(a.ctx, "Could not parse find form:") runtime.LogError(a.ctx, err.Error()) zenity.Error(err.Error(), zenity.Title("Could not parse form"), zenity.ErrorIcon) - return out + return } client, ctx, close, err := a.connectToHost(hostKey) if err != nil { - return out + return } - defer close() + var query bson.M var projection bson.M var sort bson.M @@ -47,22 +48,25 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { err = bson.UnmarshalExtJSON([]byte(form.Query), true, &query) if err != nil { runtime.LogInfof(a.ctx, "Invalid find query: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Invalid query"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Invalid query" + result.ErrorDescription = err.Error() + return } err = json.Unmarshal([]byte(form.Fields), &projection) if err != nil { runtime.LogInfof(a.ctx, "Invalid find projection: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Invalid projection"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Invalid projection" + result.ErrorDescription = err.Error() + return } err = json.Unmarshal([]byte(form.Sort), &sort) if err != nil { runtime.LogInfof(a.ctx, "Invalid find sort: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Invalid sort"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Invalid sort" + result.ErrorDescription = err.Error() + return } opt := mongoOptions.FindOptions{ @@ -75,15 +79,17 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { total, err := client.Database(dbKey).Collection(collKey).CountDocuments(ctx, query, nil) if err != nil { runtime.LogWarningf(a.ctx, "Encountered an error while counting documents: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while counting docs"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Error while counting documents" + result.ErrorDescription = err.Error() + return } cur, err := client.Database(dbKey).Collection(collKey).Find(ctx, query, &opt) if err != nil { runtime.LogWarningf(a.ctx, "Encountered an error while performing query: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while querying"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Error while querying" + result.ErrorDescription = err.Error() + return } defer cur.Close(ctx) @@ -92,25 +98,27 @@ func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { if err != nil { runtime.LogWarningf(a.ctx, "Encountered an error while performing query: %s", err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while querying"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Error while querying" + result.ErrorDescription = err.Error() + return } - out.Total = total - out.Results = make([]string, 0) + result.Total = total + result.Results = make([]string, 0) for _, r := range results { marshalled, err := bson.MarshalExtJSON(r, true, true) if err != nil { runtime.LogError(a.ctx, "Failed to marshal find BSON:") runtime.LogError(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Failed to marshal JSON"), zenity.ErrorIcon) - return out + result.ErrorTitle = "Failed to marshal JSON" + result.ErrorDescription = err.Error() + return } - out.Results = append(out.Results, string(marshalled)) + result.Results = append(result.Results, string(marshalled)) } - return out + return } func (a *App) UpdateFoundDocument(hostKey, dbKey, collKey, idJson, newDocJson string) bool { diff --git a/internal/app/collection_indexes.go b/internal/app/collection_indexes.go index c71bb04..2167a98 100644 --- a/internal/app/collection_indexes.go +++ b/internal/app/collection_indexes.go @@ -11,10 +11,15 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func (a *App) GetIndexes(hostKey, dbKey, collKey string) []bson.M { +type GetIndexesResult struct { + Indexes []bson.M `json:"indexes"` + Error string `json:"error"` +} + +func (a *App) GetIndexes(hostKey, dbKey, collKey string) (result GetIndexesResult) { client, ctx, close, err := a.connectToHost(hostKey) if err != nil { - return nil + return } defer close() @@ -22,20 +27,18 @@ func (a *App) GetIndexes(hostKey, dbKey, collKey string) []bson.M { if err != nil { runtime.LogWarning(a.ctx, "Encountered an error while creating index cursor:") runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while creating cursor"), zenity.ErrorIcon) - return nil + result.Error = err.Error() + return } - var results []bson.M - err = cur.All(ctx, &results) + err = cur.All(ctx, &result.Indexes) if err != nil { runtime.LogWarning(a.ctx, "Encountered an error while executing index cursor:") runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Error while running cursor"), zenity.ErrorIcon) - return nil + result.Error = err.Error() } - return results + return } func (a *App) CreateIndex(hostKey, dbKey, collKey, jsonData string) string { diff --git a/internal/app/collection_insert.go b/internal/app/collection_insert.go index 89d8662..74d03e1 100644 --- a/internal/app/collection_insert.go +++ b/internal/app/collection_insert.go @@ -28,8 +28,8 @@ func (a *App) InsertItems(hostKey, dbKey, collKey, jsonData string) interface{} if err != nil { return nil } - defer close() + res, err := client.Database(dbKey).Collection(collKey).InsertMany(ctx, data) if err != nil { runtime.LogWarning(a.ctx, "Encountered an error while performing insert:") diff --git a/internal/app/connection.go b/internal/app/connection.go index cdf9644..66d8985 100644 --- a/internal/app/connection.go +++ b/internal/app/connection.go @@ -12,10 +12,12 @@ import ( mongoOptions "go.mongodb.org/mongo-driver/mongo/options" ) -type HostInfo struct { - Databases []string `json:"databases"` - Status bson.M `json:"status"` - SystemInfo bson.M `json:"systemInfo"` +type OpenConnectionResult struct { + Databases []string `json:"databases"` + Status bson.M `json:"status"` + StatusError string `json:"statusError"` + SystemInfo bson.M `json:"systemInfo"` + SystemInfoError string `json:"systemInfoError"` } func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, func(), error) { @@ -49,38 +51,35 @@ func (a *App) connectToHost(hostKey string) (*mongo.Client, context.Context, fun }, nil } -func (a *App) OpenConnection(hostKey string) (info HostInfo) { +func (a *App) OpenConnection(hostKey string) (result OpenConnectionResult) { client, ctx, close, err := a.connectToHost(hostKey) if err != nil { return } + defer close() - info.Databases, err = client.ListDatabaseNames(ctx, bson.M{}) + result.Databases, err = client.ListDatabaseNames(ctx, bson.M{}) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve database names for host "+hostKey) runtime.LogWarning(a.ctx, err.Error()) zenity.Error(err.Error(), zenity.Title("Error while getting databases"), zenity.ErrorIcon) - return } command := bson.M{"serverStatus": 1} - err = client.Database("admin").RunCommand(ctx, command).Decode(&info.Status) + err = client.Database("admin").RunCommand(ctx, command).Decode(&result.Status) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve server status") runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not get server status"), zenity.ErrorIcon) - return + result.StatusError = err.Error() } command = bson.M{"hostInfo": 1} - err = client.Database("admin").RunCommand(ctx, command).Decode(&info.SystemInfo) + err = client.Database("admin").RunCommand(ctx, command).Decode(&result.SystemInfo) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve system info") runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not get system info"), zenity.ErrorIcon) - return + result.SystemInfoError = err.Error() } - defer close() return } diff --git a/internal/app/database.go b/internal/app/database.go index 87b2199..3fa95bc 100644 --- a/internal/app/database.go +++ b/internal/app/database.go @@ -6,35 +6,34 @@ import ( "go.mongodb.org/mongo-driver/bson" ) -type DatabaseInfo struct { +type OpenDatabaseResult struct { Collections []string `json:"collections"` Stats bson.M `json:"stats"` + StatsError string `json:"statsError"` } -func (a *App) OpenDatabase(hostKey, dbKey string) (info DatabaseInfo) { +func (a *App) OpenDatabase(hostKey, dbKey string) (result OpenDatabaseResult) { client, ctx, close, err := a.connectToHost(hostKey) if err != nil { return } + defer close() command := bson.M{"dbStats": 1} - err = client.Database(dbKey).RunCommand(ctx, command).Decode(&info.Stats) + err = client.Database(dbKey).RunCommand(ctx, command).Decode(&result.Stats) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve database stats for "+dbKey) runtime.LogWarning(a.ctx, err.Error()) - zenity.Error(err.Error(), zenity.Title("Could not get stats"), zenity.ErrorIcon) - return + result.StatsError = err.Error() } - info.Collections, err = client.Database(dbKey).ListCollectionNames(ctx, bson.D{}) + result.Collections, err = client.Database(dbKey).ListCollectionNames(ctx, bson.D{}) if err != nil { runtime.LogWarning(a.ctx, "Could not retrieve collection list for db "+dbKey) runtime.LogWarning(a.ctx, err.Error()) zenity.Error(err.Error(), zenity.Title("Error while getting collections"), zenity.ErrorIcon) - return } - defer close() return } @@ -48,6 +47,7 @@ func (a *App) DropDatabase(hostKey, dbKey string) bool { if err != nil { return false } + defer close() err = client.Database(dbKey).Drop(ctx) if err != nil { @@ -57,6 +57,5 @@ func (a *App) DropDatabase(hostKey, dbKey string) bool { return false } - defer close() return true }