Comparing version 0.1.9 to 0.1.10
{ | ||
"name": "meadow", | ||
"version": "0.1.9", | ||
"version": "0.1.10", | ||
"description": "A data access library.", | ||
@@ -5,0 +5,0 @@ "main": "source/Meadow.js", |
@@ -16,4 +16,3 @@ /** | ||
*/ | ||
var libAsync = require('async'); | ||
var libUnderscore = require('underscore') | ||
var libUnderscore = require('underscore'); | ||
@@ -45,3 +44,13 @@ // Multi server query generation | ||
var _Query = libFoxHound.new(_Fable).setScope(_Scope); | ||
// The custom query loader | ||
var _RawQueries = require('./Meadow-RawQuery.js').new(_Fable); | ||
// The core behaviors.. abstracted into their own modules to encapsulate complexity | ||
var _CreateBehavior = require('./behaviors/Meadow-Create.js'); | ||
var _ReadBehavior = require('./behaviors/Meadow-Read.js'); | ||
var _ReadsBehavior = require('./behaviors/Meadow-Reads.js'); | ||
var _UpdateBehavior = require('./behaviors/Meadow-Update.js'); | ||
var _DeleteBehavior = require('./behaviors/Meadow-Delete.js'); | ||
var _CountBehavior = require('./behaviors/Meadow-Count.js'); | ||
// The data provider | ||
@@ -60,50 +69,11 @@ var _Provider = false; | ||
/** | ||
* Load the schema and metadata from a package file | ||
* | ||
* @method loadFromPackage | ||
* @return {Object} Returns a new Meadow, or false if it failed | ||
*/ | ||
* Load a Meadow Package JSON, create a Meadow object from it. | ||
*/ | ||
var _MeadowPackageLoader = require('./Meadow-PackageLoader.js'); | ||
var loadFromPackage = function(pPackage) | ||
{ | ||
// Use the package loader to grab the configuration objects and clone a new Meadow. | ||
var tmpPackage = false; | ||
try | ||
{ | ||
tmpPackage = require(pPackage); | ||
} | ||
catch(pError) | ||
{ | ||
_Fable.log.error('Error loading Fable package', {Package:pPackage}); | ||
return false; | ||
} | ||
return _MeadowPackageLoader(this, pPackage); | ||
}; | ||
// Spool up a new Meadow object | ||
var tmpNewMeadow = createNew(_Fable); | ||
// Safely set the parameters | ||
if (typeof(tmpPackage.Scope) === 'string') | ||
{ | ||
tmpNewMeadow.setScope(tmpPackage.Scope); | ||
} | ||
if (typeof(tmpPackage.DefaultIdentifier) === 'string') | ||
{ | ||
tmpNewMeadow.setDefaultIdentifier(tmpPackage.DefaultIdentifier); | ||
} | ||
if (Array.isArray(tmpPackage.Schema)) | ||
{ | ||
tmpNewMeadow.setSchema(tmpPackage.Schema); | ||
} | ||
if (typeof(tmpPackage.JsonSchema) === 'object') | ||
{ | ||
tmpNewMeadow.setJsonSchema(tmpPackage.JsonSchema); | ||
} | ||
if (typeof(tmpPackage.DefaultObject) === 'object') | ||
{ | ||
tmpNewMeadow.setDefault(tmpPackage.DefaultObject) | ||
} | ||
return tmpNewMeadow; | ||
} | ||
/** | ||
@@ -217,307 +187,54 @@ * Set the scope | ||
return this; | ||
} | ||
}; | ||
/** | ||
* Create a record asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* | ||
* TODO: Add a second behavior that creates records without returning them and takes an array of records. | ||
* Create a record | ||
*/ | ||
var doCreate = function(pQuery, fCallBack) | ||
{ | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Get the record from the data source | ||
function (fStageComplete) | ||
{ | ||
pQuery.query.IDUser = _IDUser; | ||
// Make sure the user submitted a record | ||
if (!pQuery.query.records) | ||
{ | ||
return fStageComplete('No record submitted', pQuery, false); | ||
} | ||
// Merge in the default record with the passed-in record for completeness | ||
pQuery.query.records[0] = libUnderscore.extend(_Schema.defaultObject, pQuery.query.records[0]); | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider create code | ||
_Provider.Create(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery); }); | ||
}, | ||
// Step 2: Marshal the record into a POJO | ||
function (pQuery, fStageComplete) | ||
{ | ||
if (pQuery.parameters.result.value === false) | ||
{ | ||
// The value is not set (it should be set to the value for our DefaultIdentifier) | ||
return fStageComplete('Creation failed', pQuery, false); | ||
} | ||
var tmpIDRecord = pQuery.result.value; | ||
fStageComplete(pQuery.result.error, pQuery, tmpIDRecord); | ||
}, | ||
// Step 3: Read the record | ||
function (pQuery, pIDRecord, fStageComplete) | ||
{ | ||
var tmpQueryRead = pQuery.clone().addFilter(_DefaultIdentifier, pIDRecord); | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code complexity | ||
_Provider.Read(tmpQueryRead, function(){ fStageComplete(tmpQueryRead.result.error, pQuery, tmpQueryRead); }); | ||
}, | ||
// Step 4: Marshal the record into a POJO | ||
function (pQuery, pQueryRead, fStageComplete) | ||
{ | ||
if (pQueryRead.parameters.result.value.length < 1) | ||
{ | ||
// There is not at least one record returned | ||
return fStageComplete('No record found after create.', pQuery, pQueryRead, false); | ||
} | ||
return _CreateBehavior(this, pQuery, fCallBack); | ||
}; | ||
var tmpRecord = marshalRecordFromSourceToObject(pQueryRead.result.value[0]); | ||
fStageComplete(pQuery.result.error, pQuery, pQueryRead, tmpRecord); | ||
} | ||
], | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
if (pError) | ||
{ | ||
_Fable.log.warn('Error during the create waterfall', {Error:pError, Query: pQuery.query}); | ||
} | ||
// Call the callback passed in with the record as the first parameter, query second. | ||
fCallBack(pError, pQuery, pQueryRead, pRecord); | ||
} | ||
); | ||
return this; | ||
} | ||
/** | ||
* Read a record asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* Read a record | ||
*/ | ||
var doRead = function(pQuery, fCallBack) | ||
{ | ||
// Read the record from the source | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Get the record from the data source | ||
function (fStageComplete) | ||
{ | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code | ||
_Provider.Read(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery); }); | ||
}, | ||
// Step 2: Marshal the record into a POJO | ||
function (pQuery, fStageComplete) | ||
{ | ||
if (pQuery.parameters.result.value.length < 1) | ||
{ | ||
// The value is not an array | ||
return fStageComplete(false, pQuery, false); | ||
} | ||
return _ReadBehavior(this, pQuery, fCallBack); | ||
}; | ||
var tmpRecord = marshalRecordFromSourceToObject(pQuery.result.value[0]); | ||
fStageComplete(pQuery.result.error, pQuery, tmpRecord); | ||
} | ||
], | ||
function(pError, pQuery, pRecord) | ||
{ | ||
if (pError) | ||
{ | ||
_Fable.log.warn('Error during the read waterfall', {Error:pError, Query: pQuery.query}); | ||
} | ||
// Call the callback passed in with the record as the first parameter, query second. | ||
fCallBack(pError, pQuery, pRecord); | ||
} | ||
); | ||
return this; | ||
} | ||
/** | ||
* Read many records asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* Read multiple records | ||
*/ | ||
var doReads = function(pQuery, fCallBack) | ||
{ | ||
// Read the record(s) from the source | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Get a record from the data source | ||
function (fStageComplete) | ||
{ | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code | ||
_Provider.Read(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery); }); | ||
}, | ||
// Step 2: Marshal all the records into a POJO asynchronously | ||
function (pQuery, fStageComplete) | ||
{ | ||
var tmpRecords = []; | ||
return _ReadsBehavior(this, pQuery, fCallBack); | ||
}; | ||
libAsync.each | ||
( | ||
pQuery.parameters.result.value, | ||
function(pRow, pQueueCallback) | ||
{ | ||
tmpRecords.push(marshalRecordFromSourceToObject(pRow)); | ||
pQueueCallback(); | ||
}, | ||
function() | ||
{ | ||
// Now complete the waterfall | ||
fStageComplete(pQuery.result.error, pQuery, tmpRecords); | ||
} | ||
); | ||
} | ||
], | ||
function(pError, pQuery, pRecords) | ||
{ | ||
if (pError) | ||
{ | ||
_Fable.log.warn('Error during the read multiple waterfall', {Error:pError, Query: pQuery.query}); | ||
} | ||
fCallBack(pError, pQuery, pRecords); | ||
} | ||
); | ||
return this; | ||
} | ||
/** | ||
* Update a record asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* Update a record | ||
*/ | ||
var doUpdate = function(pQuery, fCallBack) | ||
{ | ||
// Update the record(s) from the source | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Update the record | ||
function (fStageComplete) | ||
{ | ||
pQuery.query.IDUser = _IDUser; | ||
// Make sure the user submitted a record | ||
if (!pQuery.query.records) | ||
{ | ||
return fStageComplete('No record submitted', pQuery, false); | ||
} | ||
// Make sure there is a default identifier | ||
if (!pQuery.query.records[0].hasOwnProperty(_DefaultIdentifier)) | ||
{ | ||
return fStageComplete('Automated update missing default identifier', pQuery, false); | ||
} | ||
return _UpdateBehavior(this, pQuery, fCallBack); | ||
}; | ||
// Now see if there is anything in the schema that is an Update action that isn't in this query | ||
for (var i = 0; i < _Schema.schema.length; i++) | ||
{ | ||
switch (_Schema.schema[i].Type) | ||
{ | ||
case 'UpdateIDUser': | ||
case 'UpdateDate': | ||
pQuery.query.records[0][_Schema.schema[i].Column] = false; | ||
break; | ||
} | ||
} | ||
// Set the update filter | ||
pQuery.addFilter(_DefaultIdentifier, pQuery.query.records[0][_DefaultIdentifier]); | ||
// Sanity check on update | ||
if ((pQuery.parameters.filter === false) || (pQuery.parameters.filter.length < 1)) | ||
{ | ||
return fStageComplete('Automated update missing filters... aborting!', pQuery, false); | ||
} | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code | ||
_Provider.Update(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery); }); | ||
}, | ||
// Step 2: Check that the record was updated | ||
function (pQuery, fStageComplete) | ||
{ | ||
if (typeof(pQuery.parameters.result.value) !== 'object') | ||
{ | ||
// The value is not an object | ||
return fStageComplete('No record updated.', pQuery, false); | ||
} | ||
fStageComplete(pQuery.result.error, pQuery); | ||
}, | ||
// Step 3: Read the record | ||
function (pQuery, fStageComplete) | ||
{ | ||
// We can clone the query, since it has the criteria for the update in it already (filters survive a clone) | ||
var tmpQueryRead = pQuery.clone(); | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code | ||
_Provider.Read(tmpQueryRead, function(){ fStageComplete(tmpQueryRead.result.error, pQuery, tmpQueryRead); }); | ||
}, | ||
// Step 4: Marshal the record into a POJO | ||
function (pQuery, pQueryRead, fStageComplete) | ||
{ | ||
var tmpRecord = marshalRecordFromSourceToObject(pQueryRead.result.value[0]); | ||
// TODO: Add error handling for marshaling | ||
fStageComplete(pQuery.result.error, pQuery, pQueryRead, tmpRecord); | ||
} | ||
], | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
if (pError) | ||
{ | ||
_Fable.log.warn('Error during Update waterfall', {Error:pError, Query: pQuery.query}); | ||
} | ||
fCallBack(pError, pQuery, pQueryRead, pRecord); | ||
} | ||
); | ||
return this; | ||
} | ||
/** | ||
* Delete a record asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* Delete a record | ||
*/ | ||
var doDelete = function(pQuery, fCallBack) | ||
{ | ||
// TODO: Check if this recordset has implicit delete tracking | ||
// Delete the record(s) from the source | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Delete the record | ||
function (fStageComplete) | ||
{ | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code complexity | ||
_Provider.Delete(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery, pQuery.result.value); }); | ||
} | ||
], | ||
function(pError, pQuery, pRecord) | ||
{ | ||
fCallBack(pError, pQuery, pRecord); | ||
} | ||
); | ||
return _DeleteBehavior(this, pQuery, fCallBack); | ||
}; | ||
return this; | ||
} | ||
/** | ||
* Count a record asynchronously, calling fCallBack with the marshalled record(s) or error in them at end | ||
* Count multiple records | ||
*/ | ||
var doCount = function(pQuery, fCallBack) | ||
{ | ||
// Count the record(s) from the source | ||
libAsync.waterfall( | ||
[ | ||
// Step 1: Get the record from the data source | ||
function (fStageComplete) | ||
{ | ||
// This odd lambda is to use the async waterfall without spilling logic into the provider read code complexity | ||
_Provider.Count(pQuery, function(){ fStageComplete(pQuery.result.error, pQuery); }); | ||
}, | ||
// Step 2: Marshal the record into a POJO | ||
function (pQuery, fStageComplete) | ||
{ | ||
if (typeof(pQuery.parameters.result.value) !== 'number') | ||
{ | ||
// The value is not a number | ||
return fStageComplete('Count did not return valid results.', pQuery, false); | ||
} | ||
return _CountBehavior(this, pQuery, fCallBack); | ||
}; | ||
fStageComplete(pQuery.result.error, pQuery, pQuery.result.value); | ||
} | ||
], | ||
function(pError, pQuery, pCount) | ||
{ | ||
fCallBack(pError, pQuery, pCount); | ||
} | ||
); | ||
return this; | ||
} | ||
/** | ||
@@ -533,6 +250,6 @@ * Take the stored representation of our object and stuff the proper values | ||
_Provider.marshalRecordFromSourceToObject(tmpNewObject, pRecord, _Schema.schema); | ||
// This turns on magical validation | ||
//_Fable.log.trace('Validation', {Value:tmpNewObject, Validation:_Schema.validateObject(tmpNewObject)}) | ||
// Now return the new object | ||
return tmpNewObject; | ||
} | ||
}; | ||
@@ -552,2 +269,3 @@ /** | ||
validateObject: _Schema.validateObject, | ||
marshalRecordFromSourceToObject: marshalRecordFromSourceToObject, | ||
@@ -557,5 +275,3 @@ setProvider: setProvider, | ||
// Schema management | ||
loadFromPackage: loadFromPackage, | ||
// | ||
setScope: setScope, | ||
@@ -596,2 +312,14 @@ setSchema: setSchema, | ||
/** | ||
* Entity Schema | ||
* | ||
* @property schema | ||
* @type object | ||
*/ | ||
Object.defineProperty(tmpNewMeadowObject, 'schemaFull', | ||
{ | ||
get: function() { return _Schema; }, | ||
enumerable: true | ||
}); | ||
/** | ||
* Default Identifier | ||
@@ -621,2 +349,16 @@ * | ||
/** | ||
* User Identifier | ||
* | ||
* Used to stamp user identity into Create/Update operations. | ||
* | ||
* @property userIdentifier | ||
* @type string | ||
*/ | ||
Object.defineProperty(tmpNewMeadowObject, 'userIdentifier', | ||
{ | ||
get: function() { return _IDUser; }, | ||
enumerable: true | ||
}); | ||
/** | ||
* Query (FoxHound) object | ||
@@ -645,2 +387,26 @@ * | ||
/** | ||
* Raw Queries | ||
* | ||
* @property rawQueries | ||
* @type object | ||
*/ | ||
Object.defineProperty(tmpNewMeadowObject, 'rawQueries', | ||
{ | ||
get: function() { return _RawQueries; }, | ||
enumerable: true | ||
}); | ||
/** | ||
* Provider | ||
* | ||
* @property provider | ||
* @type object | ||
*/ | ||
Object.defineProperty(tmpNewMeadowObject, 'provider', | ||
{ | ||
get: function() { return _Provider; }, | ||
enumerable: true | ||
}); | ||
/** | ||
* Provider Name | ||
@@ -647,0 +413,0 @@ * |
@@ -46,5 +46,8 @@ /** | ||
var marshalRecordFromSourceToObject = function(pObject, pRecord, pSchema) | ||
// The Meadow marshaller also passes in the Schema as the third parameter, but this is a blunt function ATM. | ||
var marshalRecordFromSourceToObject = function(pObject, pRecord) | ||
{ | ||
// For now, crudely assign everything in pRecord to pObject | ||
// This is safe in this context, and we don't want to slow down marshalling with millions of hasOwnProperty checks | ||
/*jshint -W089 */ | ||
for(var tmpColumn in pRecord) | ||
@@ -54,2 +57,3 @@ { | ||
} | ||
/*jshint +W089 */ | ||
}; | ||
@@ -65,3 +69,5 @@ | ||
if (pQuery.logLevel > 0) | ||
{ | ||
_Fable.log.trace(pQuery.query.body, pQuery.query.parameters); | ||
} | ||
@@ -73,3 +79,4 @@ var tmpSQLConnection = getSQLConnection(); | ||
pQuery.query.parameters, | ||
function(pError, pRows, pFields) | ||
// The MySQL library also returns the Fields as the third parameter | ||
function(pError, pRows) | ||
{ | ||
@@ -103,3 +110,5 @@ tmpResult.error = pError; | ||
if (pQuery.logLevel > 0) | ||
{ | ||
_Fable.log.trace(pQuery.query.body, pQuery.query.parameters); | ||
} | ||
@@ -111,3 +120,4 @@ var tmpSQLConnection = getSQLConnection(); | ||
pQuery.query.parameters, | ||
function(pError, pRows, pFields) | ||
// The MySQL library also returns the Fields as the third parameter | ||
function(pError, pRows) | ||
{ | ||
@@ -130,3 +140,5 @@ tmpResult.error = pError; | ||
if (pQuery.logLevel > 0) | ||
{ | ||
_Fable.log.trace(pQuery.query.body, pQuery.query.parameters); | ||
} | ||
@@ -138,3 +150,4 @@ var tmpSQLConnection = getSQLConnection(); | ||
pQuery.query.parameters, | ||
function(pError, pRows, pFields) | ||
// The MySQL library also returns the Fields as the third parameter | ||
function(pError, pRows) | ||
{ | ||
@@ -157,3 +170,5 @@ tmpResult.error = pError; | ||
if (pQuery.logLevel > 0) | ||
{ | ||
_Fable.log.trace(pQuery.query.body, pQuery.query.parameters); | ||
} | ||
@@ -165,3 +180,4 @@ var tmpSQLConnection = getSQLConnection(); | ||
pQuery.query.parameters, | ||
function(pError, pRows, pFields) | ||
// The MySQL library also returns the Fields as the third parameter | ||
function(pError, pRows) | ||
{ | ||
@@ -192,3 +208,5 @@ tmpResult.error = pError; | ||
if (pQuery.logLevel > 0) | ||
{ | ||
_Fable.log.trace(pQuery.query.body, pQuery.query.parameters); | ||
} | ||
@@ -200,3 +218,4 @@ var tmpSQLConnection = getSQLConnection(); | ||
pQuery.query.parameters, | ||
function(pError, pRows, pFields) | ||
// The MySQL library also returns the Fields as the third parameter | ||
function(pError, pRows) | ||
{ | ||
@@ -208,3 +227,3 @@ tmpResult.executed = true; | ||
{ | ||
tmpResult.value = pRows[0]['RowCount']; | ||
tmpResult.value = pRows[0].RowCount; | ||
} | ||
@@ -211,0 +230,0 @@ catch(pErrorGettingRowcount) |
@@ -19,5 +19,6 @@ /** | ||
} | ||
var _Fable = pFable; | ||
//var _Fable = pFable; | ||
var marshalRecordFromSourceToObject = function(pObject, pRecord, pSchema) | ||
//var marshalRecordFromSourceToObject = function(pObject, pRecord, pSchema) | ||
var marshalRecordFromSourceToObject = function() | ||
{ | ||
@@ -24,0 +25,0 @@ // Do nothing ... this is the NONE provider after all |
@@ -567,22 +567,2 @@ /** | ||
( | ||
'Create a record in the database with bad fields', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
var tmpQuery = testMeadow.query | ||
.addRecord({Name:'Tina', TypeWriter:'Chameleon'}); | ||
testMeadow.doCreate(tmpQuery, | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
Expect(pError) | ||
.to.be.an('object'); | ||
fDone(); | ||
} | ||
) | ||
} | ||
); | ||
test | ||
( | ||
'Create a record in the database with no record', | ||
@@ -779,2 +759,176 @@ function(fDone) | ||
); | ||
test | ||
( | ||
'Set a raw Query', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.rawQueries.setQuery('Read', 'SELECT Something from SomethingElse;'); | ||
Expect(testMeadow.rawQueries.getQuery('Read')) | ||
.to.equal('SELECT Something from SomethingElse;'); | ||
fDone(); | ||
} | ||
); | ||
test | ||
( | ||
'Load a raw Query', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-MySQL-AnimalReadQuery.sql', | ||
function(pSuccess) | ||
{ | ||
Expect(testMeadow.rawQueries.getQuery('Read')) | ||
.to.contain('SELECT'); | ||
fDone(); | ||
}); | ||
} | ||
); | ||
test | ||
( | ||
'Load a bad raw Query', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-MySQL-BADAnimalReadQuery.sql', | ||
function(pSuccess) | ||
{ | ||
Expect(testMeadow.rawQueries.getQuery('Read')) | ||
.to.equal(''); | ||
fDone(); | ||
}); | ||
} | ||
); | ||
test | ||
( | ||
'Load a raw query with no callback', | ||
function() | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-MySQL-AnimalReadQuery.sql'); | ||
} | ||
); | ||
test | ||
( | ||
'Check for a query that is not there', | ||
function() | ||
{ | ||
var testMeadow = newMeadow(); | ||
Expect(testMeadow.rawQueries.getQuery('Read')) | ||
.to.equal(false); | ||
} | ||
); | ||
test | ||
( | ||
'Read a record from a custom query', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-MySQL-AnimalReadQuery.sql', | ||
function(pSuccess) | ||
{ | ||
// Now try to read the record | ||
testMeadow.doRead(testMeadow.query.addFilter('IDAnimal', 2), | ||
function(pError, pQuery, pRecord) | ||
{ | ||
Expect(pRecord.AnimalTypeCustom) | ||
.to.equal('Bunny'); | ||
fDone(); | ||
} | ||
) | ||
}); | ||
} | ||
); | ||
test | ||
( | ||
'Read records from a custom query, then delete one, then read them again then update and create.', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
testMeadow.setDefaultIdentifier('IDAnimal'); | ||
testMeadow.rawQueries.setQuery('Delete', 'DELETE FROM FableTest WHERE IDAnimal = 1;') | ||
testMeadow.rawQueries.setQuery('Count', 'SELECT 1337 AS RowCount;') | ||
testMeadow.rawQueries.setQuery('Read', 'SELECT IDAnimal, Type AS AnimalTypeCustom FROM FableTest <%= Where %>') | ||
testMeadow.rawQueries.setQuery('Update', "UPDATE FableTest SET Type = 'FrogLeg' <%= Where %>") | ||
// And this, my friends, is why we use async.js | ||
testMeadow.rawQueries.loadQuery('Reads', __dirname+ '/Meadow-Provider-MySQL-AnimalReadQuery.sql', | ||
function(pSuccess) | ||
{ | ||
// Now try to read the record | ||
testMeadow.doReads(testMeadow.query.addFilter('IDAnimal', 2), | ||
function(pError, pQuery, pRecords) | ||
{ | ||
Expect(pRecords[1].AnimalTypeCustom) | ||
.to.equal('HumanGirl'); | ||
testMeadow.doDelete(testMeadow.query.addFilter('IDAnimal', 2), | ||
function(pError, pQuery, pRecord) | ||
{ | ||
// It returns the number of rows deleted | ||
Expect(pRecord) | ||
.to.equal(1); | ||
testMeadow.doCount(testMeadow.query.addFilter('IDAnimal', 2), | ||
function(pError, pQuery, pRecord) | ||
{ | ||
// It returns the number of rows deleted | ||
Expect(pRecord) | ||
.to.equal(1337); | ||
var tmpQuery = testMeadow.query | ||
.addRecord({IDAnimal:5, Type:'Bartfast'}); | ||
testMeadow.doUpdate(tmpQuery, | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
// We should have a record .... | ||
Expect(pRecord.AnimalTypeCustom) | ||
.to.equal('Bartfast'); | ||
var tmpQuery = testMeadow.query | ||
.addRecord({Name:'Bambi', Type:'CustomSheep'}); | ||
testMeadow.doCreate(tmpQuery, | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
// We should have a record .... | ||
Expect(pRecord.AnimalTypeCustom) | ||
.to.equal('CustomSheep'); | ||
fDone(); | ||
} | ||
) | ||
} | ||
) | ||
} | ||
) | ||
} | ||
) | ||
} | ||
) | ||
} | ||
); | ||
} | ||
); | ||
test | ||
( | ||
'Create a record in the database with bad fields', | ||
function(fDone) | ||
{ | ||
var testMeadow = newMeadow(); | ||
// NOTE: Bad fields passed in are polluting the schema forever. | ||
var tmpQuery = testMeadow.query | ||
.addRecord({Name:'Tina', TypeWriter:'Chameleon'}); | ||
testMeadow.doCreate(tmpQuery, | ||
function(pError, pQuery, pQueryRead, pRecord) | ||
{ | ||
Expect(pError) | ||
.to.be.an('object'); | ||
fDone(); | ||
} | ||
) | ||
} | ||
); | ||
} | ||
@@ -781,0 +935,0 @@ ); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
74644
25
2712
3