Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
19 changed files
with
7,696 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.test.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "standard", | ||
"rules": { | ||
"space-before-function-paren": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
|
||
# ignore sqlite databases | ||
*.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"editor.tabSize": 2 | ||
} |
26
app.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* Creates a common Koa app | ||
*/ | ||
|
||
'use strict' | ||
|
||
const path = require('path') | ||
|
||
const Koa = require('koa') | ||
const Views = require('koa-views') | ||
|
||
const app = new Koa() | ||
const handlebars = new Views( | ||
path.join(__dirname, '/views'), | ||
{ | ||
map: { hbs: 'handlebars' }, | ||
extension: 'hbs' | ||
} | ||
) | ||
|
||
const login = require('./controllers/login') | ||
|
||
app.use(handlebars) | ||
app.use(login.routes()) | ||
|
||
module.exports = app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env node | ||
|
||
'use strict' | ||
|
||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
const sqlite = require('sqlite') | ||
|
||
sqlite.open('app.db').then(db => { | ||
const sqlPath = path.join(__dirname, 'build_db.sql') | ||
fs.readFile(sqlPath, 'utf8', async (err, sql) => { | ||
if (err) { | ||
console.error(err) | ||
process.exit(1) | ||
} | ||
|
||
await db.exec(sql) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
CREATE TABLE `users` | ||
( | ||
`id` INTEGER PRIMARY KEY AUTOINCREMENT, | ||
`username` TEXT UNIQUE, | ||
`hash` TEXT | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict' | ||
|
||
const Router = require('koa-router') | ||
|
||
const apiRouter = new Router({ prefix: '/api' }) | ||
|
||
module.export = apiRouter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict' | ||
|
||
const Router = require('koa-router') | ||
|
||
const login = new Router({ prefix: '/login' }) | ||
|
||
login.get('/', async ctx => { | ||
await ctx.render('login.hbs') | ||
}) | ||
|
||
login.post('/', async ctx => { | ||
console.log(ctx.query) | ||
console.log(ctx.querystring) | ||
}) | ||
|
||
module.exports = login |
93
db.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Database controller | ||
*/ | ||
|
||
const sqlite = require('sqlite') | ||
|
||
const User = require('./models/user') | ||
|
||
class DbContext { | ||
async getUsers() { } | ||
async getUser(id) { } | ||
async deleteUser(id) { } | ||
async createUser(user) { } | ||
async updateUser(user) { } | ||
|
||
async execute(query) { } | ||
} | ||
|
||
class SqliteDbContext extends DbContext { | ||
constructor(filename) { | ||
super() | ||
|
||
this.sqlitePromise = sqlite.open(filename, { Promise }) | ||
} | ||
|
||
async getUser(id) { | ||
const sqlite = await this.sqlitePromise | ||
|
||
let query | ||
|
||
if (typeof id === 'number') { | ||
query = 'SELECT * FROM `users` WHERE `id` = ?;' | ||
} else if (typeof id === 'string') { | ||
query = 'SELECT * FROM `users` WHERE `username` = ?;' | ||
} else { | ||
throw new TypeError('id must be number or string') | ||
} | ||
|
||
const user = await sqlite.get(query, id) | ||
return Object.assign(new User(), user) | ||
} | ||
|
||
async getUsers() { | ||
const sqlite = await this.sqlitePromise | ||
|
||
const users = await sqlite.all('SELECT * FROM `users`;') | ||
return users.map(x => Object.assign(new User(), x)) | ||
} | ||
|
||
async deleteUser(id) { | ||
const sqlite = await this.sqlitePromise | ||
|
||
let query | ||
|
||
if (typeof id === 'number') { | ||
query = 'DELETE FROM `users` WHERE `id` = ?;' | ||
} else if (typeof id === 'string') { | ||
query = 'DELETE FROM `users` WHERE `username` = ?;' | ||
} else { | ||
throw new TypeError('id must be number or string') | ||
} | ||
|
||
await sqlite.run(query, id) | ||
} | ||
|
||
async createUser(user) { | ||
const sqlite = await this.sqlitePromise | ||
|
||
const { lastID } = await sqlite.run( | ||
'INSERT INTO `users` (`username`, `hash`) VALUES (?, ?);', | ||
user.username, | ||
user.hash | ||
) | ||
return this.getUser(lastID) | ||
} | ||
|
||
async updateUser(user) { | ||
const sqlite = await this.sqlitePromise | ||
|
||
await sqlite.run( | ||
'UPDATE `users` SET `username` = ?, `hash` = ? WHERE `id` = ?;', | ||
user.username, | ||
user.hash, | ||
user.id | ||
) | ||
return this.getUser(user.id) | ||
} | ||
} | ||
|
||
module.exports = { | ||
DbContext, | ||
SqliteDbContext | ||
} |
68
db.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
const db = require('./db') | ||
|
||
const User = require('./models/user') | ||
|
||
// create an in memory db | ||
const sqliteContext = new db.SqliteDbContext(':memory:') | ||
|
||
describe('user database', () => { | ||
beforeEach(async () => { | ||
await sqliteContext.sqlitePromise.then(async db => { | ||
// clear table | ||
await db.exec('DROP TABLE IF EXISTS `users`;') | ||
|
||
// create user table | ||
await db.exec('CREATE TABLE `users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `username` TEXT UNIQUE, `hash` TEXT);') | ||
|
||
// insert test users | ||
await db.exec('INSERT INTO `users` VALUES (10, \'hakasec\', \'test\'), (11, \'hello\', \'world\');') | ||
}) | ||
}) | ||
|
||
test('should get a user by id', async () => { | ||
expect(await sqliteContext.getUser(10)) | ||
.toEqual({ id: 10, username: 'hakasec', hash: 'test' }) | ||
}); | ||
|
||
test('should get a user by username', async () => { | ||
expect(await sqliteContext.getUser('hakasec')) | ||
.toEqual({ id: 10, username: 'hakasec', hash: 'test' }) | ||
}) | ||
|
||
test('should get all users', async () => { | ||
expect(await sqliteContext.getUsers()) | ||
.toContainEqual({ id: 11, username: 'hello', hash: 'world' }) | ||
}) | ||
|
||
test('should create a user', async () => { | ||
const user = await sqliteContext.createUser(new User('hello1', 'world')) | ||
expect(user.id).not.toEqual(-1) | ||
}) | ||
|
||
test('should delete a user by id', async () => { | ||
await sqliteContext.deleteUser(10) | ||
|
||
const userCheck = await sqliteContext.sqlitePromise.then(db => { | ||
return db.get('SELECT * FROM `users` WHERE `id` = 10;') | ||
}) | ||
|
||
expect(userCheck).toBe(undefined) | ||
}) | ||
|
||
test('should delete a user by username', async () => { | ||
await sqliteContext.deleteUser('hakasec') | ||
|
||
const userCheck = await sqliteContext.sqlitePromise.then(db => { | ||
return db.get('SELECT * FROM `users` WHERE `id` = \'hakasec\';') | ||
}) | ||
|
||
expect(userCheck).toBe(undefined) | ||
}) | ||
|
||
test('should update a user', async () => { | ||
let user = await sqliteContext.getUser('hakasec') | ||
user.hash = 'test1' | ||
|
||
expect(await sqliteContext.updateUser(user)).toEqual(user) | ||
}) | ||
}) |
14
index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/usr/bin/env node | ||
|
||
const path = require('path') | ||
|
||
const db = require('./db') | ||
|
||
const dbcontext = new db.SqliteDbContext(path.join(__dirname, 'app.db')) | ||
|
||
const app = require('./app') | ||
|
||
// inject the db context | ||
app.context.db = dbcontext | ||
|
||
app.listen(8080) |
Oops, something went wrong.