/*
* 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/>.
*/
/**
* find artefacts in C++ source
*
* @memberof PKM
* @instance
* @param {string} dbName - database name
* @param {object} [query] - query { kind : ('string'|'/regex/'), path : ('string'|'/regex/'), id : number, name : ('string'|'/regex/') })
* @param {object} [options] - options
*
* @return {Promise<Array.<Object>>} a promise that passes the result (an array) to resolve callback
*/
function find_in_cpp_source(dbName, query = {}, options = {})
{
return new Promise(function(resolve, reject)
{
const debug = this.debug;
const query_is_empty = Object.keys(query).length == 0;
function search_element(document, id)
{
if(document.hasOwnProperty('id') && (document.id === id))
{
return document;
}
if(document.hasOwnProperty('inner'))
{
for(let i = 0; i < document.inner.length; ++i)
{
const inner_element = document.inner[i];
const found = search_element(inner_element, id)
if(found) return found;
}
}
return undefined;
}
function search(document, query)
{
let result = [];
if(document.hasOwnProperty('manifest'))
{
document.manifest.forEach((manifest_item) =>
{
if(((query.id === undefined) || (query.id === manifest_item.id)) &&
((query.kind === undefined) || ((typeof query.kind === 'string') && (query.kind === manifest_item.kind)) || ((query.kind instanceof RegExp) && query.kind.test(manifest_item.kind))) &&
((query.name === undefined) || ((typeof query.name === 'string') && (query.name === manifest_item.name)) || ((query.name instanceof RegExp) && query.name.test(manifest_item.name))) &&
((query.path === undefined) || ((typeof query.path === 'string') && (query.path === manifest_item.path)) || ((query.path instanceof RegExp) && query.path.test(manifest_item.path))))
{
document.inner.forEach((inner_element) =>
{
const found = search_element(inner_element, manifest_item.id);
if(found !== undefined)
{
result.push(found);
}
});
}
});
}
return result;
}
let get_doc_query = {};
let search_query = {};
if(query !== undefined)
{
if(query.id !== undefined)
{
get_doc_query['manifest.id'] = query.id;
search_query.id = query.id;
}
[ 'kind', 'path', 'name' ].forEach((key) =>
{
if(query[key] !== undefined)
{
if(query[key].startsWith('/') && query[key].endsWith('/'))
{
get_doc_query['manifest.' + key] = { $regex : query[key].slice(1, query[key].length - 1) };
search_query[key] = new RegExp(query[key].slice(1, query[key].length - 1));
}
else
{
get_doc_query['manifest.' + key] = query[key];
search_query[key] = query[key];
}
}
});
}
this.get_documents(dbName, 'sourcecodeCPP', get_doc_query).then((documents) =>
{
let search_promises = [];
documents.forEach((document) =>
{
search_promises.push(new Promise((resolve, reject) =>
{
let result = search(document, search_query);
resolve(result);
}));
});
Promise.all(search_promises).then((results) =>
{
let result = results.reduce((acc, val) => acc.concat(val), []);
if(result.length || query_is_empty)
{
if((options.skip !== undefined) || (options.limit !== undefined))
{
let start = options.skip || 0;
let end = start + (options.limit ? options.limit : result.length);
resolve(result.slice(start, end));
}
else
{
resolve(result);
}
}
else
{
reject(this.NotFound());
}
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
}.bind(this));
}
exports.find_in_cpp_source = find_in_cpp_source;