diff --git a/src/components/MainLayout.vue b/src/components/MainLayout.vue index 5e755c9..b574550 100644 --- a/src/components/MainLayout.vue +++ b/src/components/MainLayout.vue @@ -111,14 +111,13 @@ scale factor 0.1 dataset. Please run KùzuExplorer locally to load a different dataset (see the - - documentation here - - ). + documentation here).

You can visualize the schema of LDBC SNB in the Schema tab and execute - interactive Cypher queries in the Shell tab. + interactive Cypher queries in the Shell tab. If your query returns more than + 1000 rows, it will be truncated.

KùzuExplorer is running in read-only mode. In this mode, you cannot load a diff --git a/src/components/SchemaView/SchemaPropertyEditCell.vue b/src/components/SchemaView/SchemaPropertyEditCell.vue index 17de50e..d25583d 100644 --- a/src/components/SchemaView/SchemaPropertyEditCell.vue +++ b/src/components/SchemaView/SchemaPropertyEditCell.vue @@ -309,7 +309,7 @@ export default { return `${type.memberType}[${type.size}]`; case DATA_TYPES.VAR_LIST: { let result = type.memberType; - for (let i = 0; i < type.dim; i++) { + for (let i = 0; i < type.dim; ++i) { result += '[]'; } return result; diff --git a/src/components/ShellView/CypherEditor.vue b/src/components/ShellView/CypherEditor.vue index 66e6aec..af0e24b 100644 --- a/src/components/ShellView/CypherEditor.vue +++ b/src/components/ShellView/CypherEditor.vue @@ -17,7 +17,7 @@

-
+
+
+ Executing query... + +
@@ -39,6 +48,7 @@ export default { errorMessage: "", isEvaluated: false, isMaximized: false, + isLoading: false, }), props: { @@ -66,6 +76,7 @@ export default { evaluateCypher(query) { this.queryResult = null; this.errorMessage = ""; + this.isLoading = true; Axios.post("/api/cypher", { query }) .then((res) => { this.queryResult = res.data; @@ -98,6 +109,8 @@ export default { this.$refs.resultContainer.handleDataChange(this.schema, null, this.errorMessage); }); } + }).finally(() => { + this.isLoading = false; }); if (!this.isEvaluated) { this.$emit("addCell"); @@ -133,4 +146,12 @@ export default { .shell-cell__wrapper { display: block; } + +div.d-flex.align-items-center { + margin: 20px; + margin-top: 0; + padding: 16px; + border: 2px solid $gray-300; + border-top: 0; +} diff --git a/src/server/Cypher.js b/src/server/Cypher.js index a9ea0f1..c3b7798 100644 --- a/src/server/Cypher.js +++ b/src/server/Cypher.js @@ -1,8 +1,15 @@ const database = require("./utils/Database"); const express = require("express"); const router = express.Router(); +const logger = require("./utils/Logger"); + const DEMO_MODE = "DEMO"; +let querySizeLimit = parseInt(process.env.KUZU_QUERY_SIZE_LIMIT); +querySizeLimit = isNaN(querySizeLimit) ? null : querySizeLimit; +if (querySizeLimit) { + logger.info(`Query size limit: ${querySizeLimit}`); +} let schema = null; router.post("/", async (req, res) => { @@ -39,7 +46,16 @@ router.post("/", async (req, res) => { const preparedStatment = await conn.prepare(query); result = await conn.execute(preparedStatment, params); } - const rows = await result.getAll(); + let rows; + const resultSize = result.getNumTuples(); + if (!querySizeLimit || resultSize <= querySizeLimit) { + rows = await result.getAll(); + } else { + rows = []; + for (let i = 0; i < querySizeLimit; ++i) { + rows.push(await result.getNext()); + } + } const columnTypes = await result.getColumnDataTypes(); const columnNames = await result.getColumnNames(); const dataTypes = {}; diff --git a/src/server/Datasets.js b/src/server/Datasets.js index 45f21ba..8a6cf7f 100644 --- a/src/server/Datasets.js +++ b/src/server/Datasets.js @@ -97,7 +97,7 @@ router.get("/:dataset/copy", async (req, res) => { } const conn = database.getConnection(); try { - for (let i = 0; i < commands.length; i++) { + for (let i = 0; i < commands.length; ++i) { const command = commands[i]; res.write("Executing: " + command + "\n"); const result = await conn.query(command); diff --git a/src/server/utils/Database.js b/src/server/utils/Database.js index f600608..fd55204 100644 --- a/src/server/utils/Database.js +++ b/src/server/utils/Database.js @@ -75,7 +75,7 @@ class Database { } this.db = new kuzu.Database(dbPath, bufferPoolSize, true, accessMode); this.connectionPool = []; - for (let i = 0; i < numberConnections; i++) { + for (let i = 0; i < numberConnections; ++i) { const conn = { connection: new kuzu.Connection(this.db, coresPerConnection), useCount: 0, @@ -99,7 +99,7 @@ class Database { getConnection() { let minUseCount = Number.MAX_SAFE_INTEGER; let minUseCountIndex = -1; - for (let i = 0; i < this.connectionPool.length; i++) { + for (let i = 0; i < this.connectionPool.length; ++i) { if (this.connectionPool[i].useCount < minUseCount) { minUseCount = this.connectionPool[i].useCount; minUseCountIndex = i; @@ -115,7 +115,7 @@ class Database { } releaseConnection(connection) { - for (let i = 0; i < this.connectionPool.length; i++) { + for (let i = 0; i < this.connectionPool.length; ++i) { if (this.connectionPool[i].connection === connection) { this.connectionPool[i].useCount--; return true;