Source: core/count_documents.js

/*
 * This file is part of PKM (Persistent Knowledge Monitor).
 * Copyright (c) 2020 Capgemini Group, Commissariat à l'énergie atomique et aux énergies alternatives,
 *                    OW2, Sysgo AG, Technikon, Tree Technology, Universitat Politècnica de València.
 * 
 * PKM is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation.
 * 
 * PKM is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with PKM.  If not, see <https://www.gnu.org/licenses/>.
 */

/**
 * Count documents in a generic manner of a collection of a database
 * 
 * @memberof PKM
 * @instance
 * @param {string} dbName - database name
 * @param {string} collection_name - collection name
 * @param {Object} [query] - query
 * @param {Object} [options] - options
 * 
 * @return {Promise} a promise
 */
function count_documents(dbName, collection_name, query = {}, options = {})
{
	return new Promise(function(resolve, reject)
	{
		const debug = this.debug;
		if(debug)
		{
			console.log('PKM.count_documents(' + JSON.stringify(dbName) + ',' + JSON.stringify(collection_name) + ',' + JSON.stringify(query) + ',' + JSON.stringify(options) + ')');
		}
		const has_postprocess = (this.has_postprocess[collection_name] !== undefined) && this.has_postprocess[collection_name](options);
		
		this.get_collection(dbName, collection_name).then((documents_collection) =>
		{
			if(has_postprocess)
			{
				let documents = [];
				
				let find_options = Object.assign({}, options);
				if(options.skip !== undefined) delete find_options.skip;
				if(options.limit !== undefined) delete find_options.limit;
				
				let document_cursor = documents_collection.find(query, find_options);
				
				document_cursor.forEach((document) =>
				{
					documents.push(this.fix_document(document, collection_name));
				}, (err) =>
				{
					if(err)
					{
						reject(this.Error(err));
					}
					else
					{
						let count = documents.length;
						if(count)
						{
							if(debug)
							{
								console.log('Counted ' + count + ' document(s) for ' + JSON.stringify(query) + ' in collection \'' + collection_name + '\' of database \'' + dbName + '\'');
							}
							
							const postprocess = this.postprocess[collection_name];
							const postprocess_slicing = has_postprocess && (options.skip || options.limit);
							if(postprocess !== undefined)
							{
								count = postprocess(documents, options).length;
								if(debug)
								{
									console.log('After postprocessing, counted ' + count + ' document(s) from collection for ' + JSON.stringify(query) + ' in \'' + collection_name + '\' of database \'' + dbName + '\'');
								}
								if(postprocess_slicing)
								{
									const start = options.skip || 0;
									const end = start + (options.limit ? options.limit : count);
									count = end - start;
									if(debug)
									{
										console.log('After slicing [' + start + ',' + end + '[, counted ' + count + ' document(s) for ' + JSON.stringify(query) + ' in collection \'' + collection_name + '\' of database \'' + dbName + '\'');
									}
								}
							}
							
							if(debug && ((postprocess !== undefined) || postprocess_slicing))
							{
								console.log('Overall counted ' + count + ' document(s) for ' + JSON.stringify(query) + ' in collection \'' + collection_name + '\' of database \'' + dbName + '\'');
							}
						}
						
						resolve(count);
					}
				});
			}
			else
			{
				documents_collection.countDocuments(query, options).then((count) =>
				{
					if(debug)
					{
						console.log('Counted ' + count + ' document(s) for ' + JSON.stringify(query) + ' in collection \'' + collection_name + '\'');
					}
					resolve(count);
				}).catch((err) =>
				{
					reject(this.Error(err));
				});
			}
		}).catch((err) =>
		{
			reject(this.Error(err));
		});
	}.bind(this));
}

module.exports.count_documents = count_documents;