From 5134ed00430cf4b08d5062a78193d6ed8cd8984b Mon Sep 17 00:00:00 2001 From: Sander Vocke Date: Tue, 14 Jan 2020 14:52:21 +0100 Subject: [PATCH] Add an interactive DB query window. --- src/database.js | 77 +++++++++++++++++++++++++++++++++++++++++++++---- src/index.js | 5 ++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/database.js b/src/database.js index 651ec45..c72d4ad 100644 --- a/src/database.js +++ b/src/database.js @@ -1,18 +1,41 @@ import React from 'react'; +var DBTypeEnum = { + SQLITE: 1, + // INDEXEDDB: 2 // TODO: implement with migration +}; + +var DBLibraryEnum = { + ALASQL: 1 +} + export class DB { state = { - db_object: false, // In current implementation, this is an alasql object. + db_type: false, + db_object: false, db_name: false, + db_library: false, } - constructor(obj, name) { + constructor(obj, name, type, library) { this.state.db_object = obj; this.state.db_name = name; + this.state.db_type = type; + this.state.db_library = library; } - query(s) { - return this.state.db_object(s); + query_async(s) { + if(this.state.db_library === DBLibraryEnum.ALASQL) { + return this.state.db_object.promise(s); + } + throw new Error("Unsupported database library: " + this.state.db_library); + } + + query_sync(s) { + if(this.state.db_library === DBLibraryEnum.ALASQL) { + return this.state.db_object(s); + } + throw new Error("Unsupported database library: " + this.state.db_library); } } @@ -29,13 +52,14 @@ function fetch_db_from_sqlite(filename) { query += "ATTACH SQLITE DATABASE db(\"" + filename + "\"); USE db;"; asql.promise(query) .then(res => { - var imported_db = new DB(asql, "db"); + var imported_db = new DB(asql, "db", DBTypeEnum.SQLITE, DBLibraryEnum.ALASQL); resolve(imported_db); }); }); }); } +// TODO: generalize to FetchDB export class FetchSQLiteDB extends React.Component { state = { loading: true, @@ -54,3 +78,46 @@ export class FetchSQLiteDB extends React.Component { return this.props.children(this.state); } } + +export class DBQueryBar extends React.Component { + onChangeHandler = (event) => { + this.props.onChange(event.target.value); + } + + render() { + return ( +
+ +
+ ); + } +} + +export class DBQueryConsole extends React.Component { + state = { + processing: false, + result: false, + query: "", + } + + onQueryChangeHandler = query => { this.setState( { query: query } ); } + onQuerySubmitHandler = () => { + console.log("Submitting query: " + this.state.query); + this.setState( { processing: true, result: false } ); + this.props.database.query_async(this.state.query) + .then(result => { + this.setState( { processing: false, result: JSON.stringify(result) } ); + }); + } + + render() { + return ( + <> + + +

Result:

+ { this.state.result &&

{this.state.result}

} + + ); + } +} diff --git a/src/index.js b/src/index.js index 2f069d5..cc04a02 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Fetch } from './fetch.js'; -import { FetchSQLiteDB } from './database.js'; +import { FetchSQLiteDB, DBQueryConsole } from './database.js'; import './index.css'; @@ -11,7 +11,7 @@ const URLFinished = ({url, data}) =>

{url} was loaded: {data.byteLength} byte const DBLoading = ({sqlite_file}) =>

Loading: {sqlite_file}

; const DBError = ({error}) =>

Failed to load database: {error.message}

; -const DBFinished = ({sqlite_file, db}) =>

{sqlite_file} was loaded. Name: { db.state.db_name }. Tables: { JSON.stringify(db.query("SHOW TABLES;")) }

; +const DBFinished = ({sqlite_file, db}) =>

{sqlite_file} was loaded. Name: { db.state.db_name }. Tables: { JSON.stringify(db.query_sync("SHOW TABLES;")) }

; const TestFetch = ({url}) => ( @@ -32,6 +32,7 @@ const TestDBFetch = ({sqlite_file}) => ( { loading && } { error && } { done && } + { done && } )}