Fixes #97: SQLite is now async, optimized, tests
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* cli.ts
|
||||
*
|
||||
* A simple clone of the sqlite3 command line
|
||||
* interface, build using deno-sqlite.
|
||||
*
|
||||
* This is an example, meant to illustrate using
|
||||
* the API provided by deno-sqlite.
|
||||
*/
|
||||
|
||||
import { readLines, writeAll } from "https://deno.land/std@0.134.0/io/mod.ts";
|
||||
import AsciiTable from "https://deno.land/x/ascii_table@v0.1.0/mod.ts";
|
||||
import { DB } from "../mod.ts";
|
||||
|
||||
const db = new DB(Deno.args[0] ?? undefined);
|
||||
|
||||
async function print(str: string) {
|
||||
const enc = new TextEncoder();
|
||||
await writeAll(Deno.stdout, enc.encode(str));
|
||||
}
|
||||
|
||||
async function prompt() {
|
||||
await print("sqlite> ");
|
||||
}
|
||||
|
||||
const tablesQuery = db.prepareQuery<[string]>(
|
||||
"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'",
|
||||
);
|
||||
|
||||
const commands: Record<string, () => Promise<void>> = {
|
||||
"tables": async () => {
|
||||
for (const [name] of tablesQuery.iter()) {
|
||||
await print(`${name}\n`);
|
||||
}
|
||||
},
|
||||
"quit": async () => {
|
||||
await print("\n");
|
||||
Deno.exit(0);
|
||||
},
|
||||
"help": async () => {
|
||||
await print(
|
||||
"Type an SQL query or run a command.\nThe following commands are available:\n",
|
||||
);
|
||||
for (const key in commands) {
|
||||
await print(`.${key}\n`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
await prompt();
|
||||
for await (const cmd of readLines(Deno.stdin)) {
|
||||
if (cmd[0] === ".") {
|
||||
const action = commands[cmd.slice(1)] ??
|
||||
(() => print("Unrecognized command, try .help\n"));
|
||||
await action();
|
||||
} else {
|
||||
try {
|
||||
const query = db.prepareQuery(cmd);
|
||||
const rows = query.all();
|
||||
const cols = query.columns();
|
||||
query.finalize();
|
||||
|
||||
if (cols.length) {
|
||||
const table = new AsciiTable();
|
||||
table.setHeading("#", ...cols.map(({ name }) => name));
|
||||
for (const [idx, row] of rows.entries()) {
|
||||
table.addRow(idx + 1, ...row);
|
||||
}
|
||||
print(table.toString());
|
||||
print("\n");
|
||||
} else {
|
||||
print(`Executed query: ${db.changes} changes\n`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
await prompt();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* notes.ts
|
||||
*
|
||||
* A command line tool to manage a set
|
||||
* of simple notes.
|
||||
*
|
||||
* This is an example, meant to illustrate using
|
||||
* the API provided by deno-sqlite.
|
||||
*/
|
||||
|
||||
import { DB } from "../mod.ts";
|
||||
|
||||
const commands: Record<string, (...args: string[]) => Promise<void> | void> = {
|
||||
"create": (file: string) => {
|
||||
const db = new DB(file, { mode: "create" });
|
||||
db.query(`
|
||||
CREATE TABLE notes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
note TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
db.close();
|
||||
console.log("Database created!");
|
||||
},
|
||||
"record": (file: string, note: string) => {
|
||||
const db = new DB(file, { mode: "write" });
|
||||
db.query("INSERT INTO notes (note, created_at) VALUES (?, ?)", [
|
||||
note,
|
||||
new Date(),
|
||||
]);
|
||||
db.close();
|
||||
console.log("Note recorded!");
|
||||
},
|
||||
"delete": (file: string, noteId: string) => {
|
||||
const db = new DB(file, { mode: "write" });
|
||||
db.query("DELETE FROM notes WHERE id = ?", [noteId]);
|
||||
db.close();
|
||||
console.log("Note deleted!");
|
||||
},
|
||||
"list": (file: string) => {
|
||||
const db = new DB(file, { mode: "read" });
|
||||
const query = db.prepareQuery<[number, string, string]>(
|
||||
"SELECT id, note, created_at FROM notes ORDER BY created_at DESC",
|
||||
);
|
||||
for (const [id, note, createdAt] of query.iter()) {
|
||||
const date = new Date(createdAt);
|
||||
console.log(`Note #${id} (recorded ${date.toLocaleString()})\n${note}\n`);
|
||||
}
|
||||
query.finalize();
|
||||
db.close();
|
||||
},
|
||||
};
|
||||
|
||||
const command = commands[Deno.args[0]] ??
|
||||
(() => console.error(`Unknown command '${Deno.args[0]}'.`));
|
||||
await command(...Deno.args.slice(1));
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* server.ts
|
||||
*
|
||||
* A server which returns the number
|
||||
* of hits to any given path since
|
||||
* the server started running.
|
||||
*
|
||||
* This is an example, meant to illustrate using
|
||||
* the API provided by deno-sqlite.
|
||||
*/
|
||||
|
||||
import { serve } from "https://deno.land/std@0.134.0/http/mod.ts";
|
||||
import { DB } from "../mod.ts";
|
||||
|
||||
const db = new DB();
|
||||
|
||||
db.query(`
|
||||
CREATE TABLE visits (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
url TEXT NOT NULL,
|
||||
visited_at TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
const addVisitQuery = db.prepareQuery(
|
||||
"INSERT INTO visits (url, visited_at) VALUES (:url, :time)",
|
||||
);
|
||||
const countVisitsQuery = db.prepareQuery<[number]>(
|
||||
"SELECT COUNT(*) FROM visits WHERE url = :url",
|
||||
);
|
||||
|
||||
console.log("Running server on localhost:8080");
|
||||
|
||||
await serve((req) => {
|
||||
addVisitQuery.execute({
|
||||
url: req.url,
|
||||
time: new Date(),
|
||||
});
|
||||
|
||||
const [count] = countVisitsQuery.one({ url: req.url });
|
||||
return new Response(`This page was visited ${count} times!`);
|
||||
}, { port: 8080 });
|
||||
Reference in New Issue
Block a user