Skip to content

Commit

Permalink
Update FsProvider
Browse files Browse the repository at this point in the history
PR-URL: #310
  • Loading branch information
SemenchenkoVitaliy committed Apr 11, 2019
1 parent a018075 commit 2fe3c88
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 127 deletions.
147 changes: 89 additions & 58 deletions lib/fs.provider.js
Original file line number Diff line number Diff line change
@@ -1,148 +1,179 @@
'use strict';

const fs = require('fs');
const mkdirp = require('mkdirp');
const common = require('@metarhia/common');
const { FileStorage } = require('@metarhia/filestorage');
const metasync = require('metasync');
const mdsf = require('mdsf');

const { StorageProvider } = require('./provider');
const { FsCursor } = require('./fs.cursor');

const readStat = Symbol('readStat');
const writeStat = Symbol('writeStat');

const THROTTLE_TIMEOUT = 5000;

class FsProvider extends StorageProvider {
constructor(
options // { path } where path is database location
) {
// Create FsProvider
// options <Object>
constructor(options) {
super(options);
this.stat = null;
this.storage = null;
this.dbOptions = {};
}

readStat(callback) {
fs.readFile(this.path + '/.gs', (err, stat) => {
// Read storage stats
// callback - <Function>
// err - <Error>
// data - <Object>, database stats
[readStat](callback) {
fs.readFile(this.path + '/.gs', 'utf8', (err, stat) => {
if (err) {
callback(err);
callback(err, this);
return;
}
const data = mdsf.parse(stat.toString());
const data = mdsf.parse(stat);
data.count = data.count || 0;
data.size = data.size || 0;
data.next = data.next || 1;
callback(null, data);
});
}

open(options, callback) {
// Write storage stats
// callback - <Function>
// err - <Error>
[writeStat](callback) {
callback = common.once(callback);
const save = () => {
const data = mdsf.stringify(this.stat);
fs.writeFile(this.path + '/.gs', data, callback);
};
this.save = this.save || metasync.throttle(THROTTLE_TIMEOUT, save);
this.save();
}

// Open FsProvider
// options - <Object>
// path - <string>
// minCompressSize - <number>
// checksum - <string>, checksum type
// dedupHash - <string>, second checksum type
// callback - <Function>
// err - <Error>
open(options, callback) {
this.path = options.path;
this.dbOptions.checksum = options.checksum;
this.dbOptions.dedupHash = options.dedupHash;
super.open(options, () => {
this.readStat((err, stat) => {
this[readStat]((err, stat) => {
if (err) {
callback(new Error('Can not open database: ' + this.path));
} else {
this.stat = stat;
this.active = true;
callback();
return;
}
this.stat = stat;
this.active = true;
this.storage = new FileStorage(
Object.assign({ dir: options.path }, options)
);
callback(null, this);
});
});
}

writeStat(callback) {
callback = common.once(callback);
const save = () => {
const data = mdsf.stringify(this.stat);
fs.writeFile(this.path + '/.gs', data, callback);
};
this.save = this.save || metasync.throttle(THROTTLE_TIMEOUT, save);
this.save();
}

// Close FsProvider
// callback - <Function>
close(callback) {
callback = common.once(callback);
this.writeStat();
this[writeStat]();
this.active = false;
callback();
}

// Generate unique id
// callback - <Function>
// err - <Error>
// id - <number>
takeId(callback) {
callback = common.once(callback);
callback(null, this.stat.next++);
this.stat.count++;
this.writeStat();
this[writeStat]();
}

// Get record from GlobalStorage
// id - <number>
// callback - <Function>
// err - <Error>
// data - <Object>
get(id, callback) {
callback = common.once(callback);
const path = common.idToPath(id);
fs.readFile(path, (err, data) => {
this.storage.read(id, this.dbOptions, (err, data) => {
if (err) callback(err);
else callback(null, mdsf.parse(data.toString()));
});
}

// Create record in GlobalStorage
// obj - <Object>
// callback - <Function>
// err - <Error>
// id - <number>
create(obj, callback) {
callback = common.once(callback);
this.takeId((err, id) => {
if (err) {
callback(err);
return;
}
obj.Id = id;
const data = mdsf.stringify(obj);
this.stat.size += data.length;
this.writeStat();
const place = common.idToChunks(obj.Id);
place.path = this.path + place.path;
mkdirp(place.path, err => {
this.storage.write(id, data, this.dbOptions, (err, stats) => {
if (err) {
callback(err);
return;
}
const pp = place.path + '/' + place.name;
fs.writeFile(pp, data, err => {
if (err) callback(err);
else callback(null, id);
});
this.stat.size += stats.size;
this[writeStat]();
callback(null, id);
});
});
}

// Update record in GlobalStorage
// obj - <Object>
// Id - <number>
// callback - <Function>
// err - <Error>
update(obj, callback) {
callback = common.once(callback);
const path = common.idToPath(obj.Id);
fs.stat(path, (err, stat) => {
const data = mdsf.stringify(obj);
this.storage.update(obj.Id, data, this.dbOptions, (err, stats) => {
if (err) {
callback(err);
return;
}
const data = mdsf.stringify(obj);
this.stat.size += data.length - stat.size;
this.writeStat();
fs.writeFile(path, data, err => {
if (err) callback(err);
else callback();
});
this.stat.size += stats.size - stats.originalSize;
this[writeStat]();
callback();
});
}

// Delete record from GlobalStorage
// id - <number>
// callback - <Function>
// err - <Error>
delete(id, callback) {
callback = common.once(callback);
const path = common.idToPath(id);
fs.stat(path, (err, stat) => {
this.storage.stat(id, (err, stats) => {
if (err) {
callback(err);
return;
}
fs.unlink(path, err => {
this.storage.rm(id, err => {
if (err) {
callback(err);
return;
}
this.stat.count--;
this.stat.size -= stat.size;
this.writeStat();
this.stat.size -= stats.size;
this[writeStat]();
callback();
});
});
Expand Down
Loading

0 comments on commit 2fe3c88

Please sign in to comment.