mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
fix release for graphite
This commit is contained in:
parent
75d6450341
commit
b144849c77
@ -1,2 +1 @@
|
||||
- a35042b3 updated docsys nuxt resources
|
||||
- 1a7dfcf8 updated guidebook static content
|
||||
- 75d64503 (HEAD -> main, origin/main) Fix for graphite reporter regression
|
||||
|
258
docsys/src/main/node/docsys/components/builders/CqlBuilder.vue
Normal file
258
docsys/src/main/node/docsys/components/builders/CqlBuilder.vue
Normal file
@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row>
|
||||
Workload details
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-text-field
|
||||
outlined
|
||||
label="Workload name"
|
||||
v-model="workloadName"
|
||||
></v-text-field>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-textarea
|
||||
outlined
|
||||
label="Create Table Statement"
|
||||
v-model="createTableDef"
|
||||
v-on:blur="parseStatement()"
|
||||
></v-textarea>
|
||||
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-btn :title="save_title" v-if="parseSuccess" v-on:click="saveWorkloadToWorkspace()">{{
|
||||
save_button
|
||||
}}
|
||||
</v-btn>
|
||||
<v-btn :title="dl_title" v-if="parseSuccess" v-on:click="downloadWorkload()">{{ dl_button }}</v-btn>
|
||||
<v-btn :title="example1" v-if="!parseSuccess" v-on:click="loadExample1()">Load example1.cql</v-btn>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- <v-col cols="12">-->
|
||||
<!-- </v-col>-->
|
||||
<!-- </v-card>-->
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import antlr4 from "antlr4";
|
||||
import {saveAs} from "file-saver";
|
||||
import yamlDumper from "js-yaml";
|
||||
import CQL3Parser from '@/antlr/CQL3Parser.js';
|
||||
import CQL3Lexer from '@/antlr/CQL3Lexer.js';
|
||||
import defaultYaml from 'assets/default.yaml';
|
||||
import basictypes from 'assets/basictypes.yaml';
|
||||
|
||||
export default {
|
||||
data(context) {
|
||||
let data = {
|
||||
createTableDef: "",
|
||||
workloadName: "",
|
||||
parseSuccess: false,
|
||||
blob: null,
|
||||
};
|
||||
return data;
|
||||
},
|
||||
computed: {
|
||||
save_button: function () {
|
||||
return "Save to workspace '" + this.$store.getters["workspaces/getWorkspace"] + "'";
|
||||
},
|
||||
dl_button: function () {
|
||||
return "Download as " + this.filename;
|
||||
},
|
||||
dl_title: function () {
|
||||
return "Click to download the workload as '" + this.filename + "'";
|
||||
},
|
||||
filename: function () {
|
||||
return this.workloadName + ".yaml";
|
||||
},
|
||||
save_title: function () {
|
||||
return "Click to save this workload in the '" + this.workspace + "' workspace, or change the workspace in the app bar first.\n"
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadExample1() {
|
||||
this.$data.createTableDef="create table a.b (\n a text,\n b text,\n primary key(a,b))\n";
|
||||
this.$data.workloadName="example1";
|
||||
this.parseStatement();
|
||||
},
|
||||
async parseStatement() {
|
||||
console.log(this.$data.createTableDef);
|
||||
|
||||
const input = this.$data.createTableDef;
|
||||
|
||||
const chars = new antlr4.InputStream(input);
|
||||
const lexer = new CQL3Lexer.CQL3Lexer(chars);
|
||||
|
||||
lexer.strictMode = false; // do not use js strictMode
|
||||
|
||||
const tokens = new antlr4.CommonTokenStream(lexer);
|
||||
const parser = new CQL3Parser.CQL3Parser(tokens);
|
||||
|
||||
const context = parser.create_table_stmt();
|
||||
|
||||
try {
|
||||
const keyspaceName = context.table_name().keyspace_name().getChild(0).getText()
|
||||
const tableName = context.table_name().table_name_noks().getChild(0).getText()
|
||||
|
||||
const columnDefinitions = context.column_definitions().column_definition();
|
||||
|
||||
let columns = [];
|
||||
let partitionKeys = [];
|
||||
let clusteringKeys = [];
|
||||
columnDefinitions.forEach(columnDef => {
|
||||
if (columnDef.column_name() != null) {
|
||||
columns.push({
|
||||
"name": columnDef.column_name().getText(),
|
||||
"type": columnDef.column_type().getText()
|
||||
})
|
||||
} else {
|
||||
const primaryKeyContext = columnDef.primary_key()
|
||||
if (primaryKeyContext.partition_key() != null) {
|
||||
const partitionKeysContext = primaryKeyContext.partition_key().column_name();
|
||||
partitionKeysContext.map((partitionKey, i) => {
|
||||
const partitionKeyName = partitionKey.getText()
|
||||
const col = {
|
||||
"name": partitionKeyName,
|
||||
"type": columns.filter(x => x.name == partitionKeyName)[0].type
|
||||
}
|
||||
partitionKeys.push(col)
|
||||
})
|
||||
}
|
||||
if (primaryKeyContext.clustering_column().length != 0) {
|
||||
const clusteringKeysContext = primaryKeyContext.clustering_column();
|
||||
clusteringKeysContext.map((clusteringKey, i) => {
|
||||
const clusteringKeyName = clusteringKey.getText()
|
||||
const col = {
|
||||
"name": clusteringKeyName,
|
||||
"type": columns.filter(x => x.name == clusteringKeyName)[0].type
|
||||
}
|
||||
clusteringKeys.push(col)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
columns = columns.filter(col => {
|
||||
return partitionKeys.filter(pk => pk.name == col.name).length == 0 && clusteringKeys.filter(cc => cc.name == col.name).length == 0
|
||||
})
|
||||
|
||||
const allColumns = [].concat(columns, partitionKeys, clusteringKeys)
|
||||
|
||||
this.$data.tableName = tableName;
|
||||
this.$data.keyspaceName = keyspaceName;
|
||||
this.$data.columns = columns;
|
||||
this.$data.clusteringKeys = clusteringKeys;
|
||||
this.$data.partitionKeys = partitionKeys;
|
||||
this.$data.allColumns = allColumns;
|
||||
|
||||
console.log(this.$data)
|
||||
|
||||
console.log(defaultYaml)
|
||||
|
||||
// schema and bindings
|
||||
let createTableStatement = "CREATE TABLE IF NOT EXISTS <<keyspace:" + keyspaceName + ">>." + tableName + " (\n";
|
||||
|
||||
console.log(basictypes)
|
||||
defaultYaml.bindings = {}
|
||||
allColumns.forEach(column => {
|
||||
let recipe = basictypes.bindings[column.type + "val"];
|
||||
if (recipe == undefined) {
|
||||
const chars = new antlr4.InputStream(column.type);
|
||||
const lexer = new CQL3Lexer.CQL3Lexer(chars);
|
||||
lexer.strictMode = false; // do not use js strictMode
|
||||
const tokens = new antlr4.CommonTokenStream(lexer);
|
||||
const parser = new CQL3Parser.CQL3Parser(tokens);
|
||||
|
||||
const typeContext = parser.column_type();
|
||||
const collectionTypeContext = typeContext.data_type().collection_type();
|
||||
const collectionType = collectionTypeContext.children[0].getText();
|
||||
if (collectionType.toLowerCase() == "set") {
|
||||
const type = collectionTypeContext.children[2].getText();
|
||||
recipe = "Set(HashRange(1,<<set-count-" + column.name + ":5>>)," + basictypes.bindings[type + "val"] + ") -> java.util.Set"
|
||||
} else if (collectionType.toLowerCase() == "list") {
|
||||
const type = collectionTypeContext.children[2].getText();
|
||||
recipe = "List(HashRange(1,<<list-count-" + column.name + ":5>>)," + basictypes.bindings[type + "val"] + ") -> java.util.List"
|
||||
|
||||
} else if (collectionType.toLowerCase() == "map") {
|
||||
const type1 = collectionTypeContext.children[2].getText();
|
||||
const type2 = collectionTypeContext.children[4].getText();
|
||||
recipe = "Map(HashRange(1,<<map-count-" + column.name + ":5>>)," + basictypes.bindings[type1 + "val"] + "," + basictypes.bindings[type2 + "val"] + ") -> java.util.Map"
|
||||
} else {
|
||||
alert("Could not generate recipe for type: " + column.type + " for column: " + column.name)
|
||||
}
|
||||
}
|
||||
defaultYaml.bindings[column.name] = recipe
|
||||
createTableStatement = createTableStatement + column.name + " " + column.type + ",\n";
|
||||
})
|
||||
|
||||
let pk = "PRIMARY KEY (("
|
||||
pk = pk + partitionKeys.map(x => x.name).reduce((x, acc) => acc = acc + "," + x)
|
||||
pk = pk + ")"
|
||||
if (clusteringKeys.length > 0) {
|
||||
pk = pk + "," + clusteringKeys.map(x => x.name).reduce((x, acc) => acc = acc + "," + x)
|
||||
}
|
||||
pk = pk + ")"
|
||||
createTableStatement = createTableStatement + pk + "\n);"
|
||||
defaultYaml.blocks[0].statements[0] = {"create-table": createTableStatement}
|
||||
|
||||
//rampup
|
||||
let insertStatement = "INSERT INTO <<keyspace:" + keyspaceName + ">>." + tableName + " (\n";
|
||||
insertStatement = insertStatement + allColumns.map(x => x.name).reduce((x, acc) => acc = acc + ",\n" + x) + "\n) VALUES (\n";
|
||||
insertStatement = insertStatement + allColumns.map(x => "{" + x.name + "}").reduce((x, acc) => acc = acc + ",\n" + x) + "\n);"
|
||||
|
||||
defaultYaml.blocks[1].statements[0] = {"insert-rampup": insertStatement}
|
||||
|
||||
//main-write
|
||||
defaultYaml.blocks[2].statements[0] = {"insert-main": insertStatement}
|
||||
|
||||
//main-read-partition
|
||||
let readPartitionStatement = "SELECT * from <<keyspace:" + keyspaceName + ">>." + tableName + " WHERE ";
|
||||
readPartitionStatement = readPartitionStatement + partitionKeys.map(x => x.name + "={" + x.name + "}").reduce((x, acc) => acc = acc + " AND " + x);
|
||||
let readRowStatement = readPartitionStatement + ";";
|
||||
if (clusteringKeys.length > 0) {
|
||||
readPartitionStatement = readPartitionStatement + " AND " + clusteringKeys.map(x => x.name + "={" + x.name + "}").reduce((x, acc) => acc = acc + " AND " + x);
|
||||
}
|
||||
readPartitionStatement = readPartitionStatement + ";";
|
||||
|
||||
defaultYaml.blocks[3].statements[0] = {"read-partition": readPartitionStatement}
|
||||
|
||||
//main-read-row
|
||||
defaultYaml.blocks[4].statements[0] = {"read-row": readRowStatement}
|
||||
|
||||
defaultYaml.description = this.$data.workloadName
|
||||
|
||||
const yamlOutputText = yamlDumper.dump(defaultYaml)
|
||||
this.blob = new Blob([yamlOutputText], {type: "text/plain;charset=utf-8"});
|
||||
this.parseSuccess = true;
|
||||
} catch (e) {
|
||||
console.log("blur, invalid create table def")
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
},
|
||||
downloadWorkload() {
|
||||
saveAs(this.blob, this.$data.filename);
|
||||
},
|
||||
saveWorkloadToWorkspace() {
|
||||
let workspace =this.$store.getters["workspaces/getWorkspace"];
|
||||
this.$store.dispatch("workspaces/putFile", {
|
||||
workspace: workspace,
|
||||
filename: this.filename,
|
||||
content: this.blob
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('service_status/loadEndpoints')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<v-container>
|
||||
|
||||
<!-- OpenAPI Selection -->
|
||||
<v-row>
|
||||
<v-select
|
||||
v-if="mode==='selecting'"
|
||||
label="Use OpenAPI YAML"
|
||||
v-model="yamloptions"
|
||||
:items="yamlfiles_in_workspace"
|
||||
>
|
||||
<template v-slot:append-item>
|
||||
<v-list-item>
|
||||
<v-btn @click="mode='importing'">import</v-btn>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-select>
|
||||
</v-row>
|
||||
|
||||
<div v-if="mode==='importing'">
|
||||
|
||||
<v-row>
|
||||
<v-text-field
|
||||
outlined
|
||||
label="OpenAPI YAML URL"
|
||||
@input="nameImport()"
|
||||
v-model="import_url"></v-text-field>
|
||||
|
||||
</v-row>
|
||||
<v-row v-if="import_as">
|
||||
<v-text-field outlined
|
||||
label="import as name"
|
||||
v-model="import_as"></v-text-field>
|
||||
</v-row>
|
||||
<v-row>
|
||||
|
||||
<v-btn
|
||||
@click="loadExample1()"
|
||||
v-if="!this.import_url"
|
||||
title="load https://gist.githubusercontent.com/jshook/529e1b3f80e6283459c55ae56255bbc5/raw/c0d2ac9853099b57ca6d2209661f332a3953ab02/stargate.yaml"
|
||||
>Load stargate.yaml
|
||||
</v-btn>
|
||||
|
||||
<v-btn
|
||||
v-if="this.import_url && this.import_url.match('^http')"
|
||||
@click="importToWorkspace()"
|
||||
>Save to Workspace
|
||||
</v-btn>
|
||||
|
||||
</v-row>
|
||||
</div>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "openapi",
|
||||
data() {
|
||||
return {
|
||||
openapifiles: [],
|
||||
mode: 'selecting',
|
||||
import_url: null,
|
||||
yamloptions: null,
|
||||
import_as: null,
|
||||
example_url: "https://gist.githubusercontent.com/jshook/529e1b3f80e6283459c55ae56255bbc5/raw/c0d2ac9853099b57ca6d2209661f332a3953ab02/stargate.yaml"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
yamlfiles_in_workspace: {
|
||||
get() {
|
||||
let wsfiles = this.$store.getters["workspaces/getMatchingFiles"]
|
||||
}
|
||||
},
|
||||
workspace: function () {
|
||||
return this.$store.getters["workspaces/getWorkspace"]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshOpenApiFiles() {
|
||||
let wsfiles = this.$store.dispatch("workspaces/listWorkspaceFiles",
|
||||
{
|
||||
wsname: this.workspace,
|
||||
contains: '^openapi: 3.*'
|
||||
})
|
||||
console.log("wsfiles:" + JSON.stringify(wsfiles,null,2))
|
||||
// this.openapifiles=wsfiles.ls.map(f => f.name)
|
||||
},
|
||||
loadExample1() {
|
||||
this.import_url = this.example_url
|
||||
this.nameImport();
|
||||
},
|
||||
nameImport() {
|
||||
let parts = this.import_url.split("/");
|
||||
this.import_as = parts[parts.length - 1]
|
||||
},
|
||||
importToWorkspace() {
|
||||
this.$store.dispatch("workspaces/importUrlToWorkspace",
|
||||
{
|
||||
workspace: this.workspace,
|
||||
import_url: this.import_url,
|
||||
import_as: this.import_as
|
||||
}
|
||||
)
|
||||
this.refreshOpenApiFiles()
|
||||
this.mode = 'selecting'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.refreshOpenApiFiles()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
128
docsys/src/main/node/docsys/pages/ui/openapi.vue
Normal file
128
docsys/src/main/node/docsys/pages/ui/openapi.vue
Normal file
@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<main-app-bar></main-app-bar>
|
||||
|
||||
<!-- <workspace-selector @changed="seenChange(workspace)"></workspace-selector>-->
|
||||
|
||||
<!-- <v-btn title="start a new workspace" @click="startNewWorkspace()">-->
|
||||
<!-- <v-icon>mdi-folder-plus-outline</v-icon>-->
|
||||
<!-- </v-btn>-->
|
||||
|
||||
<!-- <v-btn icon title="upload a workspace zip file">-->
|
||||
<!-- <v-icon>mdi-folder-upload</v-icon>-->
|
||||
<!-- </v-btn>-->
|
||||
<!-- <v-btn icon title="download workspaces.zip">-->
|
||||
<!-- <v-icon>mdi-briefcase-download</v-icon>-->
|
||||
<!-- </v-btn>-->
|
||||
<!-- <v-btn icon title="upload workspaces.zip">-->
|
||||
<!-- <v-icon>mdi-briefcase-upload</v-icon>-->
|
||||
<!-- </v-btn>-->
|
||||
|
||||
<v-content justify-start align-start class="d-inline-block pa-4 ma-10">
|
||||
<div class="row no-gutters">
|
||||
<v-card min-width="300" max-width="300" max-height="400" raised elevation="5" v-for="(cardspace,w) in workspaces" :key="w"
|
||||
class="pa-4 ma-4">
|
||||
<v-row>
|
||||
<v-card-title title="workspace name">{{ cardspace.name }}</v-card-title>
|
||||
<v-icon v-if="workspace === cardspace.name">mdi-check-bold</v-icon>
|
||||
</v-row>
|
||||
|
||||
<v-card-subtitle title="last change">{{ abbrev(cardspace.summary.last_changed_filename) }}</v-card-subtitle>
|
||||
<v-divider></v-divider>
|
||||
<v-list align-start>
|
||||
<v-simple-table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Bytes</td>
|
||||
<td>{{ cardspace.summary.total_bytes }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Files</td>
|
||||
<td>{{ cardspace.summary.total_files }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-simple-table>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list-item>
|
||||
<v-btn title="view details of workspace">
|
||||
<v-icon>mdi-magnify</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn title="download zipped workspace">
|
||||
<v-icon>mdi-folder-download</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn title="purge workspace">
|
||||
<v-icon @click="purgeWorkspace(cardspace.name)">mdi-trash-can</v-icon>
|
||||
</v-btn>
|
||||
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-content>
|
||||
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import WorkspaceSelector from "@/components/WorkspaceSelector";
|
||||
import {mapActions, mapGetters, mapMutations} from "vuex";
|
||||
import AppSelector from "@/components/AppSelector";
|
||||
import MainAppBar from "@/components/MainAppBar";
|
||||
|
||||
export default {
|
||||
name: "workspaces.vue",
|
||||
components: {
|
||||
MainAppBar,
|
||||
AppSelector,
|
||||
WorkspaceSelector
|
||||
},
|
||||
data(context) {
|
||||
let data = {};
|
||||
return data;
|
||||
},
|
||||
computed: {
|
||||
workspace: {
|
||||
get() {
|
||||
return this.$store.getters["workspaces/getWorkspace"]
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch("workspaces/setWorkspace", val)
|
||||
}
|
||||
},
|
||||
workspaces: {
|
||||
get() {
|
||||
return this.$store.getters["workspaces/getWorkspaces"]
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch("workspaces/setWorkspaces", val)
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
abbrev(name) {
|
||||
return name;
|
||||
},
|
||||
purgeWorkspace: function (ws) {
|
||||
// console.log("purging " + ws);
|
||||
this.$store.dispatch('workspaces/purgeWorkspace', ws);
|
||||
// this.$store.dispatch("workspaces/setWorkspace")
|
||||
this.$forceUpdate();
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('workspaces/initWorkspaces', "workspace panel load");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
36
docsys/src/main/node/docsys/store/openapi.js
Normal file
36
docsys/src/main/node/docsys/store/openapi.js
Normal file
@ -0,0 +1,36 @@
|
||||
import endpoints from "@/js/endpoints";
|
||||
|
||||
export const state = () => ({
|
||||
pathops: []
|
||||
});
|
||||
|
||||
export const getters = {
|
||||
getPathOps: (state, getters) => {
|
||||
return state.pathops;
|
||||
}
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
setPathOps: (state,pathops) => {
|
||||
state.pathops=pathops
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
async loadPaths(context, opts) {
|
||||
let reason = opts.reason;
|
||||
let workspace = opts.workspace;
|
||||
let filepath = (opts.filepath ? opts.filepath : "stargate.yaml")
|
||||
if (!reason || !workspace || !filepath) {
|
||||
throw "reason, workspace, filepath are all required in opts: " + JSON.stringify(opts,null,2);
|
||||
}
|
||||
|
||||
await this.$axios.$get(endpoints.url(document, context, "/services/openapi/paths?filepath=" + filepath))
|
||||
.then(res => {
|
||||
context.commit('setPathOps', res)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("axios/nuxt scenarios async error:", e);
|
||||
})
|
||||
},
|
||||
}
|
Loading…
Reference in New Issue
Block a user