Start adding some structure. Async loading of database is working.

master
Sander Vocke 6 years ago
parent be5b31ed69
commit d6568c5e5d
  1. 56
      src/database.js
  2. 26
      src/fetch.js
  3. 108
      src/index.js

@ -0,0 +1,56 @@
import React from 'react';
export class DB {
state = {
db_object: false, // In current implementation, this is an alasql object.
db_name: false,
}
constructor(obj, name) {
this.state.db_object = obj;
this.state.db_name = name;
}
query(s) {
return this.state.db_object(s);
}
}
function fetch_db_from_sqlite(filename) {
return new Promise(function(resolve, reject) {
var initSqlJs = require('sql.js');
initSqlJs({ locateFile: filename => `/sql.js/dist/${filename}` })
.then( SQL => {
var asql = require('alasql');
// Attach to the SQLite database file,
// Create an IndexedDB to migrate it to, named "db",
// Get tables
var query = "";
query += "ATTACH SQLITE DATABASE db(\"" + filename + "\"); USE db;";
asql.promise(query)
.then(res => {
var imported_db = new DB(asql, "db");
resolve(imported_db);
});
});
});
}
export class FetchSQLiteDB extends React.Component {
state = {
loading: true,
error: false,
done: false,
db: false
};
componentDidMount() {
fetch_db_from_sqlite(this.props.sqlite_file)
.then(db => { this.setState({ loading: false, done: true, db: db }); })
.catch(error => this.setState({ loading: false, done: false, error }));
}
render() {
return this.props.children(this.state);
}
}

@ -0,0 +1,26 @@
import React from 'react';
export class Fetch extends React.Component {
state = {
loading: true,
error: false,
done: false,
data: [],
};
componentDidMount() {
fetch(this.props.url)
.then(res => {
if (!res.ok) {
throw new Error(res.status);
}
return res.arrayBuffer();
})
.then(data => this.setState({ loading: false, done: true, data }))
.catch(error => this.setState({ loading: false, done: false, error }));
}
render() {
return this.props.children(this.state);
}
}

@ -1,100 +1,46 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import './index.css'; import { Fetch } from './fetch.js';
import { FetchSQLiteDB } from './database.js';
var initSqlJs = require('sql.js');
var alasql = require('alasql');
var FetchTypeEnum = {
TO_VARIABLE: 1,
TO_LOCALSTORAGE: 2
}
class Fetch extends React.Component {
state = {
loading: true,
error: false,
done: false,
data: [],
};
componentDidMount() {
fetch(this.props.url)
.then(res => {
if (!res.ok) {
throw new Error(res.status);
}
return res.arrayBuffer();
})
.then(data => this.setState({ loading: false, done: true, data }))
.catch(error => this.setState({ loading: false, done: false, error }));
}
render() {
console.log(this.state);
return this.props.children(this.state);
}
}
class FetchSQLiteToIndexedDB extends React.Component {
state = {
loading: true,
error: false,
done: false,
sqlite_path: false,
indexed_db: false
};
componentDidMount() {
fetch(this.props.url)
.then(res => {
if (!res.ok) {
throw new Error(res.status);
}
return res.arrayBuffer();
})
.then(sqlite_data => this.setState({ loading: true, done: false }))
.catch(error => this.setState({ loading: false, done: false, error }));
}
render() { import './index.css';
console.log(this.state);
return this.props.children(this.state);
}
}
const Loading = ({url}) => <p>Loading: {url}</p>;
const Error = ({error}) => <p>Oops! Something went wrong: {error.message}</p>; const URLLoading = ({url}) => <p>Loading: {url}</p>;
const URLError = ({error}) => <p>Failed to load URL resource: {error.message}</p>;
const URLFinished = ({url, data}) => <p>{url} was loaded: {data.byteLength} bytes received.</p>;
const Finished = ({url, data}) => <p>{url} was loaded: {data.byteLength} bytes received.</p>; const DBLoading = ({sqlite_file}) => <p>Loading: {sqlite_file}</p>;
const DBError = ({error}) => <p>Failed to load database: {error.message}</p>;
const DBFinished = ({sqlite_file, db}) => <p>{sqlite_file} was loaded. Name: { db.state.db_name }. Tables: { JSON.stringify(db.query("SHOW TABLES;")) } </p>;
const TestFetch = ({url}) => ( const TestFetch = ({url}) => (
<Fetch url={url}> <Fetch url={url}>
{({ loading, error, done, data }) => ( {({ loading, error, done, data }) => (
<> <>
{ loading && <Loading url={url}/> } { loading && <URLLoading url={url}/> }
{ error && <Error error={error} />} { error && <URLError error={error} />}
{ done && <Finished url={url} data={data} /> } { done && <URLFinished url={url} data={data} /> }
</> </>
)} )}
</Fetch> </Fetch>
) )
// alasql(['ATTACH SQLITE DATABASE testdb("/test.sqlite");\ const TestDBFetch = ({sqlite_file}) => (
// SELECT * FROM images']).then(function(res){ <FetchSQLiteDB sqlite_file={sqlite_file}>
// console.log("Images:",res.pop()); {({ loading, error, done, db }) => (
// }); <>
{ loading && <DBLoading sqlite_file={sqlite_file}/> }
initSqlJs({ locateFile: filename => `/sql.js/dist/${filename}` }).then( SQL => { { error && <DBError error={error} />}
alasql(['ATTACH SQLITE DATABASE test("/test.sqlite");\ { done && <DBFinished sqlite_file={sqlite_file} db={db} /> }
USE test;\ </>
SELECT * FROM images']).then(function(res){ )}
console.log("Images:",res.pop()); </FetchSQLiteDB>
}); )
} );
ReactDOM.render( ReactDOM.render(
<TestFetch url={process.env.PUBLIC_URL + "/stuff"} />, <>
<TestFetch url={process.env.PUBLIC_URL + "/stuff"} />
<TestDBFetch sqlite_file={process.env.PUBLIC_URL + "/test.sqlite"} />
</>,
document.getElementById('root') document.getElementById('root')
); );

Loading…
Cancel
Save