-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
71 lines (59 loc) · 1.51 KB
/
index.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
69
70
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var crypto = require('crypto');
var sqlite3 = require('sqlite3');
var dbPath = process.env.DBPATH || path.join(__dirname, '/db');
var db = new sqlite3.Database(dbPath);
function getScript(name) {
var p = path.join(__dirname, 'sql', name + '.sql');
return fs.readFileSync(p, { encoding: 'utf8' });
}
var sql = [
'init',
'add',
'recent',
'lookup',
'increment',
'clean'
].reduce(function(o, n) { o[n] = getScript(n); return o; }, {});
db.serialize(function() { db.run(sql.init); });
module.exports = {
add: add,
recent: recent,
lookup: lookup,
clean: clean,
_db: db
};
function add(url, cb) {
var id = shorten(url);
var ts = Date.now();
db.run(sql.add, { $id: id, $url: url, $ts: ts }, after);
function after(err) {
cb(err, err ? undefined : id);
}
}
function shorten(url) {
return crypto
.createHash('sha1')
.update(url)
.digest('base64')
.replace(/[=+/]/g, '')
.slice(0, 6);
}
function recent(count, cb) {
assert(typeof count === 'number', 'count must be a number');
assert(count > 0, 'count must be bigger than zero');
assert(Math.floor(count) === count, 'count must be an intiger');
db.all(sql.recent, { $limit: count }, cb);
}
function lookup(id, cb) {
db.serialize(function() {
db.run(sql.increment, { $id: id });
db.get(sql.lookup, { $id: id }, after);
});
function after(err, res) { cb(err, res && res.url); }
}
function clean(cb) {
db.run(sql.clean, cb);
}