Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/8401_icat_update_query_l…
Browse files Browse the repository at this point in the history
…ang'
  • Loading branch information
gesnerpassos committed Nov 15, 2013
2 parents f1e2972 + c06ec21 commit ac231bd
Showing 1 changed file with 66 additions and 77 deletions.
143 changes: 66 additions & 77 deletions Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp
Expand Up @@ -115,16 +115,8 @@ namespace Mantid
*/
std::string ICat4Catalog::getSearchQuery(const CatalogSearchParam& inputs)
{
// This will hold strings for each table of the query. Each segment will be joined together (<->).
std::vector<std::string> querySegments;

// The investigation segment will be stored here as it makes up for several inputs.
// It will be converted to a string, joined and then added to the querySegments.
std::vector<std::string> investigationWhere;

// In ICat4.2 `Dataset` and `Sample` cannot be in the same query (due to restriction with join).
// As such, we will query for sample only when dataset inputs are not used.
bool queryDataset = false;
// Contain the related where and join clauses for the search query based on user-input.
std::vector<std::string> whereClause, joinClause;

// Format the timestamps in order to compare them.
std::string startDate = formatDateTime(inputs.getStartDate(), "%Y-%m-%d %H:%M:%S");
Expand All @@ -133,120 +125,113 @@ namespace Mantid
// Investigation startDate if endDate is not selected
if (inputs.getStartDate() != 0 && inputs.getEndDate() == 0)
{
investigationWhere.push_back("startDate >= '" + startDate + "'");
whereClause.push_back("inves.startDate >= '" + startDate + "'");
}

// Investigation endDate if startdate is not selected
if (inputs.getEndDate() != 0 && inputs.getStartDate() == 0)
{
investigationWhere.push_back("endDate <= '" + endDate + "'");
whereClause.push_back("inves.endDate <= '" + endDate + "'");
}

// Investigation Start and end date if both selected
if(inputs.getStartDate() != 0 && inputs.getEndDate() != 0)
{
investigationWhere.push_back("startDate BETWEEN '" + startDate + "' AND '" + endDate + "'");
whereClause.push_back("inves.startDate BETWEEN '" + startDate + "' AND '" + endDate + "'");
}

// Investigation name (title)
if(!inputs.getInvestigationName().empty())
{
investigationWhere.push_back("title LIKE '%" + inputs.getInvestigationName() + "%' ");
}

// Iterate over query vector and append AND between inputs.
std::string investigationResult = Strings::join(investigationWhere.begin(), investigationWhere.end(), " AND ");

// Add the investigation result to the query if it exists.
if (!investigationResult.empty())
{
querySegments.push_back("Investigation[" + investigationResult + "]");
whereClause.push_back("inves.title LIKE '%" + inputs.getInvestigationName() + "%'");
}

// Investigation type
if(!inputs.getInvestigationType().empty())
{
querySegments.push_back("InvestigationType[name IN ('" + inputs.getInvestigationType() + "')]");
joinClause.push_back("JOIN inves.type itype");
whereClause.push_back("itype.name = '" + inputs.getInvestigationType() + "'");
}

// Investigator's surname
if(!inputs.getInvestigatorSurName().empty())
// Instrument name
if(!inputs.getInstrument().empty())
{
querySegments.push_back("InvestigationUser <-> User[name LIKE '%" + inputs.getInvestigatorSurName() + "%']");
joinClause.push_back("JOIN inves.investigationInstruments invInst");
joinClause.push_back("JOIN invInst.instrument inst");
whereClause.push_back("inst.name = '" + inputs.getInstrument() + "'");
}

// Datafile name
if(!inputs.getDatafileName().empty())
// Keywords
if(!inputs.getKeywords().empty())
{
querySegments.push_back("Dataset <-> Datafile[name LIKE '%" + inputs.getDatafileName() + "%']");
queryDataset = true;
joinClause.push_back("JOIN inves.keywords keywords");
whereClause.push_back("keywords.name IN ('" + inputs.getKeywords() + "')");
}

// Run start and end
if(inputs.getRunStart() > 0 && inputs.getRunEnd() > 0)
// Sample name
if(!inputs.getSampleName().empty())
{
// Convert the start and end runs to string.
std::string runStart = Strings::toString(inputs.getRunStart());
std::string runEnd = Strings::toString(inputs.getRunEnd());

// To be able to use DatafileParameter we need to have access to Dataset and Datafile.
// If queryDataset is true, then we can rest assured that the relevant access is possible.
if (queryDataset)
{
querySegments.push_back("DatafileParameter[type.name ='run_number' AND numericValue BETWEEN " + runStart + " AND " + runEnd + "]");
}
else
{
// Otherwise we directly include them ourselves.
querySegments.push_back("Dataset <-> Datafile <-> DatafileParameter[type.name ='run_number' AND numericValue BETWEEN " + runStart + " AND " + runEnd + "]");
// We then set queryDataset to true since Sample can not be included if a dataset is.
queryDataset = true;
}
joinClause.push_back("JOIN inves.samples sample");
whereClause.push_back("sample.name LIKE '%" + inputs.getSampleName() + "%'");
}

// Instrument name
if(!inputs.getInstrument().empty())
// If the user has selected the "My data only" button.
// (E.g. they want to display or search through all the data they have access to.
if (inputs.getMyData())
{
querySegments.push_back("InvestigationInstrument <-> Instrument[name = '" + inputs.getInstrument() + "']");
joinClause.push_back("JOIN inves.investigationUsers users");
joinClause.push_back("JOIN users.user user");
whereClause.push_back("user.name = :user");
}

// Keywords
if(!inputs.getKeywords().empty())
// Investigators complete name.
if (!inputs.getInvestigatorSurName().empty())
{
querySegments.push_back("Keyword[name IN ('" + inputs.getKeywords() + "')]");
// We join another investigationUsers & user tables as we need two aliases.
joinClause.push_back("JOIN inves.investigationUsers usrs");
joinClause.push_back("JOIN usrs.user usr");
whereClause.push_back("usr.fullName LIKE '%" + inputs.getInvestigatorSurName() + "%'");
}

// Sample name
if(!inputs.getSampleName().empty() && !queryDataset)
// Similar to above. We check if either has been input,
// join the related table and add the specific WHERE clause.
if(!inputs.getDatafileName().empty() || (inputs.getRunStart() > 0 && inputs.getRunEnd() > 0))
{
querySegments.push_back("Sample[name = '" + inputs.getSampleName() + "']");
}

// Now we build the query from the segments. For each segment, we append a join ("<->").
std::string query = Strings::join(querySegments.begin(), querySegments.end(), " <-> ");
joinClause.push_back("JOIN inves.datasets dataset");
joinClause.push_back("JOIN dataset.datafiles datafile");

// We then append the required includes to output related data, such as instrument name and run parameters.
if (!query.empty())
{
// If the user wants to search through their data in their archive.
if (inputs.getMyData())
if (!inputs.getDatafileName().empty())
{
query.insert(0, "DISTINCT Investigation INCLUDE InvestigationInstrument, Instrument, InvestigationParameter <-> InvestigationUser <-> User[name = :user] <-> ");
whereClause.push_back("datafile.name LIKE '%" + inputs.getDatafileName() + "%'");
}
// Otherwise, we search the entire archive.
else

if (inputs.getRunStart() > 0 && inputs.getRunEnd() > 0)
{
query.insert(0, "DISTINCT Investigation INCLUDE InvestigationInstrument, Instrument, InvestigationParameter <-> ");
joinClause.push_back("JOIN datafile.parameters datafileparameters");
joinClause.push_back("JOIN datafileparameters.type dtype");
whereClause.push_back("dtype.name='run_number' AND datafileparameters.numericValue BETWEEN "
+ Strings::toString(inputs.getRunStart()) + " AND " + Strings::toString(inputs.getRunEnd()) + "");
}
}

// If the user has only selected the "My data only" button (E.g. they want to display all their "My data").
if (query.empty() && inputs.getMyData())
std::string query;

// This prevents the user searching the entire archive (E.g. there is no "default" query).
if (!whereClause.empty() || !joinClause.empty())
{
query.insert(0, "DISTINCT Investigation INCLUDE InvestigationInstrument, Instrument, InvestigationParameter <-> InvestigationUser <-> User[name = :user]");
std::string select, from, join, where, orderBy, includes;

select = "SELECT DISTINCT inves";
from = " FROM Investigation inves ";
join = Strings::join(joinClause.begin(), joinClause.end(), " ");
where = Strings::join(whereClause.begin(), whereClause.end(), " AND ");
where.insert(0, " WHERE ");
orderBy = " ORDER BY inves.id ASC";
includes = " INCLUDE inves.investigationInstruments.instrument, inves.parameters";
query = select + from + join + where + orderBy + includes;
}

g_log.debug() << "Query: { " << query << " }" << std::endl;
g_log.debug() << "ICat4Catalog::getSearchQuery: { " << query << " }" << std::endl;

return (query);
}
Expand Down Expand Up @@ -413,6 +398,8 @@ namespace Mantid
std::string query = "Datafile <-> Dataset <-> Investigation[id = '" + boost::lexical_cast<std::string>(investigationId) + "']";
request.query = &query;

g_log.debug() << "ICat4Catalog::getDataSets -> { " << query << " }" << std::endl;

int result = icat.search(&request, &response);

if (result == 0)
Expand Down Expand Up @@ -481,6 +468,8 @@ namespace Mantid
std::string query = "Datafile <-> Dataset <-> Investigation[id = '" + boost::lexical_cast<std::string>(investigationId) + "']";
request.query = &query;

g_log.debug() << "ICat4Catalog::getDataSets -> { " << query << " }" << std::endl;

int result = icat.search(&request, &response);

if (result == 0)
Expand Down Expand Up @@ -684,7 +673,7 @@ namespace Mantid
// Add all the REST pieces to the URL.
urlToBuild += ("getData?" + session + datafile + outname + "&zip=false");

g_log.debug() << "External URL is: " << urlToBuild << std::endl;
g_log.debug() << "ICat4Catalog::getDownloadURL -> { " << urlToBuild << " }" << std::endl;

url = urlToBuild;
}
Expand Down

0 comments on commit ac231bd

Please sign in to comment.