/*
* Copyright 2015-2016 OpenCB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opencb.opencga.catalog.db.mongodb;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.UpdateResult;
import org.apache.commons.lang.NotImplementedException;
import org.bson.BsonDocument;
import org.bson.BsonString;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.opencb.commons.datastore.core.ObjectMap;
import org.opencb.commons.datastore.core.Query;
import org.opencb.commons.datastore.core.QueryOptions;
import org.opencb.commons.datastore.core.QueryResult;
import org.opencb.commons.datastore.mongodb.MongoDBCollection;
import org.opencb.opencga.catalog.db.api.DBIterator;
import org.opencb.opencga.catalog.db.api.ProjectDBAdaptor;
import org.opencb.opencga.catalog.db.api.StudyDBAdaptor;
import org.opencb.opencga.catalog.db.mongodb.converters.ProjectConverter;
import org.opencb.opencga.catalog.exceptions.CatalogDBException;
import org.opencb.opencga.catalog.models.Project;
import org.opencb.opencga.catalog.models.Status;
import org.opencb.opencga.catalog.models.Study;
import org.opencb.opencga.catalog.models.User;
import org.opencb.opencga.core.common.TimeUtils;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.opencb.opencga.catalog.db.mongodb.MongoDBUtils.parseUser;
/**
* Created by imedina on 08/01/16.
*/
public class ProjectMongoDBAdaptor extends MongoDBAdaptor implements ProjectDBAdaptor {
private final MongoDBCollection userCollection;
private ProjectConverter projectConverter;
public ProjectMongoDBAdaptor(MongoDBCollection userCollection, MongoDBAdaptorFactory dbAdaptorFactory) {
super(LoggerFactory.getLogger(ProjectMongoDBAdaptor.class));
this.dbAdaptorFactory = dbAdaptorFactory;
this.userCollection = userCollection;
this.projectConverter = new ProjectConverter();
}
@Override
public boolean exists(long projectId) {
QueryResult<Long> count = userCollection.count(new Document("projects.id", projectId));
return count.getResult().get(0) != 0;
}
@Override
public QueryResult<Project> insert(Project project, String userId, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
List<Study> studies = project.getStudies();
if (studies == null) {
studies = Collections.emptyList();
}
project.setStudies(Collections.<Study>emptyList());
// Check if project.alias already exists.
// DBObject countQuery = BasicDBObjectBuilder
// .start("id", userId)
// .append("projects.alias", project.getAlias())
// .get();
Bson countQuery = Filters.and(Filters.eq("id", userId), Filters.eq("projects.alias", project.getAlias()));
QueryResult<Long> count = userCollection.count(countQuery);
if (count.getResult().get(0) != 0) {
throw new CatalogDBException("Project {alias:\"" + project.getAlias() + "\"} already exists for this user");
}
// if(getProjectId(userId, project.getAlias()) >= 0){
// throw new CatalogManagerException( "Project {alias:\"" + project.getAlias() + "\"} already exists in this user");
// }
//Generate json
// int projectId = CatalogMongoDBUtils.getNewAutoIncrementId(metaCollection);
long projectId = dbAdaptorFactory.getCatalogMetaDBAdaptor().getNewAutoIncrementId();
project.setId(projectId);
// DBObject query = new BasicDBObject("id", userId);
// query.put("projects.alias", new BasicDBObject("$ne", project.getAlias()));
Bson query = Filters.and(Filters.eq("id", userId), Filters.ne("projects.alias", project.getAlias()));
Document projectDocument = projectConverter.convertToStorageType(project);
// DBObject update = new BasicDBObject("$push", new BasicDBObject("projects", projectDBObject));
Bson update = Updates.push("projects", projectDocument);
//Update object
// QueryResult<WriteResult> queryResult = userCollection.update(query, update, null);
QueryResult<UpdateResult> queryResult = userCollection.update(query, update, null);
if (queryResult.getResult().get(0).getModifiedCount() == 0) { // Check if the project has been inserted
throw new CatalogDBException("Project {alias:\"" + project.getAlias() + "\"} already exists for this user");
}
String errorMsg = "";
for (Study study : studies) {
String studyErrorMsg = dbAdaptorFactory.getCatalogStudyDBAdaptor().insert(project.getId(), study, options).getErrorMsg();
if (studyErrorMsg != null && !studyErrorMsg.isEmpty()) {
errorMsg += ", " + study.getAlias() + ":" + studyErrorMsg;
}
}
List<Project> result = get(project.getId(), null).getResult();
return endQuery("Create Project", startTime, result, errorMsg, null);
}
@Override
public QueryResult<Project> get(long projectId, QueryOptions options) throws CatalogDBException {
checkId(projectId);
return get(new Query(QueryParams.ID.key(), projectId).append(QueryParams.STATUS_NAME.key(), "!=" + Status.DELETED), options);
//
// long startTime = startQuery();
// Bson query = Filters.eq("projects.id", projectId);
// Bson projection = Projections.elemMatch("projects", Filters.eq("id", projectId));
//
// QueryResult<Document> result = userCollection.find(query, projection, options);
//
// User user = parseUser(result);
//
// if (user == null || user.getProjects().isEmpty()) {
// throw CatalogDBException.idNotFound("Project", projectId);
// }
// // Fixme: Check the code below
// List<Project> projects = user.getProjects();
// joinFields(projects.get(0), options);
//
// return endQuery("Get project", startTime, projects);
}
/**
* At the moment it does not clean external references to itself.
*/
// @Override
// public QueryResult<Integer> deleteProject(int projectId) throws CatalogDBException {
// long startTime = startQuery();
// DBObject query = new BasicDBObject("projects.id", projectId);
// DBObject pull = new BasicDBObject("$pull",
// new BasicDBObject("projects",
// new BasicDBObject("id", projectId)));
//
// QueryResult<WriteResult> update = userCollection.update(query, pull, null);
// List<Integer> deletes = new LinkedList<>();
// if (update.getResult().get(0).getN() == 0) {
// throw CatalogDBException.idNotFound("Project", projectId);
// } else {
// deletes.add(update.getResult().get(0).getN());
// return endQuery("delete project", startTime, deletes);
// }
// }
@Override
public QueryResult<Project> get(String userId, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
Query query = new Query(QueryParams.USER_ID.key(), userId);
return endQuery("User projects list", startTime, get(query, options).getResult());
}
/*
* db.user.update(
* {
* "projects.id" : projectId,
* "projects.alias" : {
* $ne : newAlias
* }
* },
* {
* $set:{
* "projects.$.alias":newAlias
* }
* })
*/
@Override
public QueryResult renameAlias(long projectId, String newProjectAlias) throws CatalogDBException {
long startTime = startQuery();
// String projectOwner = getProjectOwner(projectId);
//
// int collisionProjectId = getProjectId(projectOwner, newProjectAlias);
// if (collisionProjectId != -1) {
// throw new CatalogManagerException("Couldn't rename project alias, alias already used in the same user");
// }
QueryResult<Project> projectResult = get(projectId, null); // if projectId doesn't exist, an exception is raised
Project project = projectResult.getResult().get(0);
//String oldAlias = project.getAlias();
project.setAlias(newProjectAlias);
/*
DBObject query = BasicDBObjectBuilder
.start("projects.id", projectId)
.append("projects.alias", new BasicDBObject("$ne", newProjectAlias)) // check that any other project in the user has
// the new name
.get();
DBObject update = new BasicDBObject("$set",
new BasicDBObject("projects.$.alias", newProjectAlias));
*/
Bson query = Filters.and(Filters.eq("projects.id", projectId),
Filters.ne("projects.alias", newProjectAlias));
Bson update = Updates.set("projects.$.alias", newProjectAlias);
QueryResult<UpdateResult> result = userCollection.update(query, update, null);
if (result.getResult().get(0).getModifiedCount() == 0) { //Check if the the study has been inserted
throw new CatalogDBException("Project {alias:\"" + newProjectAlias + "\"} already exists");
}
return endQuery("rename project alias", startTime, result);
}
// @Deprecated
// @Override
// public QueryResult<Project> modifyProject(long projectId, ObjectMap parameters) throws CatalogDBException {
// long startTime = startQuery();
//
// if (!projectExists(projectId)) {
// throw CatalogDBException.idNotFound("Project", projectId);
// }
// //BasicDBObject projectParameters = new BasicDBObject();
// Bson projectParameters = new Document();
//
// String[] acceptedParams = {"name", "creationDate", "description", "organization", "status", "lastModified"};
// for (String s : acceptedParams) {
// if (parameters.containsKey(s)) {
// ((Document) projectParameters).put("projects.$." + s, parameters.getString(s));
// }
// }
// String[] acceptedIntParams = {"quota", "size"};
// for (String s : acceptedIntParams) {
// if (parameters.containsKey(s)) {
// int anInt = parameters.getInt(s, Integer.MIN_VALUE);
// if (anInt != Integer.MIN_VALUE) {
// ((Document) projectParameters).put(s, anInt);
// }
// }
// }
// Map<String, Object> attributes = parameters.getMap("attributes");
// if (attributes != null) {
// for (Map.Entry<String, Object> entry : attributes.entrySet()) {
// ((Document) projectParameters).put("projects.$.attributes." + entry.getKey(), entry.getValue());
// }
//// projectParameters.put("projects.$.attributes", attributes);
// }
//
// if (!((Document) projectParameters).isEmpty()) {
// Bson query = Filters.eq("projects.id", projectId);
// Bson updates = new Document("$set", projectParameters);
// // Fixme: Updates
// /*
// BasicDBObject query = new BasicDBObject("projects.id", projectId);
// BasicDBObject updates = new BasicDBObject("$set", projectParameters);
// */
// QueryResult<UpdateResult> updateResult = userCollection.update(query, updates, null);
// if (updateResult.getResult().get(0).getModifiedCount() == 0) {
// throw CatalogDBException.idNotFound("Project", projectId);
// }
// }
// /*
// if (!projectParameters.isEmpty()) {
// BasicDBObject query = new BasicDBObject("projects.id", projectId);
// BasicDBObject updates = new BasicDBObject("$set", projectParameters);
// QueryResult<WriteResult> updateResult = userCollection.update(query, updates, null);
// if (updateResult.getResult().get(0).getN() == 0) {
// throw CatalogDBException.idNotFound("Project", projectId);
// }
// }
// */
// return endQuery("Modify project", startTime, getProject(projectId, null));
// }
@Override
public long getId(String userId, String projectAlias) throws CatalogDBException {
QueryResult<Document> queryResult = userCollection.find(
new BsonDocument("projects.alias", new BsonString(projectAlias))
.append("id", new BsonString(userId)),
Projections.fields(Projections.include("projects.id"),
Projections.elemMatch("projects", Filters.eq("alias", projectAlias))),
null);
/*
QueryResult<DBObject> queryResult = userCollection.find(
BasicDBObjectBuilder
.start("projects.alias", projectAlias)
.append("id", userId).get(),
BasicDBObjectBuilder.start("projects.id", true)
.append("projects", new BasicDBObject("$elemMatch", new BasicDBObject("alias", projectAlias))).get(),
null
);*/
User user = parseUser(queryResult);
if (user == null || user.getProjects().isEmpty()) {
return -1;
} else {
return user.getProjects().get(0).getId();
}
}
@Override
public String getOwnerId(long projectId) throws CatalogDBException {
// DBObject query = new BasicDBObject("projects.id", projectId);
Bson query = Filters.eq("projects.id", projectId);
// DBObject projection = new BasicDBObject("id", "true");
Bson projection = Projections.include("id");
// QueryResult<DBObject> result = userCollection.find(query, projection, null);
QueryResult<Document> result = userCollection.find(query, projection, null);
if (result.getResult().isEmpty()) {
throw CatalogDBException.idNotFound("Project", projectId);
} else {
return result.getResult().get(0).get("id").toString();
}
}
@Override
public QueryResult<Long> count(Query query) throws CatalogDBException {
Bson bson = parseQuery(query);
return userCollection.count(bson);
}
@Override
public QueryResult distinct(Query query, String field) throws CatalogDBException {
Bson bson = parseQuery(query);
return userCollection.distinct(field, bson);
}
@Override
public QueryResult stats(Query query) {
return null;
}
@Override
public QueryResult<Project> get(Query query, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
if (!query.containsKey(QueryParams.STATUS_NAME.key())) {
query.append(QueryParams.STATUS_NAME.key(), "!=" + Status.TRASHED + ";!=" + Status.DELETED);
}
List<Bson> aggregates = new ArrayList<>();
aggregates.add(Aggregates.unwind("$projects"));
aggregates.add(Aggregates.match(parseQuery(query)));
// Check include
if (options != null && options.get(QueryOptions.INCLUDE) != null) {
List<String> includeList = new ArrayList<>();
List<String> optionsAsStringList = options.getAsStringList(QueryOptions.INCLUDE);
includeList.addAll(optionsAsStringList.stream().collect(Collectors.toList()));
if (!includeList.contains(QueryParams.ID.key())) {
includeList.add(QueryParams.ID.key());
}
// Check if they start with projects.
for (int i = 0; i < includeList.size(); i++) {
if (!includeList.get(i).startsWith("projects.")) {
String param = "projects." + includeList.get(i);
includeList.set(i, param);
}
}
if (includeList.size() > 0) {
aggregates.add(Aggregates.project(Projections.include(includeList)));
}
}
QueryResult<Project> projectQueryResult = userCollection.aggregate(aggregates, projectConverter, options);
if (options == null || !options.containsKey(QueryOptions.EXCLUDE)
|| !options.getAsStringList(QueryOptions.EXCLUDE).contains("projects.studies")) {
for (Project project : projectQueryResult.getResult()) {
Query studyQuery = new Query(StudyDBAdaptor.QueryParams.PROJECT_ID.key(), project.getId());
try {
QueryResult<Study> studyQueryResult = dbAdaptorFactory.getCatalogStudyDBAdaptor().get(studyQuery, options);
project.setStudies(studyQueryResult.getResult());
} catch (CatalogDBException e) {
e.printStackTrace();
}
}
}
return endQuery("Get project", startTime, projectQueryResult.getResult());
}
@Override
public QueryResult nativeGet(Query query, QueryOptions options) throws CatalogDBException {
if (!query.containsKey(QueryParams.STATUS_NAME.key())) {
query.append(QueryParams.STATUS_NAME.key(), "!=" + Status.TRASHED + ";!=" + Status.DELETED);
}
List<Bson> aggregates = new ArrayList<>();
aggregates.add(Aggregates.match(parseQuery(query)));
aggregates.add(Aggregates.unwind("$projects"));
// Check include & excludes
if (options != null && options.get(QueryOptions.INCLUDE) != null) {
List<String> includeList = new ArrayList<>();
List<String> optionsAsStringList = options.getAsStringList(QueryOptions.INCLUDE);
includeList.addAll(optionsAsStringList.stream().collect(Collectors.toList()));
if (includeList.size() > 0) {
aggregates.add(Aggregates.project(Projections.include(includeList)));
}
}
QueryResult<Document> projectQueryResult = userCollection.aggregate(aggregates, options);
ArrayList<Document> returnedProjectList = new ArrayList<>();
for (Document user : projectQueryResult.getResult()) {
Document project = (Document) user.get("projects");
Query studyQuery = new Query(StudyDBAdaptor.QueryParams.PROJECT_ID.key(), project.get("id"));
QueryResult studyQueryResult = dbAdaptorFactory.getCatalogStudyDBAdaptor().nativeGet(studyQuery, options);
project.remove("studies");
project.append("studies", studyQueryResult.getResult());
returnedProjectList.add(project);
}
projectQueryResult.setResult(returnedProjectList);
return projectQueryResult;
}
@Override
public QueryResult<Long> update(Query query, ObjectMap parameters) throws CatalogDBException {
long startTime = startQuery();
Bson projectParameters = new Document();
String[] acceptedParams = {QueryParams.NAME.key(), QueryParams.CREATION_DATE.key(), QueryParams.DESCRIPTION.key(),
QueryParams.ORGANIZATION.key(), QueryParams.LAST_MODIFIED.key(), QueryParams.ORGANISM_SCIENTIFIC_NAME.key(),
QueryParams.ORGANISM_COMMON_NAME.key(), QueryParams.ORGANISM_ASSEMBLY.key(), };
for (String s : acceptedParams) {
if (parameters.containsKey(s)) {
((Document) projectParameters).put("projects.$." + s, parameters.getString(s));
}
}
String[] acceptedIntParams = {QueryParams.SIZE.key(), QueryParams.ORGANISM_TAXONOMY_CODE.key(), };
for (String s : acceptedIntParams) {
if (parameters.containsKey(s)) {
int anInt = parameters.getInt(s, Integer.MIN_VALUE);
if (anInt != Integer.MIN_VALUE) {
((Document) projectParameters).put("projects.$." + s, anInt);
}
}
}
Map<String, Object> attributes = parameters.getMap(QueryParams.ATTRIBUTES.key());
if (attributes != null) {
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
((Document) projectParameters).put("projects.$.attributes." + entry.getKey(), entry.getValue());
}
// projectParameters.put("projects.$.attributes", attributes);
}
if (parameters.containsKey(QueryParams.STATUS_NAME.key())) {
((Document) projectParameters).put("projects.$." + QueryParams.STATUS_NAME.key(),
parameters.get(QueryParams.STATUS_NAME.key()));
((Document) projectParameters).put("projects.$." + QueryParams.STATUS_DATE.key(), TimeUtils.getTime());
}
QueryResult<UpdateResult> updateResult = new QueryResult<>();
if (!((Document) projectParameters).isEmpty()) {
Bson bsonQuery = parseQuery(query);
Bson updates = new Document("$set", projectParameters);
// Fixme: Updates
/*
BasicDBObject query = new BasicDBObject("projects.id", projectId);
BasicDBObject updates = new BasicDBObject("$set", projectParameters);
*/
updateResult = userCollection.update(bsonQuery, updates, null);
}
/*
if (!projectParameters.isEmpty()) {
BasicDBObject query = new BasicDBObject("projects.id", projectId);
BasicDBObject updates = new BasicDBObject("$set", projectParameters);
QueryResult<WriteResult> updateResult = userCollection.update(query, updates, null);
if (updateResult.getResult().get(0).getN() == 0) {
throw CatalogDBException.idNotFound("Project", projectId);
}
}
*/
return endQuery("Update project", startTime, Collections.singletonList(updateResult.first().getModifiedCount()));
}
@Override
public QueryResult<Project> update(long id, ObjectMap parameters) throws CatalogDBException {
long startTime = startQuery();
checkId(id);
QueryResult<Long> update = update(new Query(QueryParams.ID.key(), id), parameters);
if (update.getNumTotalResults() != 1) {
throw new CatalogDBException("Could not update project with id " + id);
}
return endQuery("Update project", startTime, get(id, null));
}
public void delete(long id) throws CatalogDBException {
Query query = new Query(QueryParams.ID.key(), id);
Document pull = new Document("$pull", new Document("projects", new Document("id", id)));
QueryResult<UpdateResult> update = userCollection.update(parseQuery(query), pull, null);
if (update.first().getModifiedCount() != 1) {
throw CatalogDBException.deleteError("Project " + id);
}
}
@Override
public void delete(Query query) throws CatalogDBException {
throw new NotImplementedException();
}
@Deprecated
@Override
public QueryResult<Project> delete(long id, QueryOptions queryOptions) throws CatalogDBException {
long startTime = startQuery();
checkId(id);
// Check the project is active
Query query = new Query(QueryParams.ID.key(), id).append(QueryParams.STATUS_NAME.key(), Status.READY);
if (count(query).first() == 0) {
query.put(QueryParams.STATUS_NAME.key(), Status.TRASHED + "," + Status.DELETED);
QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, QueryParams.STATUS_NAME.key());
Project project = get(query, options).first();
throw new CatalogDBException("The project {" + id + "} was already " + project.getStatus().getName());
}
// If we don't find the force parameter, we check first if the user does not have an active project.
if (!queryOptions.containsKey(FORCE) || !queryOptions.getBoolean(FORCE)) {
checkCanDelete(id);
}
if (queryOptions.containsKey(FORCE) && queryOptions.getBoolean(FORCE)) {
// Delete the active studies (if any)
query = new Query(StudyDBAdaptor.QueryParams.PROJECT_ID.key(), id);
dbAdaptorFactory.getCatalogStudyDBAdaptor().delete(query, queryOptions);
}
// Change the status of the project to deleted
setStatus(id, Status.TRASHED);
query = new Query(QueryParams.ID.key(), id)
.append(QueryParams.STATUS_NAME.key(), Status.TRASHED);
return endQuery("Delete project", startTime, get(query, queryOptions));
}
@Override
public QueryResult<Long> delete(Query query, QueryOptions queryOptions) throws CatalogDBException {
long startTime = startQuery();
query.append(QueryParams.STATUS_NAME.key(), Status.READY);
QueryResult<Project> projectQueryResult = get(query, new QueryOptions(MongoDBCollection.INCLUDE, QueryParams.ID.key()));
for (Project project : projectQueryResult.getResult()) {
delete(project.getId(), queryOptions);
}
return endQuery("Delete project", startTime, Collections.singletonList(projectQueryResult.getNumTotalResults()));
}
QueryResult<Long> setStatus(Query query, String status) throws CatalogDBException {
return update(query, new ObjectMap(QueryParams.STATUS_NAME.key(), status));
}
private QueryResult<Project> setStatus(long projectId, String status) throws CatalogDBException {
return update(projectId, new ObjectMap(QueryParams.STATUS_NAME.key(), status));
}
@Override
public QueryResult<Project> remove(long id, QueryOptions queryOptions) throws CatalogDBException {
throw new UnsupportedOperationException("Remove not yet implemented.");
}
@Override
public QueryResult<Long> remove(Query query, QueryOptions queryOptions) throws CatalogDBException {
throw new UnsupportedOperationException("Remove not yet implemented.");
}
@Override
public QueryResult<Long> restore(Query query, QueryOptions queryOptions) throws CatalogDBException {
long startTime = startQuery();
query.put(QueryParams.STATUS_NAME.key(), Status.TRASHED);
return endQuery("Restore projects", startTime, setStatus(query, Status.READY));
}
@Override
public QueryResult<Project> restore(long id, QueryOptions queryOptions) throws CatalogDBException {
long startTime = startQuery();
checkId(id);
// Check if the cohort is active
Query query = new Query(QueryParams.ID.key(), id)
.append(QueryParams.STATUS_NAME.key(), Status.TRASHED);
if (count(query).first() == 0) {
throw new CatalogDBException("The project {" + id + "} is not deleted");
}
// Change the status of the cohort to deleted
setStatus(id, Status.READY);
query = new Query(QueryParams.ID.key(), id);
return endQuery("Restore project", startTime, get(query, null));
}
@Override
public DBIterator<Project> iterator(Query query, QueryOptions options) throws CatalogDBException {
Bson bson = parseQuery(query);
MongoCursor<Document> iterator = userCollection.nativeQuery().find(bson, options).iterator();
return new MongoDBIterator<>(iterator, projectConverter);
}
@Override
public DBIterator nativeIterator(Query query, QueryOptions options) throws CatalogDBException {
Bson bson = parseQuery(query);
MongoCursor<Document> iterator = userCollection.nativeQuery().find(bson, options).iterator();
return new MongoDBIterator<>(iterator);
}
@Override
public QueryResult rank(Query query, String field, int numResults, boolean asc) {
throw new NotImplementedException("Rank project is not implemented");
}
@Override
public QueryResult groupBy(Query query, String field, QueryOptions options) {
throw new NotImplementedException("GroupBy in project is not implemented");
}
@Override
public QueryResult groupBy(Query query, List<String> fields, QueryOptions options) {
throw new NotImplementedException("GroupBy in project is not implemented");
}
@Override
public void forEach(Query query, Consumer<? super Object> action, QueryOptions options) throws CatalogDBException {
Objects.requireNonNull(action);
DBIterator<Project> catalogDBIterator = iterator(query, options);
while (catalogDBIterator.hasNext()) {
action.accept(catalogDBIterator.next());
}
catalogDBIterator.close();
}
private Bson parseQuery(Query query) throws CatalogDBException {
List<Bson> andBsonList = new ArrayList<>();
for (Map.Entry<String, Object> entry : query.entrySet()) {
String key = entry.getKey().split("\\.")[0];
QueryParams queryParam = QueryParams.getParam(entry.getKey()) != null ? QueryParams.getParam(entry.getKey())
: QueryParams.getParam(key);
if (queryParam == null) {
continue;
}
try {
switch (queryParam) {
case ID:
addOrQuery("projects." + queryParam.key(), queryParam.key(), query, queryParam.type(), andBsonList);
break;
case USER_ID:
addOrQuery(PRIVATE_ID, queryParam.key(), query, queryParam.type(), andBsonList);
break;
case ATTRIBUTES:
addAutoOrQuery("projects." + entry.getKey(), entry.getKey(), query, queryParam.type(), andBsonList);
break;
case BATTRIBUTES:
String mongoKey = "projects." + entry.getKey().replace(QueryParams.BATTRIBUTES.key(), QueryParams.ATTRIBUTES.key());
addAutoOrQuery(mongoKey, entry.getKey(), query, queryParam.type(), andBsonList);
break;
case NATTRIBUTES:
mongoKey = "projects." + entry.getKey().replace(QueryParams.NATTRIBUTES.key(), QueryParams.ATTRIBUTES.key());
addAutoOrQuery(mongoKey, entry.getKey(), query, queryParam.type(), andBsonList);
break;
case NAME:
case ALIAS:
case CREATION_DATE:
case DESCRIPTION:
case ORGANIZATION:
case ORGANISM:
case ORGANISM_SCIENTIFIC_NAME:
case ORGANISM_COMMON_NAME:
case ORGANISM_TAXONOMY_CODE:
case ORGANISM_ASSEMBLY:
case STATUS_NAME:
case STATUS_MSG:
case STATUS_DATE:
case LAST_MODIFIED:
case SIZE:
case DATASTORES:
case STUDY_ID:
case STUDY_NAME:
case STUDY_ALIAS:
case STUDY_CREATOR_ID:
case STUDY_STATUS:
case STUDY_LAST_MODIFIED:
case ACL_USER_ID:
addAutoOrQuery("projects." + queryParam.key(), queryParam.key(), query, queryParam.type(), andBsonList);
break;
default:
break;
}
} catch (Exception e) {
throw new CatalogDBException(e);
}
}
if (andBsonList.size() > 0) {
return Filters.and(andBsonList);
} else {
return new Document();
}
}
/**
* Checks whether the projectId has any active study.
*
* @param projectId project id.
* @throws CatalogDBException when the project has active studies. Studies must be deleted first.
*/
private void checkCanDelete(long projectId) throws CatalogDBException {
checkId(projectId);
Query query = new Query(StudyDBAdaptor.QueryParams.PROJECT_ID.key(), projectId)
.append(StudyDBAdaptor.QueryParams.STATUS_NAME.key(), Status.READY);
Long count = dbAdaptorFactory.getCatalogStudyDBAdaptor().count(query).first();
if (count > 0) {
throw new CatalogDBException("The project {" + projectId + "} cannot be deleted. The project has " + count
+ " studies in use.");
}
}
}