diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c14963a..dd5065f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Remove the deprecated `DbQuery` class * Let field/association constraints be a `Criteria` instance * Add "AQL" (Alchemy Query Language) implementation +* Add `Model#findOne(conditions, options)` and `Model#findAll(conditions, options)` ## 1.3.22 (2023-12-21) diff --git a/lib/app/helper_model/00-base_criteria.js b/lib/app/helper_model/00-base_criteria.js index 557b5da4..a8e0b2ce 100644 --- a/lib/app/helper_model/00-base_criteria.js +++ b/lib/app/helper_model/00-base_criteria.js @@ -58,8 +58,8 @@ Criteria.setStatic(function isCriteria(instance) { * @since 1.4.0 * @version 1.4.0 * - * @param {Object} conditions The conditions - * @param {Object} options The thing that should be a criteria + * @param {Object|string|Criteria} conditions + * @param {Object} options * * @return {Criteria} */ diff --git a/lib/app/helper_model/10-model_criteria.js b/lib/app/helper_model/10-model_criteria.js index 30ce9eee..e12a4584 100644 --- a/lib/app/helper_model/10-model_criteria.js +++ b/lib/app/helper_model/10-model_criteria.js @@ -27,23 +27,34 @@ const Criteria = Function.inherits('Alchemy.Criteria.Criteria', function Model(m * * @author Jelle De Loecker * @since 1.2.5 - * @version 1.3.4 + * @version 1.4.0 * - * @param {Object} obj The thing that should be a criteria - * @param {Model} model The model that it probably belongs to + * @param {Object} conditions The thing that should be a criteria + * @param {Object} options The options to apply + * @param {Model} model The model that it probably belongs to * * @return {Criteria} */ -Criteria.setStatic(function cast(obj, model) { +Criteria.setStatic(function cast(conditions, options, model) { + + if (Criteria.isCriteria(conditions)) { + return conditions; + } - if (Criteria.isCriteria(obj)) { - return obj; + if (arguments.length == 2) { + model = options; + options = conditions; + conditions = null; } let instance = new Criteria(model); - if (obj) { - instance.applyOldOptions(obj); + if (options) { + instance.applyOldOptions(options); + } + + if (conditions) { + instance.applyConditions(conditions); } return instance; diff --git a/lib/app/helper_model/model.js b/lib/app/helper_model/model.js index c6a4efdd..5ea26ee0 100644 --- a/lib/app/helper_model/model.js +++ b/lib/app/helper_model/model.js @@ -1,3 +1,5 @@ +const CriteriaNS = Function.getNamespace('Alchemy.Criteria'); + let class_cache = new Map(), fallback_datasource, TABLE = Symbol('table'); @@ -668,6 +670,38 @@ Model.setMethod(function getAliasModel(alias) { return result; }); +/** + * Find one record + * + * @author Jelle De Loecker + * @since 1.4.0 + * @version 1.4.0 + * + * @param {string|Object|Criteria} conditions + * + * @return {Pledge|Criteria} + */ +Model.setMethod(function findOne(conditions, options) { + conditions = CriteriaNS.Model.cast(conditions, options, this); + return this.find('first', conditions); +}); + +/** + * Find all records + * + * @author Jelle De Loecker + * @since 1.4.0 + * @version 1.4.0 + * + * @param {string|Object|Criteria} conditions + * + * @return {Pledge|Criteria} + */ +Model.setMethod(function findAll(conditions, options) { + conditions = CriteriaNS.Model.cast(conditions, options, this); + return this.find('all', conditions); +}); + /** * Query the database * diff --git a/test/03-model.js b/test/03-model.js index 17bb1fe6..02b1d360 100644 --- a/test/03-model.js +++ b/test/03-model.js @@ -1153,6 +1153,39 @@ describe('Model', function() { }); }); + describe('#findOne(string)', () => { + it('should find a single document by an AQL query', async () => { + + const Person = Model.get('Person'); + + let record = await Person.findOne('_id = "' + _id + '"'); + assert.strictEqual(String(_id), String(record._id)); + + record = await Person.findOne('birthdate < "1980-01-01"'); + assert.strictEqual(record.firstname, 'Griet'); + + record = await Person.findOne('birthdate > "1980-01-01"'); + assert.strictEqual(record.firstname, 'Jelle'); + }); + }); + + describe('#findAll(string)', () => { + it('should find all documents matching an AQL query', async () => { + + const Person = Model.get('Person'); + + let records = await Person.findAll('_id = "' + _id + '"'); + assert.strictEqual(records.length, 1); + assert.strictEqual(String(_id), String(records[0]._id)); + + records = await Person.findAll('birthdate < "2000-01-01"'); + assert.strictEqual(records.length, 2); + + records = await Person.findAll('birthdate > "1980-01-01"'); + assert.strictEqual(records.length, 1); + }); + }); + describe('#findById(object_id, callback)', function() { it('should find a single document by ObjectId instance', function(done) { Model.get('Person').findById(_id, function gotPerson(err, person) {