forked from creationix/git-fs-db
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfs-db.js
129 lines (113 loc) · 3.29 KB
/
fs-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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
module.exports = function (platform) {
var isHash = /^[a-z0-9]{40}$/;
return fsDb;
function fsDb(fs) {
var inflate = platform.inflate;
var deflate = platform.deflate;
return {
get: get,
set: set,
has: has,
del: del,
keys: keys,
init: init,
clear: clear,
};
function get(key, callback) {
if (!callback) return get.bind(this, key);
if (isHash.test(key)) {
return fs.read(hashToPath(key), function (err, deflated) {
if (err) return callback(err);
return inflate(deflated, callback);
});
}
return fs.read(key, "ascii")(callback);
}
function set(key, value, callback) {
if (!callback) return set.bind(this, key, value);
if (isHash.test(key)) {
return deflate(value, function (err, deflated) {
if (err) return callback(err);
return write(hashToPath(key), deflated, callback);
});
}
return write(key, value, callback);
}
function write(path, data, callback) {
return mkdirp(dirname(path), function (err) {
if (err) return callback(err);
return fs.write(path, data)(callback);
});
}
function del(key, callback) {
if (!callback) return del.bind(this, key);
if (isHash.test(key)) {
return unlink(hashToPath(key), callback);
}
return unlink(key, callback);
}
function unlink(path, callback) {
fs.unlink(path, function (err) {
if (err) return callback(err);
clean(dirname(path));
});
function clean(dir) {
if (dir.length <= 1) return callback();
return fs.rmdir(dir, function (err) {
if (!err) return clean(dirname(dir));
if (err.code === "ENOTEMPTY" || err.code === "ENOENT") {
return callback();
}
return callback(err);
});
}
}
function has(key, callback) {
if (!callback) return has.bind(this, key);
if (isHash.test(key)) {
return fs.stat(hashToPath(key), onStat);
}
return fs.stat(key, onStat);
function onStat(err) {
if (err) {
if (err.code === "ENOENT") return callback();
return callback(err);
}
return callback(null, true);
}
}
function keys(prefix, callback) {
if (!callback) return keys.bind(this, prefix);
return fs.readdir(prefix || "/", callback);
}
function hashToPath(hash) {
return "objects/" + hash.substr(0, 2) + "/" + hash.substr(2);
}
function mkdirp(path, callback) {
fs.mkdir(path)(function (err) {
if (!err || err.code === "EEXIST") return callback();
if (err.code === "ENOENT") {
return mkdirp(dirname(path), function (err) {
if (err) return callback(err);
mkdirp(path, callback);
});
}
return callback(err);
});
}
function init(callback) {
if (!callback) return init.bind(this);
callback();
}
function clear(callback) {
if (!callback) return clear.bind(this);
callback(new Error("TODO: rm-rf the directory"));
}
}
};
function dirname(path) {
var index = path.lastIndexOf("/");
if (index < 0) return ".";
if (index === 0) return "/";
return path.substr(0, index);
}