-
Notifications
You must be signed in to change notification settings - Fork 1
/
db.js
68 lines (55 loc) · 1.74 KB
/
db.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
The database is a set of files, which maintain records in simple binary format
db/message (total 256 bytes)
timestamp (4 bytes)
room (12 bytes, ascii)
username (16 bytes, ascii)
text (224 bytes, ascii)
*/
const assert = require('assert')
const fs = require('fs')
const unpack = (buf) => buf.toString('ascii', 0, buf.indexOf(0x00))
// Given a JS object representing a message, return a buffer ready to write to db
const _serializeMessage = (message) => {
const buf = Buffer.alloc(256, 0)
buf.writeUInt32BE(message.timestamp)
buf.write(message.room, 4, 12, 'ascii')
buf.write(message.username, 16, 16, 'ascii')
buf.write(message.text, 32, 224, 'ascii')
return buf
}
// Given a buffer representing a db record of a message, return a JS object
const _deserializeMessage = (buf) => {
return {
timestamp: buf.readUInt32BE(),
room: unpack(buf.slice(4, 16)),
username: unpack(buf.slice(16, 32)),
text: unpack(buf.slice(32, 256)),
}
}
// Serialize a chat message for storage as db record
const insertMessage = (room, username, text) => {
const message = {
timestamp: Math.floor(Date.now() / 1000),
room,
username,
text
}
const record = _serializeMessage(message)
assert.deepEqual(message, _deserializeMessage(record))
fs.appendFileSync('db/messages', record)
return message
}
// Select and return all messages
const selectMessages = () => {
const recordsBytes = fs.readFileSync('db/messages')
const messages = []
for (let i = 0; i < recordsBytes.length; i += 256) {
messages.push(_deserializeMessage(recordsBytes.slice(i, i + 256)))
}
return messages
}
module.exports = {
insertMessage,
selectMessages
}