Skip to content

Commit

Permalink
Add and modify existing examples
Browse files Browse the repository at this point in the history
I took many of these examples from the gh-pages branch.
These examples are useful even outside of a Github Pages context, so I wanted to include them here. This makes it easier for the README to reference them.
Since they are now in the main branch, I have taken care to point to CDN libraries where I could so that it doesn't get cluttered with vendor code, like for the codemirror library.
  • Loading branch information
Taytay committed Apr 25, 2019
1 parent d86aca6 commit 77ad0d3
Show file tree
Hide file tree
Showing 9 changed files with 488 additions and 0 deletions.
81 changes: 81 additions & 0 deletions examples/GUI/demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
html {
background:#222;
margin:auto;
width:80%;
}

body{
background: linear-gradient(#aaa 0, #ddd 10px, #fff 55px);
border: 1px solid black;
padding: 10px 20px;
box-shadow: 5px 0px 30px #000;
border-radius: 8px;
}

h1 {
text-align: center;
color: #222;
margin: 0 0 30px;
}

.button {
color: #333;
background: linear-gradient(#eee, #ddd);
border: 1px solid #222;
border-radius: 3px;
padding: 7px;
margin-right: 5px;
transition: .3s;
font-family: ubuntu, sans-serif;
font-size: 1em;
}

.button:active {
background: linear-gradient(#ddd, #eee);
}

.button:hover, button:focus {
box-shadow: 0 0 2px #222;
}

#execute {
margin-top: 5px;;
width: 10%;
min-width:100px;
}

.CodeMirror {
border: 1px solid #222;
height: auto;
}
.CodeMirror-scroll {
overflow-y: hidden;
overflow-x: auto;
}

.error {
color:red;
transition:.5s;
overflow:hidden;
}

#output {
overflow: auto;
}

table {
width:auto;
margin:auto;
border:1px solid black;
border-collapse:collapse;
margin-bottom:10px;
}

th, td {
border:1px solid #777;
}

footer {
font-size:.8em;
color: #222;
}
136 changes: 136 additions & 0 deletions examples/GUI/gui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
var execBtn = document.getElementById("execute");
var outputElm = document.getElementById('output');
var errorElm = document.getElementById('error');
var commandsElm = document.getElementById('commands');
var dbFileElm = document.getElementById('dbfile');
var savedbElm = document.getElementById('savedb');

// Start the worker in which sql.js will run
var worker = new Worker("/dist/worker.sql-wasm.js");
worker.onerror = error;

// Open a database
worker.postMessage({action:'open'});

// Connect to the HTML element we 'print' to
function print(text) {
outputElm.innerHTML = text.replace(/\n/g, '<br>');
}
function error(e) {
console.log(e);
errorElm.style.height = '2em';
errorElm.textContent = e.message;
}

function noerror() {
errorElm.style.height = '0';
}

// Run a command in the database
function execute(commands) {
tic();
worker.onmessage = function(event) {
var results = event.data.results;
toc("Executing SQL");

tic();
outputElm.innerHTML = "";
for (var i=0; i<results.length; i++) {
outputElm.appendChild(tableCreate(results[i].columns, results[i].values));
}
toc("Displaying results");
}
worker.postMessage({action:'exec', sql:commands});
outputElm.textContent = "Fetching results...";
}

// Create an HTML table
var tableCreate = function () {
function valconcat(vals, tagName) {
if (vals.length === 0) return '';
var open = '<'+tagName+'>', close='</'+tagName+'>';
return open + vals.join(close + open) + close;
}
return function (columns, values){
var tbl = document.createElement('table');
var html = '<thead>' + valconcat(columns, 'th') + '</thead>';
var rows = values.map(function(v){ return valconcat(v, 'td'); });
html += '<tbody>' + valconcat(rows, 'tr') + '</tbody>';
tbl.innerHTML = html;
return tbl;
}
}();

// Execute the commands when the button is clicked
function execEditorContents () {
noerror()
execute (editor.getValue() + ';');
}
execBtn.addEventListener("click", execEditorContents, true);

// Performance measurement functions
var tictime;
if (!window.performance || !performance.now) {window.performance = {now:Date.now}}
function tic () {tictime = performance.now()}
function toc(msg) {
var dt = performance.now()-tictime;
console.log((msg||'toc') + ": " + dt + "ms");
}

// Add syntax highlihjting to the textarea
var editor = CodeMirror.fromTextArea(commandsElm, {
mode: 'text/x-mysql',
viewportMargin: Infinity,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets : true,
autofocus: true,
extraKeys: {
"Ctrl-Enter": execEditorContents,
"Ctrl-S": savedb,
}
});

// Load a db from a file
dbFileElm.onchange = function() {
var f = dbFileElm.files[0];
var r = new FileReader();
r.onload = function() {
worker.onmessage = function () {
toc("Loading database from file");
// Show the schema of the loaded database
editor.setValue("SELECT `name`, `sql`\n FROM `sqlite_master`\n WHERE type='table';");
execEditorContents();
};
tic();
try {
worker.postMessage({action:'open',buffer:r.result}, [r.result]);
}
catch(exception) {
worker.postMessage({action:'open',buffer:r.result});
}
}
r.readAsArrayBuffer(f);
}

// Save the db to a file
function savedb () {
worker.onmessage = function(event) {
toc("Exporting the database");
var arraybuff = event.data.buffer;
var blob = new Blob([arraybuff]);
var a = document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = "sql.db";
a.onclick = function() {
setTimeout(function() {
window.URL.revokeObjectURL(a.href);
}, 1500);
};
a.click();
};
tic();
worker.postMessage({action:'export'});
}
savedbElm.addEventListener("click", savedb, true);
64 changes: 64 additions & 0 deletions examples/GUI/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!doctype html>
<html>
<head>
<meta charset="utf8">
<title>sql.js demo: Online SQL interpreter</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/codemirror.css">
<link rel="stylesheet" href="demo.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/codemirror.js"></script>

</head>
<body>
<!-- Github ribbon -->
<a href="https://github.com/kripken/sql.js"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://camo.githubusercontent.com/82b228a3648bf44fc1163ef44c62fcc60081495e/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f7265645f6161303030302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_red_aa0000.png"></a>

<h1>Online SQL interpreter</h1>

<main>
<label for='commands'>Enter some SQL</label>
<br>

<textarea id="commands">DROP TABLE IF EXISTS employees;
CREATE TABLE employees( id integer, name text,
designation text, manager integer,
hired_on date, salary integer,
commission float, dept integer);

INSERT INTO employees VALUES (1,'JOHNSON','ADMIN',6,'1990-12-17',18000,NULL,4);
INSERT INTO employees VALUES (2,'HARDING','MANAGER',9,'1998-02-02',52000,300,3);
INSERT INTO employees VALUES (3,'TAFT','SALES I',2,'1996-01-02',25000,500,3);
INSERT INTO employees VALUES (4,'HOOVER','SALES I',2,'1990-04-02',27000,NULL,3);
INSERT INTO employees VALUES (5,'LINCOLN','TECH',6,'1994-06-23',22500,1400,4);
INSERT INTO employees VALUES (6,'GARFIELD','MANAGER',9,'1993-05-01',54000,NULL,4);
INSERT INTO employees VALUES (7,'POLK','TECH',6,'1997-09-22',25000,NULL,4);
INSERT INTO employees VALUES (8,'GRANT','ENGINEER',10,'1997-03-30',32000,NULL,2);
INSERT INTO employees VALUES (9,'JACKSON','CEO',NULL,'1990-01-01',75000,NULL,4);
INSERT INTO employees VALUES (10,'FILLMORE','MANAGER',9,'1994-08-09',56000,NULL,2);
INSERT INTO employees VALUES (11,'ADAMS','ENGINEER',10,'1996-03-15',34000,NULL,2);
INSERT INTO employees VALUES (12,'WASHINGTON','ADMIN',6,'1998-04-16',18000,NULL,4);
INSERT INTO employees VALUES (13,'MONROE','ENGINEER',10,'2000-12-03',30000,NULL,2);
INSERT INTO employees VALUES (14,'ROOSEVELT','CPA',9,'1995-10-12',35000,NULL,1);

SELECT designation,COUNT(*) AS nbr, (AVG(salary)) AS avg_salary FROM employees GROUP BY designation ORDER BY avg_salary DESC;
SELECT name,hired_on FROM employees ORDER BY hired_on;</textarea>

<button id="execute" class="button">Execute</button>
<button id='savedb' class="button">Save the db</button>
<label class="button">Load an SQLite database file: <input type='file' id='dbfile' ></label>

<div id="error" class="error"></div>

<pre id="output">Results will be displayed here</pre>
</main>

<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/mode/sql/sql.min.js"></script>

<footer>
Original work by kripken (<a href='https://github.com/kripken/sql.js'>sql.js</a>).
C to Javascript compiler by kripken (<a href='https://github.com/kripken/emscripten'>emscripten</a>).
Project now maintained by <a href='https://github.com/lovasoa'>lovasoa</a>
</footer>

<script type="text/javascript" src="gui.js"></script>
</body>
</html>
6 changes: 6 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

To show these examples locally, first run:
./start_local_server.py

Then, open http://localhost:8081/index.html in a local browser.

66 changes: 66 additions & 0 deletions examples/persistent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!doctype html>
<html>
<head>
<meta charset="utf8">
<title>Persistent sqlite</title>
<script src="/dist/sql-wasm.js"></script>
</head>
<body>
<p>You have seen this page <span id="views">0</span> times.</p>
<div>
You have been here on the following dates: <ol id="dates"></ol>
</div>
<script>

function toBinArray (str) {
var l = str.length,
arr = new Uint8Array(l);
for (var i=0; i<l; i++) arr[i] = str.charCodeAt(i);
return arr;
}

function toBinString (arr) {
var uarr = new Uint8Array(arr);
var strings = [], chunksize = 0xffff;
// There is a maximum stack size. We cannot call String.fromCharCode with as many arguments as we want
for (var i=0; i*chunksize < uarr.length; i++){
strings.push(String.fromCharCode.apply(null, uarr.subarray(i*chunksize, (i+1)*chunksize)));
}
return strings.join('');
}

// Normally Sql.js tries to load sql-wasm.wasm relative to the page, not relative to the javascript
// doing the loading. So, we help it find the .wasm file with this function.
var config = {
locateFile: filename => `${baseUrl}/${filename}`
}
initSqlJs(config).then(function(SQL){
var dbstr = window.localStorage.getItem("viewcount.sqlite");
if (dbstr) {
var db = new SQL.Database(toBinArray(dbstr));
} else {
var db = new SQL.Database();
db.run("CREATE TABLE views (date INTEGER PRIMARY KEY)");
}
db.run("INSERT INTO views(date) VALUES (?)", [Date.now()]);

document.getElementById('views').textContent = db.exec("SELECT COUNT(*) FROM views")[0].values[0][0];

var count = 0,
dates = document.getElementById("dates");

db.each("SELECT date FROM views ORDER BY date ASC",
function callback (row) {
var li = document.createElement("li");
li.textContent = new Date(row.date);
dates.appendChild(li);
}, function done () {
var dbstr = toBinString(db.export());
window.localStorage.setItem("viewcount.sqlite", dbstr);
}
);
});

</script>
</body>
</html>
Loading

0 comments on commit 77ad0d3

Please sign in to comment.