From 4a620e61e0c8bbe4924a76cbf2e7ed7b608a8998 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Tue, 13 Feb 2024 17:46:37 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20`Model#findOne(conditions,=20?= =?UTF-8?q?options)`=20and=20`Model#findAll(conditions,=20options)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + lib/app/helper_model/00-base_criteria.js | 4 +-- lib/app/helper_model/10-model_criteria.js | 27 ++++++++++++------ lib/app/helper_model/model.js | 34 +++++++++++++++++++++++ test/03-model.js | 33 ++++++++++++++++++++++ 5 files changed, 89 insertions(+), 10 deletions(-) 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) {