Skip to content

Commit

Permalink
Merge pull request #71 from GoblinDBRocks/dev
Browse files Browse the repository at this point in the history
0.1.2
  • Loading branch information
CodingCarlos authored Oct 7, 2019
2 parents ab3d9a0 + 5400ccf commit 9943dbd
Show file tree
Hide file tree
Showing 7 changed files with 5,258 additions and 2,009 deletions.
2 changes: 1 addition & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ module.exports = {
fileName : 'goblin_db',
pointerSymbol: '.',
recordChanges: true,
mode : 'production',
mode : 'production'
};
82 changes: 65 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const _ = require('lodash');

const goblin = require('./lib/goblin');
const mode = require('./lib/logger/mode');
const modes = require('./lib/logger/mode');
const Ambush = require('./lib/ambush');
const Database = require('./lib/database');

Expand All @@ -22,8 +22,7 @@ function GoblinExports(config, cb) {
}

// Set configuration
config = configValidation(config, goblin.config);
goblin.config = _.merge({}, goblin.config, config);
goblin.config = initialConfiguration(goblin.config, config);

// Initialize current database
Database.init(function(dbError) {
Expand All @@ -49,10 +48,10 @@ function GoblinExports(config, cb) {
on: goblin.hooks.add,
off: goblin.hooks.remove,
getConfig: function() {
return goblin.config;
return Object.assign({}, goblin.config);
},
updateConfig: function(newConfig) {
goblin.config = _.merge({}, goblin.config, newConfig);
goblin.config = updateConfiguration(goblin.config, newConfig);
},
stopStorage: function() {
goblin.config.recordChanges = false;
Expand All @@ -69,18 +68,67 @@ function GoblinExports(config, cb) {
};
}

function configValidation(configuration, goblinConfiguration) {
configuration = typeof(configuration) === 'object' &&
configuration !== null ? configuration : {};
configuration.fileName = configuration.fileName || goblinConfiguration.fileName;
configuration.files = {
ambush: configuration.fileName + '.goblin',
db: configuration.fileName + '.json'
};
configuration.pointerSymbol = configuration.pointerSymbol || goblinConfiguration.pointerSymbol;
configuration.recordChanges = configuration.recordChanges || goblinConfiguration.recordChanges;
configuration.mode = configuration.mode || goblinConfiguration.mode;
return configuration;
function isNotEmptyString(element) {
return element && typeof(element) === 'string';
}

function isBoolean(element) {
return typeof(element) === 'boolean';
}

function isValidMode(mode) {
return modes[mode] !== undefined;
}

function initialConfiguration(defaultConfiguration, externalConfiguration) {
const updated = updateConfiguration(defaultConfiguration, externalConfiguration);

if (!updated.files) {
updated.files = {
ambush: updated.fileName + '.goblin',
db: updated.fileName + '.json'
};
}

return updated;
}

function updateConfiguration(currentConfiguration, newConfiguration) {
if (
typeof(newConfiguration) !== 'object' ||
newConfiguration === null ||
Object.keys(newConfiguration).length === 0
) {
return currentConfiguration;
}

const updatedConfig = Object.assign({}, currentConfiguration);

if (isNotEmptyString(newConfiguration.fileName)) {
updatedConfig.fileName = newConfiguration.fileName;
updatedConfig.files = {
ambush: newConfiguration.fileName + '.goblin',
db: newConfiguration.fileName + '.json'
};
}

if (isNotEmptyString(newConfiguration.pointerSymbol)) {
updatedConfig.pointerSymbol = newConfiguration.pointerSymbol;
}

if (isBoolean(newConfiguration.recordChanges)) {
updatedConfig.recordChanges = newConfiguration.recordChanges;
}

if (isValidMode(newConfiguration.mode)) {
updatedConfig.mode = newConfiguration.mode;
}
// console.log(updateConfiguration, newConfiguration);
if (isNotEmptyString(newConfiguration.logPrefix)) {
updatedConfig.logPrefix = '[' + newConfiguration.logPrefix + ']'
}

return updatedConfig;
}

module.exports = GoblinExports;
48 changes: 36 additions & 12 deletions lib/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ goblin.goblinDataEmitter.on('change', function(details) {
});
});


/**
* Initialize database.
*
Expand Down Expand Up @@ -56,7 +55,7 @@ function get(point) {

for (let i = 0; i < tree.length; i++) {
if(i !== tree.length-1) {
if(typeof parent[tree[i]] === 'undefined') {
if(parent[tree[i]] === undefined) {
// If there is no child here, won't be deeper. Return undefined
return undefined;
}
Expand Down Expand Up @@ -114,13 +113,15 @@ function set(data, point, silent) {
return logger('DB_SAVE_INVALID_DATA');
}

data = makeInmutable(data);

if (point && typeof(point) === 'string') {
const tree = point.split(goblin.config.pointerSymbol);
let parent = goblin.db;

for (let i = 0; i < tree.length; i++) {
if (i !== tree.length - 1) {
if (typeof parent[tree[i]] === 'undefined') {
if (parent[tree[i]] === undefined) {
parent[tree[i]] = {};
}

Expand Down Expand Up @@ -159,28 +160,31 @@ function set(data, point, silent) {
* update the stored data then it'll replace all db, in that case the data can not
* be an array. The first element of the DB has to be always an object.
*
* @param {object | array} data The data to store in the database.
* @param {any} data The data to store in the database.
* @param {string} point The place to store the data.
* @returns {void}
*/
function update(data, point) {
if (!data || typeof(data) !== 'object') {
if (!data || (!point && typeof(data) !== 'object')) {
return logger('DB_SAVE_INVALID_DATA');
}

data = makeInmutable(data);

if (point && typeof(point) === 'string') {
const tree = point.split('.');
let parent = goblin.db;

for (let i = 0; i < tree.length; i++) {
if (i !== tree.length-1) {
if (typeof parent[tree[i]] === 'undefined') {
parent[tree[i]] = {};
}
if (parent[tree[i]] === undefined) {
return logger('DB_UPDATE_POIN_NOT_EXIST', 'Invalid point: ' + point);
}

if (i < tree.length - 1) {
parent = parent[tree[i]];
} else {
const oldValue = parent[tree[i]];
parent[tree[i]] = Object.assign({}, goblin.db, data);
parent[tree[i]] = data;
goblin.goblinDataEmitter.emit('change', {
type: 'update',
value: parent[tree[i]],
Expand Down Expand Up @@ -257,7 +261,7 @@ function deleteFn(point) {
* @returns {void} Nothing
*/
function truncate() {
const oldValue = goblin.db;
const oldValue = Object.assign({}, goblin.db);
goblin.db = {};
goblin.goblinDataEmitter.emit('change', {
type: 'truncate',
Expand All @@ -266,6 +270,26 @@ function truncate() {
});
}


/**
* Private. Check if an element is an object and creates a new memory ref for that object
* to preserve inmutability.
*
* @param {any} element The element to test agains.
* @return {any} A new memory ref in the case it's an object.
*/
function makeInmutable(element) {
if (element && typeof(element) === 'object') {
if (Array.isArray(element)) {
return [...element];
} else {
return Object.assign({}, element);
}
}

return element;
}

module.exports = {
init: init,
get: get,
Expand Down
3 changes: 2 additions & 1 deletion lib/logger/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
'AMBUSH_ADD_ERROR': 'Ambush ADD error: This ambush function was registered before.',
'AMBUSH_NOT_STORED_ID': 'Ambush error: The provided ID doesn not belong to any stored ambush function.',
'DB_DELETE_INVALID_POINT': 'Database delete error: Invalid pointer, there is no data in that part of tree.',
'DB_DELETE_MISSING_POINT': 'Database delete error: Missing point that indicates where to delete. It\'s mandatory, if you want to delete from root use truncate() instead.'
'DB_DELETE_MISSING_POINT': 'Database delete error: Missing point that indicates where to delete. It\'s mandatory, if you want to delete from root use truncate() instead.',
'DB_UPDATE_POIN_NOT_EXIST': 'Database update error: You\'re trying to store data in a key that doesn\'t exist. Please use a valid pointer or the method set() which create the structure if not exist.'
};

Loading

0 comments on commit 9943dbd

Please sign in to comment.