UNPKG

dl

Version:

DreamLab Libs

220 lines (190 loc) 6.74 kB
var fs = require('fs'); var Path = require('path'); var Core = require('core'); var Assertions = Core.common.Assertions; var Types = Core.common.Types; var VALUE_MAGIC_FILE = '.value'; var AbstractDataProvider = require('./AbstractDataProvider.js').AbstractDataProvider; var FilesDataProvider = function (rootPath) { AbstractDataProvider.call(this, rootPath); Assertions.isString(rootPath, FilesDataProvider.Exception.BAD_FILE_NAME); this._rootPath = rootPath; this._watches = {}; }; FilesDataProvider.prototype = Object.create(AbstractDataProvider.prototype); FilesDataProvider.prototype.init = function (callback) { var that = this; fs.stat(this._rootPath, function (error, stats) { if (error) { if (error.code != "ENOENT") { callback(error, null); return; } else { fs.mkdir(that._rootPath, '0777', function (error) { if (error) { callback(error, null); return; } callback(null, true); }); } return; } callback(null, true); }); }; FilesDataProvider.prototype.destroy = function () { for (var key in this._watches) { if (this._watches.hasOwnProperty(key)) { this.unwatch(key); } } }; FilesDataProvider.prototype.watch = function (key, callback) { var _self = this; var path = Path.join(this._rootPath, key); if (key[key.length - 1] != '/') { path = Path.join(path, VALUE_MAGIC_FILE); } if (this._watches.hasOwnProperty(key)) { this._watches[key].push(callback); this._onWatchFile(key, callback); return; } /* TODO - przejsc na fs.watch */ fs.watchFile(path, {interval: 500}, function (current, previous) { if (current.size == 0) { /* * pomijam event przy czyszczeniu pliku * po CLOSE_WRITE zostanie wygenerowany nowy event */ } else { /* odpalenie callbackow dla "słuchaczy" */ if (_self._watches.hasOwnProperty(key)) { _self._onWatchFile(key, _self._watches[key]); } } }); this._watches[key] = [callback]; this._onWatchFile(key, callback); }; FilesDataProvider.prototype._onWatchFile = function (key, callbacks) { var _self = this; callbacks = Types.isArray(callbacks) ? callbacks : [callbacks]; this.get(key, function (err, data) { if (err) { console.error('Error reading watched file (%s):', key, err) data = null; } for (var i = 0, len = callbacks.length; i < len; i++) { callbacks[i](err, data); } }); } FilesDataProvider.prototype.unwatch = function (key, callback) { var path = Path.join(this._rootPath, key); if (key[key.length - 1] != '/') { path = Path.join(path, VALUE_MAGIC_FILE); } if (this._watches.hasOwnProperty(key)) { fs.unwatchFile(path); delete this._watches[key]; } if (callback) { callback(); } }; FilesDataProvider.prototype.set = function (key, value, options, callback) { var that = this; Assertions.isString(key, FilesDataProvider.Exception.KEY_HAS_TO_BE_A_STRING); var dirPath = Path.join(this._rootPath, key); fs.stat(dirPath, function (error, stats) { if (error) { if (error.code == 'ENOENT') { fs.mkdir(dirPath, '0777', function () { that._writeValue(key, value, callback); }); } else { callback(error, null); } } else { that._writeValue(key, value, callback); } }); }; FilesDataProvider.prototype.remove = function (key, options, callback) { console.info('TODO :)'); }; FilesDataProvider.prototype._writeValue = function (key, value, callback) { var filePath = Path.join(this._rootPath, key, VALUE_MAGIC_FILE); fs.writeFile(filePath, value, function (error, value) { callback(error, value); }); }; FilesDataProvider.prototype.get = function (key, callback) { Assertions.isString(key, FilesDataProvider.Exception.KEY_HAS_TO_BE_A_STRING); var dirPath = Path.join(this._rootPath, key); if (key[key.length - 1] == '/') { //odczytujemy dzieciaki fs.readdir(dirPath, function (error, value) { callback(error, value.filter(function (element) { return element[0] != '.'; })); }); } else { fs.readFile(Path.join(dirPath, VALUE_MAGIC_FILE), 'utf-8', function (error, data) { if (error) { callback(error, null); return; } callback(error, data.toString(), {}); }); } }; FilesDataProvider.prototype.remove = function (key, options, callback) { Assertions.isString(key, FilesDataProvider.Exception.KEY_HAS_TO_BE_A_STRING); var that = this; var dirPath = Path.join(this._rootPath, key); fs.stat(dirPath, function (err, stat) { if (err) { callback(err.code, stat); return; } if (!stat.isDirectory()) { fs.unlink(dirPath, function (err) { callback(err, null); }); } else { fs.readdir(dirPath, function (err, files) { var length = files.length, deleted = 0, i; if (err) { callback(err); return; } if (!length) { fs.rmdir(dirPath, function (err) { callback(err); }); return; } for (i = 0; i < length; i++) { that.remove(Path.join(dirPath, files[i]), options, function (err) { if (err) { callback(err, null); return; } if (++deleted == length) { fs.rmdir(dirPath, function (err) { callback(err, null); }); } }); } }); } }); }; FilesDataProvider.Exception = {}; FilesDataProvider.Exception.BAD_FILE_NAME = "File name has to be a string"; FilesDataProvider.Exception.WRONG_KEY = "Key has to be a string"; FilesDataProvider.Exception.WRONG_VALUE = "Value has to be a string or an object"; exports.FilesDataProvider = FilesDataProvider;