Skip to content
Permalink
Browse files
created todo app with database
  • Loading branch information
aa7401 committed Sep 13, 2019
1 parent 934a8b2 commit d2a6180cf6f1b0c141ffc286c4417acff9cd1334
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 295 deletions.
@@ -27,3 +27,4 @@ website.db
*.c9

messages.txt
todo.db
@@ -0,0 +1,61 @@
#!/usr/bin/env node

'use strict'

const Koa = require('koa')
const Router = require('koa-router')
const stat = require('koa-static')
const bodyParser = require('koa-bodyparser')
const handlebars = require('koa-hbs-renderer')

const app = new Koa()
const router = new Router()
app.use(stat('public'))
app.use(bodyParser())
app.use(handlebars({ paths: { views: `${__dirname}/views` } }))
app.use(router.routes())

const port = 8080
const dbName = 'todo.db'

const ToDo = require('./modules/todo')

router.get('/', async ctx => {
try {
const todo = await new ToDo(dbName)
const data = {}
if(ctx.query.msg) data.msg = ctx.query.msg
data.items = await todo.getAll()
console.log('all records')
console.log(data)
ctx.render('home', data)
} catch(err) {
console.log(err.message)
ctx.render('home', {msg: err.message})
}
})

router.post('/', async ctx => {
try {
const todo = await new ToDo(dbName)
const body = ctx.request.body
todo.add(body.item, body.qty)
ctx.redirect('/')
} catch(err) {
console.log(err.message)
ctx.redirect(`/?msg=${err.message}`)
}
})

router.get('/delete/:key', ctx => {
try {
console.log(`key: ${ctx.params.key}`)
todo.delete(ctx.params.key)
ctx.redirect('/msg=item deleted')
} catch(err) {
console.log(err.message)
ctx.redirect(`/${err.message}`)
}
})

module.exports = app.listen(port, () => console.log(`listening on port ${port}`))
@@ -0,0 +1,45 @@

'use strict'

const sqlite = require('sqlite-async')

module.exports = class ToDo {

constructor(dbName = ':memory:') {
return (async() => {
this.db = await sqlite.open(dbName)
const sql = 'CREATE TABLE IF NOT EXISTS items(id INTEGER PRIMARY KEY AUTOINCREMENT, item TEXT, qty NUMERIC)'
await this.db.run(sql)
return this
})()
}

async add(item, qty) {
qty = Number(qty)
if(isNaN(qty)) throw new Error('the quantity must be a number')
const sql = `INSERT INTO items(item, qty) VALUES("${item}", ${qty})`
await this.db.run(sql)
}

async getAll() {
const sql = 'SELECT * FROM items'
const data = await this.db.all(sql)
console.log(data)
return data
}

async delete(id) {
const sql = `DELETE FROM items WHERE id=${id}`
await this.db.run(sql)
}

async countItems() {
const sql = 'SELECT COUNT(*) as items FROM items'
const data = await this.db.get(sql)
return data
}

}

// https://stackoverflow.com/questions/43431550/async-await-class-constructor
// https://www.sqlite.org/inmemorydb.html
@@ -0,0 +1,19 @@
{
"name": "database",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"koa": "^2.8.1",
"koa-bodyparser": "^4.2.1",
"koa-hbs-renderer": "^1.2.0",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"sqlite-async": "^1.0.12"
}
}
@@ -0,0 +1,11 @@

body {
font-family: Arial, Helvetica, sans-serif;
}

.msg {
border: 1px solid red;
font-weight: bold;
color: red;
padding: 1em;
}
@@ -0,0 +1,33 @@

'use strict'
/*
const sqlite = require('sqlite-async')
const db = await sqlite.open('./website.db')
await db.run('xxx')
const records = await db.get('xxx')
await db.close()
*/

module.exports.open = async name => {
// opens a connection
console.log(name)
return new DB()
}

class DB {
async run(query) {
// runs a query
console.log('run')
console.log(query)
}
async get(query) {
// runs a query and returns data
console.log('get')
console.log(query)
return ['bread', 'butter', 'cheese']
}
async close() {
// closes the connection
console.log('close')
}
}
@@ -0,0 +1,33 @@

<!DOCTYPE html>
<html>
<head>
<title>ToDo List</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>ToDo List</h1>
<h2>My List</h2>
{{#if msg}}
<p class="msg">{{msg}}</p>
{{/if}}
{{#if items.length}}
<table>
<caption>Shopping List</caption>
<tr><th>Item</th><th>Qty</th><th>Action</th></tr>
{{#each items}}
<tr><td>{{this.item}}</td><td>{{this.qty}}</td><td><a href="/delete/{{this.key}}">delete</a></td></tr>
{{/each}}
</table>
{{else}}
<h2>Your list is empty, lets add some items...</h2>
{{/if}}
<form method="post" action="/">
Item:
<input type="text" name="item" />
Qty:
<input type="text" name="qty" />
<input type="submit" value="Add Item" />
</form>
</body>
</html>

This file was deleted.

0 comments on commit d2a6180

Please sign in to comment.