mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-01-18 21:17:59 +00:00
Index creation
This commit is contained in:
parent
53093681ec
commit
480edf8d59
@ -124,18 +124,4 @@
|
|||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-top: 1px solid #ccc;
|
border-top: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.outer {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
<script>
|
||||||
|
import Icon from '../../../components/icon.svelte';
|
||||||
|
import { input } from '../../../actions';
|
||||||
|
import Modal from '../../../components/modal.svelte';
|
||||||
|
import { CreateIndex } from '../../../../wailsjs/go/app/App';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
export let collection = {};
|
||||||
|
export let creatingNewIndex = false;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
let index = { model: [] };
|
||||||
|
|
||||||
|
function addRule() {
|
||||||
|
index.model = [ ...index.model, {} ];
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeRule(ruleIndex) {
|
||||||
|
index.model.splice(ruleIndex, 1);
|
||||||
|
index.model = index.model;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function create() {
|
||||||
|
const newIndexName = await CreateIndex(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(index));
|
||||||
|
if (newIndexName) {
|
||||||
|
creatingNewIndex = false;
|
||||||
|
index = { model: [] };
|
||||||
|
dispatch('reload');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal title="Create new index {collection ? `on collection ${collection.key}` : ''}" bind:show={creatingNewIndex}>
|
||||||
|
<form on:submit|preventDefault={create}>
|
||||||
|
<label class="field name">
|
||||||
|
<span class="label">Name</span>
|
||||||
|
<input type="text" placeholder="Optional" bind:value={index.name} use:input={{ autofocus: true }} />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="toggles">
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Background (legacy)</span>
|
||||||
|
<span class="checkbox">
|
||||||
|
<input type="checkbox" bind:checked={index.background} />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Unique</span>
|
||||||
|
<span class="checkbox">
|
||||||
|
<input type="checkbox" bind:checked={index.unique} />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<!-- <label class="field">
|
||||||
|
<span class="label">Drop duplicates</span>
|
||||||
|
<span class="checkbox">
|
||||||
|
<input type="checkbox" bind:checked={index.dropDuplicates} />
|
||||||
|
</span>
|
||||||
|
</label> -->
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Sparse</span>
|
||||||
|
<span class="checkbox">
|
||||||
|
<input type="checkbox" bind:checked={index.sparse} />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="model">
|
||||||
|
{#each index.model as rule, ruleIndex}
|
||||||
|
<div class="row">
|
||||||
|
<label class="field">
|
||||||
|
<span class="label">Key</span>
|
||||||
|
<input type="text" placeholder="_id" bind:value={rule.key}>
|
||||||
|
</label>
|
||||||
|
<label class="field">
|
||||||
|
<select bind:value={rule.sort}>
|
||||||
|
<option value={1}>Ascending</option>
|
||||||
|
<option value={-1}>Decending</option>
|
||||||
|
<option value="hashed" disabled={index.model.length > 1}>Hashed</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<button type="button" class="btn danger" on:click={() => removeRule(ruleIndex)} disabled={index.model.length < 2}>
|
||||||
|
<Icon name="-" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
No rules
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="btn" type="button" on:click={addRule} disabled={index.model.some(r => r.sort === 'hashed')}>
|
||||||
|
<Icon name="+" /> Add rule
|
||||||
|
</button>
|
||||||
|
<button class="btn" type="submit" disabled={!index.model.length || index.model.some(r => !r.key)}>
|
||||||
|
<Icon name="+" /> Create index
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.field.name {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggles {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.model .row {
|
||||||
|
display: grid;
|
||||||
|
grid-template: 1fr / 1fr auto auto;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.buttons button[type="submit"] {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,12 +3,14 @@
|
|||||||
import ObjectGrid from '../../../components/objectgrid.svelte';
|
import ObjectGrid from '../../../components/objectgrid.svelte';
|
||||||
import { DropIndex, GetIndexes } from '../../../../wailsjs/go/app/App';
|
import { DropIndex, GetIndexes } from '../../../../wailsjs/go/app/App';
|
||||||
import Icon from '../../../components/icon.svelte';
|
import Icon from '../../../components/icon.svelte';
|
||||||
|
import IndexDetail from './indexes-detail.svelte';
|
||||||
|
|
||||||
export let collection;
|
export let collection;
|
||||||
|
|
||||||
let indexes = [];
|
let indexes = [];
|
||||||
let activePath = [];
|
let activePath = [];
|
||||||
let objectViewerData = '';
|
let objectViewerData = '';
|
||||||
|
let creatingNewIndex = false;
|
||||||
|
|
||||||
$: collection && getIndexes();
|
$: collection && getIndexes();
|
||||||
|
|
||||||
@ -19,6 +21,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createIndex() {
|
||||||
|
creatingNewIndex = true;
|
||||||
|
}
|
||||||
|
|
||||||
async function drop(key) {
|
async function drop(key) {
|
||||||
if (typeof key !== 'string') {
|
if (typeof key !== 'string') {
|
||||||
key = activePath[0];
|
key = activePath[0];
|
||||||
@ -41,7 +47,7 @@
|
|||||||
<button class="btn" on:click={getIndexes}>
|
<button class="btn" on:click={getIndexes}>
|
||||||
<Icon name="reload" /> Reload
|
<Icon name="reload" /> Reload
|
||||||
</button>
|
</button>
|
||||||
<button class="btn">
|
<button class="btn" on:click={createIndex}>
|
||||||
<Icon name="+" /> Create index…
|
<Icon name="+" /> Create index…
|
||||||
</button>
|
</button>
|
||||||
<button class="btn danger" on:click={drop} disabled={!indexes?.length || !activePath[0]}>
|
<button class="btn danger" on:click={drop} disabled={!indexes?.length || !activePath[0]}>
|
||||||
@ -61,6 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ObjectViewer bind:data={objectViewerData} />
|
<ObjectViewer bind:data={objectViewerData} />
|
||||||
|
<IndexDetail bind:creatingNewIndex {collection} on:reload={getIndexes} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.indexes {
|
.indexes {
|
||||||
|
2
frontend/wailsjs/go/app/App.d.ts
vendored
2
frontend/wailsjs/go/app/App.d.ts
vendored
@ -7,6 +7,8 @@ import {menu} from '../models';
|
|||||||
|
|
||||||
export function AddHost(arg1:string):Promise<void>;
|
export function AddHost(arg1:string):Promise<void>;
|
||||||
|
|
||||||
|
export function CreateIndex(arg1:string,arg2:string,arg3:string,arg4:string):Promise<string>;
|
||||||
|
|
||||||
export function DropCollection(arg1:string,arg2:string,arg3:string):Promise<boolean>;
|
export function DropCollection(arg1:string,arg2:string,arg3:string):Promise<boolean>;
|
||||||
|
|
||||||
export function DropDatabase(arg1:string,arg2:string):Promise<boolean>;
|
export function DropDatabase(arg1:string,arg2:string):Promise<boolean>;
|
||||||
|
@ -6,6 +6,10 @@ export function AddHost(arg1) {
|
|||||||
return window['go']['app']['App']['AddHost'](arg1);
|
return window['go']['app']['App']['AddHost'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CreateIndex(arg1, arg2, arg3, arg4) {
|
||||||
|
return window['go']['app']['App']['CreateIndex'](arg1, arg2, arg3, arg4);
|
||||||
|
}
|
||||||
|
|
||||||
export function DropCollection(arg1, arg2, arg3) {
|
export function DropCollection(arg1, arg2, arg3) {
|
||||||
return window['go']['app']['App']['DropCollection'](arg1, arg2, arg3);
|
return window['go']['app']['App']['DropCollection'](arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,6 +45,75 @@ func (a *App) GetIndexes(hostKey, dbKey, collKey string) []bson.M {
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) CreateIndex(hostKey, dbKey, collKey, jsonData string) string {
|
||||||
|
client, ctx, close, err := a.connectToHost(hostKey)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer close()
|
||||||
|
|
||||||
|
type modelItem struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Sort interface{} `json:"sort"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var form struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Background bool `json:"background"`
|
||||||
|
Unique bool `json:"unique"`
|
||||||
|
DropDuplicates bool `json:"dropDuplicates"`
|
||||||
|
Sparse bool `json:"sparse"`
|
||||||
|
Model []modelItem `json:"model"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(jsonData), &form)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||||
|
Type: runtime.ErrorDialog,
|
||||||
|
Title: "Couldn't parse JSON",
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if form.Model == nil {
|
||||||
|
form.Model = make([]modelItem, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys bson.D
|
||||||
|
for _, v := range form.Model {
|
||||||
|
asFloat, canBeFloat := v.Sort.(float64)
|
||||||
|
if canBeFloat {
|
||||||
|
v.Sort = int8(math.Floor(asFloat))
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = append(keys, bson.E{
|
||||||
|
Key: v.Key,
|
||||||
|
Value: v.Sort,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
indexModel := mongo.IndexModel{
|
||||||
|
Keys: keys,
|
||||||
|
Options: options.Index().SetUnique(form.Unique).SetSparse(form.Sparse),
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := client.Database(dbKey).Collection(collKey).Indexes().CreateOne(ctx, indexModel)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||||
|
Type: runtime.ErrorDialog,
|
||||||
|
Title: "Error while creating index",
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) DropIndex(hostKey, dbKey, collKey, indexName string) bool {
|
func (a *App) DropIndex(hostKey, dbKey, collKey, indexName string) bool {
|
||||||
client, ctx, close, err := a.connectToHost(hostKey)
|
client, ctx, close, err := a.connectToHost(hostKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user