123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- const isStr = require('./isStr');
- const isObj = require('./isObj');
- const each = require('./each');
- const Emitter = require('./Emitter');
- const toArr = require('./toArr');
- const unique = require('./unique');
- const concat = require('./concat');
- const keys = require('./keys');
- const fs = require('fs');
- exports = Emitter.extend({
- initialize: function FileBlobStore(path, data) {
- this.callSuper(Emitter, 'initialize', arguments);
- this._path = path;
- this._mapPath = path + '.MAP';
- this._lockPath = path + '.LOCK';
- this._data = data || {};
- let storedBlob = Buffer.alloc(0);
- let storedBlobMap = {};
- if (fs.existsSync(path) && fs.existsSync(this._mapPath)) {
- try {
- storedBlob = fs.readFileSync(path);
- storedBlobMap = JSON.parse(fs.readFileSync(this._mapPath));
- } catch (e) {
- storedBlobMap = {};
- storedBlob = Buffer.alloc(0);
- }
- }
- this._storedBlob = storedBlob;
- this._storedBlobMap = storedBlobMap;
- },
- set(key, buf) {
- let data;
- if (isStr(key)) {
- data = {};
- data[key] = buf;
- } else if (isObj(key)) {
- data = key;
- }
- each(data, (buf, key) => {
- const oldBuf = this.get(key);
- this._data[key] = buf;
- this.emit('change', key, buf, oldBuf);
- });
- },
- get(key) {
- if (isStr(key)) {
- return this._get(key);
- }
- const ret = {};
- each(key, val => {
- ret[val] = this._get(val);
- });
- return ret;
- },
- remove(key) {
- key = toArr(key);
- const data = this._data;
- const storedBlobMap = this._storedBlobMap;
- each(key, val => {
- delete data[val];
- delete storedBlobMap[val];
- });
- },
- clear() {
- this._data = {};
- this._storedBlob = Buffer.alloc(0);
- this._storedBlobMap = {};
- },
- each(fn) {
- const allKeys = this._getKeys();
- each(allKeys, key => {
- fn(this._get(key), key);
- });
- },
- save() {
- const dump = this._getDump();
- const blobToStore = Buffer.concat(dump[0]);
- const mapToStore = JSON.stringify(dump[1]);
- let lock = false;
- try {
- fs.writeFileSync(this._lockPath, 'LOCK', { flag: 'wx' });
- lock = true;
- fs.writeFileSync(this._path, blobToStore);
- fs.writeFileSync(this._mapPath, mapToStore);
- } catch (error) {
- if (error.code !== 'EEXIST') {
- throw error;
- }
- } finally {
- if (lock) {
- fs.unlinkSync(this._lockPath);
- }
- }
- },
- _get(key) {
- return this._data[key] || this._getFromStorage(key);
- },
- _getFromStorage(key) {
- if (!this._storedBlobMap[key]) {
- return;
- }
- const [start, end] = this._storedBlobMap[key];
- return this._storedBlob.slice(start, end);
- },
- _getDump() {
- const buffers = [];
- const blobMap = {};
- let curBufStart = 0;
- function dump(buf, key) {
- buffers.push(buf);
- const len = buf.length;
- blobMap[key] = [curBufStart, curBufStart + len];
- curBufStart += len;
- }
- this.each(dump);
- return [buffers, blobMap];
- },
- _getKeys() {
- return unique(concat(keys(this._data), keys(this._storedBlobMap)));
- }
- });
- module.exports = exports;
|