blueentities
Advanced tools
Comparing version 0.0.3 to 0.1.0
@@ -13,7 +13,8 @@ "use strict"; | ||
class BlueEntity { | ||
constructor(schema, dbId, redisConfig) { | ||
class BlueEntities { | ||
constructor(schema, dbId, redisConfig, module) { | ||
this._redisClient = redis.createClient(redisConfig); | ||
this._dbId = dbId ? dbId+":" : ""; | ||
this._redisConfig = redisConfig ? redisConfig : {}; | ||
this._schemaPropertyKeys = []; | ||
this._entitiesSchema = []; | ||
@@ -44,4 +45,4 @@ this._entitiesNames = []; | ||
_checkProperty( propertyName, propertyValue, entityName ) { | ||
var sch = entityName + "." + propertyName; | ||
var prop = this._entitiesSchema[ sch ]; | ||
var sch = this._getSchemaPropertyKey(entityName, propertyName); | ||
var prop = this._schemaPropertyKeys[ sch ]; | ||
var res = { validated: true }; | ||
@@ -152,3 +153,5 @@ var t = typeof propertyValue; | ||
* name: <property name>, | ||
* type: <property type> (integer, datetime, string, boolean, etc.) | ||
* type: <property type (integer, datetime, string, boolean, etc.), | ||
* optional: <true|false, indicated if this property es optional> | ||
* defaultValue: <default value is optional is true> | ||
* }, | ||
@@ -158,2 +161,3 @@ * ... | ||
* } | ||
* In properties, name and type properties are mandatory. | ||
*/ | ||
@@ -168,6 +172,7 @@ addEntitySchema( entitySchema ) { | ||
this._entitiesNames[entitySchema.name] = ""; | ||
this._entitiesSchema[entitySchema.name] = entitySchema.properties; | ||
entitySchema.properties.map( (property) => { | ||
this._entitiesSchema[ this._getSchemaPropertyKey(entitySchema.name, property.name) ] = property; | ||
}) | ||
this._schemaPropertyKeys[ this._getSchemaPropertyKey(entitySchema.name, property.name) ] = property; | ||
}) | ||
} | ||
@@ -179,3 +184,3 @@ | ||
* entityName: name of the entity, it should be defined in the schema | ||
* entityProperties: array with properties and its values: [ { propA: valueA }, { propB: valueB }... ] | ||
* entityProperties: array with properties and its values: [ propA: valueA, propB: valueB, ... ] | ||
* entityId: unique ID for the new entity (optional). Should be an string with 8 characters. | ||
@@ -192,19 +197,49 @@ * If it is not set, addEntity will generate a new one. | ||
var valuesToHset = []; | ||
entityId = entityId === undefined ? shortid.generate() : entityId; | ||
// Creates array with properties to set: valuesToHset[<property name>] = <property value> | ||
var propertiesKeys = Object.keys(entityProperties); | ||
for( let i = 0; i < propertiesKeys.length; i++ ) { | ||
var property = propertiesKeys[i]; | ||
var value = entityProperties[property]; | ||
valuesToHset[property] = value; | ||
} | ||
return new Promise( (resolve, reject) => { | ||
var promises = []; | ||
var check = this._checkProperties( valuesToHset, entityName ); | ||
var check; | ||
// Check if all properties are included and optional values | ||
var schemaProperties = this._entitiesSchema[entityName]; | ||
schemaProperties.forEach( (property) => { | ||
// Property not set and not indicated as optional in schema | ||
if ( entityProperties[property.name] === undefined && (property.optional === undefined || property.optional === false) ) { | ||
reject( new Error( util.format("Property '%s' missing in entity", property.name) ) ); | ||
} | ||
// Property not set but indicated as optional | ||
if ( entityProperties[property.name] === undefined && property.optional === true ) { | ||
if ( property.defaultValue === undefined ) { | ||
switch( property.type ) { | ||
case "integer": { | ||
entityProperties[property.name] = 0; | ||
} | ||
break; | ||
case "string": { | ||
entityProperties[property.name] = ""; | ||
} | ||
break; | ||
case "boolean": { | ||
entityProperties[property.name] = false; | ||
} | ||
} | ||
} else { | ||
let defaultValueType = typeof property.defaultValue; | ||
defaultValueType = defaultValueType == 'number' ? 'integer' : defaultValueType; | ||
if ( defaultValueType !== property.type ) { | ||
reject( new Error( util.format( "Default value of '%s' is not of type expected '%s'", property.defaultValue, property.type ))); | ||
} | ||
entityProperties[property.name] = property.defaultValue; | ||
} | ||
} | ||
}) | ||
// Check properties types | ||
check = this._checkProperties( entityProperties, entityName ); | ||
if ( !check.validated ) { | ||
@@ -216,5 +251,5 @@ reject("One of more properties are invalid or missing: " + check.msg ); | ||
// Insert for the same haddKey and entry by each property | ||
Object.keys(valuesToHset).forEach( (propertyName) => { | ||
var propSchema = this._entitiesSchema[ this._getSchemaPropertyKey(entityName,propertyName) ]; | ||
var propertyValue = valuesToHset[propertyName]; | ||
Object.keys(entityProperties).forEach( (propertyName) => { | ||
var propSchema = this._schemaPropertyKeys[ this._getSchemaPropertyKey(entityName,propertyName) ]; | ||
var propertyValue = entityProperties[propertyName]; | ||
@@ -269,2 +304,3 @@ switch(propSchema.type) { | ||
* entityId: id for the entity instance to retrieve | ||
* Returns a promise. When completed, the result is a json object with the entity | ||
*/ | ||
@@ -280,3 +316,3 @@ getEntity( entityName, entityId ) { | ||
if ( propertyName !== "id" ) { | ||
var propSchema = this._entitiesSchema[ this._getSchemaPropertyKey(entityName,propertyName) ]; | ||
var propSchema = this._schemaPropertyKeys[ this._getSchemaPropertyKey(entityName,propertyName) ]; | ||
var propertyValue = result[propertyName]; | ||
@@ -307,2 +343,19 @@ | ||
/* | ||
* Checks if an entity exists given its entity name and its ID | ||
* Params: | ||
* entityName: name of the entity | ||
* entityId: id for the entity instance to retrieve | ||
* Returns a promise. When completed, the result indicates if the entity exists (true) or not (false) | ||
*/ | ||
existsEntity( entityName, entityId ) { | ||
var key = this._getEntityKey(entityName, entityId); | ||
return new Promise( (resolve,reject) => { | ||
redisPromisified.exists( key, this._redisClient ) | ||
.then( (exists) => { resolve(exists === 1); }) | ||
.catch( (err) => { reject(err); }) | ||
}); | ||
} | ||
/* | ||
* Returns the number of entities instances for a given entity | ||
@@ -446,3 +499,3 @@ * Params: | ||
module.exports = function(schema, dbId, redisConfig) { | ||
return new BlueEntity(schema, dbId, redisConfig); | ||
return new BlueEntities(schema, dbId, redisConfig, this); | ||
} |
@@ -65,5 +65,3 @@ "use strict"; | ||
if ( err ) { reject(err); } | ||
else { | ||
resolved(result); | ||
} | ||
else { resolved(result); } | ||
}) | ||
@@ -77,7 +75,14 @@ }); | ||
if ( err ) { reject(err); } | ||
else { | ||
resolved(result); | ||
} | ||
else { resolved(result); } | ||
}) | ||
}); | ||
} | ||
module.exports.exists = function( key , redisClient) { | ||
return new Promise( (resolved, reject) => { | ||
redisClient.exists( key, (err, result) => { | ||
if ( err ) { reject(err); } | ||
else { resolved(result); } | ||
}) | ||
}) | ||
} |
{ | ||
"name": "blueentities", | ||
"version": "0.0.3", | ||
"version": "0.1.0", | ||
"description": "Entities management for Redis database", | ||
@@ -5,0 +5,0 @@ "main": "blueentities.js", |
@@ -80,2 +80,4 @@ # Blue Entities | ||
### existsEntity( entityName, entityId ) | ||
### cleanSchemaEntities() | ||
@@ -82,0 +84,0 @@ |
@@ -83,5 +83,9 @@ "strict mode"; | ||
console.time("benchMarkTest1"); | ||
benchMarkTest1().then( () => { | ||
console.log("bechMarkTest1 done"); | ||
console.timeEnd("benchMarkTest1"); | ||
blueEntities.shutdown(); | ||
}); |
@@ -14,4 +14,4 @@ "strict mode"; | ||
{ name: "location", type: "string" }, | ||
{ name: "filetype", type: "string" }, | ||
{ name: "size", type: "integer" }, | ||
{ name: "filetype", type: "string", optional: true }, | ||
{ name: "size", type: "integer", optional: true, defaultValue: 20 }, | ||
{ name: "checked", type: "boolean" } | ||
@@ -104,3 +104,3 @@ ]} | ||
blueEntities.addEntity( "img", entity ) | ||
.then( (id) => { | ||
.then( (id) => { | ||
done( new Error("Exception expected in this test") ); | ||
@@ -113,2 +113,46 @@ }) | ||
it( "# Add entity with optional value and no default value", (done) => { | ||
let entity = { | ||
filename: shortid.generate(), | ||
location: shortid.generate(), | ||
/* filetype: "png", filetype marked as optional in schema */ | ||
size: Math.floor(Math.random()*1000), | ||
checked: true | ||
} | ||
blueEntities.addEntity( "img", entity ) | ||
.then( (id) => { | ||
return blueEntities.getEntity( "img", id ); | ||
}) | ||
.then( (r) => { | ||
assert.equal( "", r.filetype ); | ||
done(); | ||
}) | ||
.catch( (err) => { | ||
done(err); | ||
}) | ||
}); | ||
it( "# Add entity with optional value and default value", (done) => { | ||
let entity = { | ||
filename: shortid.generate(), | ||
location: shortid.generate(), | ||
filetype: "png", | ||
/* size: Math.floor(Math.random()*1000), size is marked in schema as optional and with default value of 20 */ | ||
checked: true | ||
} | ||
blueEntities.addEntity( "img", entity ) | ||
.then( (id) => { | ||
return blueEntities.getEntity( "img", id ) | ||
}) | ||
.then( (r) => { | ||
assert.equal( 20, r.size ); | ||
done(); | ||
}) | ||
.catch( (err) => { | ||
done(err); | ||
}) | ||
}); | ||
it( "# Add multiple entities", (done) => { | ||
@@ -151,2 +195,28 @@ const COUNT = 10; | ||
}); | ||
it( "# Add entity and check if exists", (done) => { | ||
blueEntities.addEntity( "img", _getSampleEntity() ) | ||
.then( (id) => { | ||
assert.isString(id); | ||
return blueEntities.existsEntity( "img", id ); | ||
}) | ||
.then( (exists) => { | ||
assert.isBoolean( exists ); | ||
assert.isTrue( exists ); | ||
done(); | ||
}) | ||
.catch( (err) => { | ||
done(err); | ||
}) | ||
}); | ||
it( "# Check entity no exists", (done) => { | ||
blueEntities.existsEntity( "img", blueEntities.getUniqueId() ) | ||
.then( (exists) => { | ||
assert.isBoolean( exists ); | ||
assert.isFalse( exists ); | ||
done(); | ||
}) | ||
.catch( (err) => { done(err); }); | ||
}); | ||
}); | ||
@@ -153,0 +223,0 @@ |
37487
1120
88