From 1b2315b0b001665ddec735d85447d33a9a413f6c Mon Sep 17 00:00:00 2001 From: Romein van Buren Date: Sat, 18 Feb 2023 15:41:53 +0100 Subject: [PATCH] Aggregation --- frontend/src/components/details.svelte | 4 + frontend/src/components/icon.svelte | 4 + .../src/components/mongo-collation.svelte | 92 +++++++++++ frontend/src/components/tabbar.svelte | 5 +- .../src/lib/mongo-aggregation-stages.json | 41 +++++ frontend/src/lib/mongo-locales.json | 152 ++++++++++++++++++ frontend/src/lib/mongo.js | 9 ++ .../connection/collection/aggregate.svelte | 127 +++++++++++++++ .../connection/collection/index.svelte | 15 +- frontend/src/styles/style.css | 7 + frontend/wailsjs/go/app/App.d.ts | 2 + frontend/wailsjs/go/app/App.js | 4 + internal/app/collection_aggregate.go | 70 ++++++++ internal/app/collection_find.go | 2 +- 14 files changed, 526 insertions(+), 8 deletions(-) create mode 100644 frontend/src/components/mongo-collation.svelte create mode 100644 frontend/src/lib/mongo-aggregation-stages.json create mode 100644 frontend/src/lib/mongo-locales.json create mode 100644 frontend/src/organisms/connection/collection/aggregate.svelte create mode 100644 internal/app/collection_aggregate.go diff --git a/frontend/src/components/details.svelte b/frontend/src/components/details.svelte index 52b8e6a..b9809b8 100644 --- a/frontend/src/components/details.svelte +++ b/frontend/src/components/details.svelte @@ -54,6 +54,10 @@ } summary::before { content: ''; + display: none; + } + summary::-webkit-details-marker { + display: none; } summary :global(svg) { width: 14px; diff --git a/frontend/src/components/icon.svelte b/frontend/src/components/icon.svelte index 2511e6b..8cf40d2 100644 --- a/frontend/src/components/icon.svelte +++ b/frontend/src/components/icon.svelte @@ -87,5 +87,9 @@ {:else if name === 'save'} + {:else if name === 're'} + + {:else if name === 'chart'} + {/if} diff --git a/frontend/src/components/mongo-collation.svelte b/frontend/src/components/mongo-collation.svelte new file mode 100644 index 0000000..c18ae3a --- /dev/null +++ b/frontend/src/components/mongo-collation.svelte @@ -0,0 +1,92 @@ + + +
+ +
+ +
+ + +
+ +
+ + +
+ + + +
+ + +
+ +
+ + +
+ + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ + +
+ + + +
+
diff --git a/frontend/src/components/tabbar.svelte b/frontend/src/components/tabbar.svelte index f5681cc..efdec28 100644 --- a/frontend/src/components/tabbar.svelte +++ b/frontend/src/components/tabbar.svelte @@ -18,7 +18,10 @@
    {#each tabs as tab (tab.key)}
  • - + {#if tab.closable} + + + + {/each} + + + + +
    +
    + + +
    + +
    + + + +
    + +
    + + + +
    +
    + +
    + +
    +
    + + diff --git a/frontend/src/organisms/connection/collection/index.svelte b/frontend/src/organisms/connection/collection/index.svelte index b7452cc..ad9dcc0 100644 --- a/frontend/src/organisms/connection/collection/index.svelte +++ b/frontend/src/organisms/connection/collection/index.svelte @@ -3,6 +3,7 @@ import TabBar from '$components/tabbar.svelte'; import { EventsOn } from '$wails/runtime/runtime'; import { tick } from 'svelte'; + import Aggregate from './aggregate.svelte'; import ViewConfig from './components/viewconfig.svelte'; import Find from './find.svelte'; import Indexes from './indexes.svelte'; @@ -46,12 +47,13 @@ {#if collection} {#key collection}
    @@ -61,6 +63,7 @@ {:else if tab === 'update'} {:else if tab === 'remove'} {:else if tab === 'indexes'} + {:else if tab === 'aggregate'} {/if}
    {/key} diff --git a/frontend/src/styles/style.css b/frontend/src/styles/style.css index ac9eba9..040acb4 100644 --- a/frontend/src/styles/style.css +++ b/frontend/src/styles/style.css @@ -179,6 +179,13 @@ code, font-family: Menlo, monospace; } +.settinggrid { + display: grid; + grid-template-columns: 1fr 3fr; + align-items: center; + gap: 0.5rem; +} + @keyframes flashGreen { 0% { color: #0d0; diff --git a/frontend/wailsjs/go/app/App.d.ts b/frontend/wailsjs/go/app/App.d.ts index 19d5b9b..c4a8843 100755 --- a/frontend/wailsjs/go/app/App.d.ts +++ b/frontend/wailsjs/go/app/App.d.ts @@ -7,6 +7,8 @@ import {menu} from '../models'; export function AddHost(arg1:string):Promise; +export function Aggregate(arg1:string,arg2:string,arg3:string,arg4:string,arg5:string):Promise; + export function CreateIndex(arg1:string,arg2:string,arg3:string,arg4:string):Promise; export function DropCollection(arg1:string,arg2:string,arg3:string):Promise; diff --git a/frontend/wailsjs/go/app/App.js b/frontend/wailsjs/go/app/App.js index 8ba3108..334999e 100755 --- a/frontend/wailsjs/go/app/App.js +++ b/frontend/wailsjs/go/app/App.js @@ -6,6 +6,10 @@ export function AddHost(arg1) { return window['go']['app']['App']['AddHost'](arg1); } +export function Aggregate(arg1, arg2, arg3, arg4, arg5) { + return window['go']['app']['App']['Aggregate'](arg1, arg2, arg3, arg4, arg5); +} + export function CreateIndex(arg1, arg2, arg3, arg4) { return window['go']['app']['App']['CreateIndex'](arg1, arg2, arg3, arg4); } diff --git a/internal/app/collection_aggregate.go b/internal/app/collection_aggregate.go new file mode 100644 index 0000000..77a0e21 --- /dev/null +++ b/internal/app/collection_aggregate.go @@ -0,0 +1,70 @@ +package app + +import ( + "encoding/json" + "fmt" + + "github.com/wailsapp/wails/v2/pkg/runtime" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func (a *App) Aggregate(hostKey, dbKey, collKey, pipelineJson, settingsJson string) { + var settings *options.AggregateOptions + if err := json.Unmarshal([]byte(settingsJson), &settings); err != nil { + runtime.LogError(a.ctx, "Could not parse aggregation settings:") + runtime.LogError(a.ctx, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Type: runtime.ErrorDialog, + Title: "Couldn't parse aggregation settings", + Message: err.Error(), + }) + return + } + + var pipeline mongo.Pipeline + if err := bson.UnmarshalExtJSON([]byte(pipelineJson), true, &pipeline); err != nil { + runtime.LogWarning(a.ctx, "Could not parse aggregation pipeline:") + runtime.LogWarning(a.ctx, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Type: runtime.ErrorDialog, + Title: "Couldn't parse aggregation pipeline", + Message: err.Error(), + }) + return + } + + client, ctx, close, err := a.connectToHost(hostKey) + if err != nil { + return + } + + defer close() + + cursor, err := client.Database(dbKey).Collection(collKey).Aggregate(ctx, pipeline, settings) + if err != nil { + runtime.LogWarning(a.ctx, "Could not get aggregation cursor:") + runtime.LogWarning(a.ctx, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Type: runtime.ErrorDialog, + Title: "Couldn't get aggregation cursor", + Message: err.Error(), + }) + return + } + + var results []bson.M + if err := cursor.All(ctx, &results); err != nil { + runtime.LogInfo(a.ctx, "Error while running aggregation pipeline:") + runtime.LogInfo(a.ctx, err.Error()) + runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Type: runtime.ErrorDialog, + Title: "Error while running aggregation pipeline", + Message: err.Error(), + }) + return + } + + fmt.Println(results) +} diff --git a/internal/app/collection_find.go b/internal/app/collection_find.go index 805b7a2..7679b0d 100644 --- a/internal/app/collection_find.go +++ b/internal/app/collection_find.go @@ -21,7 +21,7 @@ type QueryResult struct { Results []string `json:"results"` } -func (a *App) FindItems(hostKey, dbKey, collKey string, formJson string) QueryResult { +func (a *App) FindItems(hostKey, dbKey, collKey, formJson string) QueryResult { var out QueryResult var form Query