/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.persistence.dao.impl;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import org.orcid.jaxb.model.common_v2.Visibility;
import org.orcid.persistence.dao.ProfileFundingDao;
import org.orcid.persistence.jpa.entities.ProfileFundingEntity;
import org.springframework.transaction.annotation.Transactional;
public class ProfileFundingDaoImpl extends GenericDaoImpl<ProfileFundingEntity, Long> implements ProfileFundingDao {
public ProfileFundingDaoImpl() {
super(ProfileFundingEntity.class);
}
/**
* Find and retrieve a profile funding that have the given id and belongs to the given user
*
* @param userOrcid
* The owner of the funding
* @param profileFundingId
* The id of the element
* @return a profile funding entity that have the give id and belongs to the given user
* */
@Override
public ProfileFundingEntity getProfileFunding(String userOrcid, Long profileFundingId) {
Query query = entityManager.createQuery("from ProfileFundingEntity where profile.id=:userOrcid and id=:profileFundingId");
query.setParameter("userOrcid", userOrcid);
query.setParameter("profileFundingId", profileFundingId);
return (ProfileFundingEntity) query.getSingleResult();
}
/**
* Removes the relationship that exists between a funding and a profile.
*
* @param profileFundingId
* The id of the profileFunding that will be removed from the
* client profile
* @param userOrcid
* The user orcid
* @return true if the relationship was deleted
* */
@Override
@Transactional
public boolean removeProfileFunding(String userOrcid, Long profileFundingId) {
Query query = entityManager.createQuery("delete from ProfileFundingEntity where profile.id=:userOrcid and id=:profileFundingId");
query.setParameter("userOrcid", userOrcid);
query.setParameter("profileFundingId", profileFundingId);
return query.executeUpdate() > 0 ? true : false;
}
/**
* Updates the visibility of an existing profile funding relationship
*
* @param clientOrcid
* The client orcid
*
* @param profileFundingId
* The id of the profile funding that will be updated
*
* @param visibility
* The new visibility value for the profile profileFunding object
*
* @return true if the relationship was updated
* */
@Override
@Transactional
public boolean updateProfileFundingVisibility(String clientOrcid, Long profileFundingId, Visibility visibility) {
Query query = entityManager.createQuery("update ProfileFundingEntity set visibility=:visibility where profile.id=:clientOrcid and id=:profileFundingId");
query.setParameter("clientOrcid", clientOrcid);
query.setParameter("profileFundingId", profileFundingId);
query.setParameter("visibility", visibility);
return query.executeUpdate() > 0 ? true : false;
}
/**
* Creates a new profile funding relationship between an organization and a
* profile.
*
* @param newProfileFundingEntity
* The object to be persisted
* @return the created newProfileFundingEntity with the id assigned on
* database
* */
@Override
@Transactional
public ProfileFundingEntity addProfileFunding(ProfileFundingEntity newProfileFundingEntity) {
entityManager.persist(newProfileFundingEntity);
return newProfileFundingEntity;
}
/**
* Get the funding associated with the client orcid and the organization id
*
* @param clientOrcid
* The client orcid
*
* @param orgId
* The id of the organization
*
* @return the ProfileFundingEntity object
* */
@Override
public ProfileFundingEntity getProfileFundingEntity(String orgId, String clientOrcid) {
Query query = entityManager.createQuery("from ProfileFundingEntity where profile.id=:clientOrcid and org.id=:orgId");
query.setParameter("clientOrcid", clientOrcid);
query.setParameter("orgId", Long.valueOf(orgId));
return (ProfileFundingEntity) query.getSingleResult();
}
/**
* Get the funding associated with the given profileFunding id
*
* @param profileFundingId
* The id of the ProfileFundingEntity object
*
* @return the ProfileFundingEntity object
* */
@Override
public ProfileFundingEntity getProfileFundingEntity(Long profileFundingId) {
Query query = entityManager.createQuery("from ProfileFundingEntity where id=:id");
query.setParameter("id", profileFundingId);
return (ProfileFundingEntity) query.getSingleResult();
}
/**
* Get all the profile fundings where the amount is not null
*
* @return a list of all profile fundings where the amount is not null
* */
public List<ProfileFundingEntity> getProfileFundingWithAmount() {
TypedQuery<ProfileFundingEntity> query = entityManager.createQuery("from ProfileFundingEntity where amount is not null and numeric_amount is null", ProfileFundingEntity.class);
return query.getResultList();
}
/**
* Edits a profileFunding
*
* @param profileFunding
* The profileFunding to be edited
* @return the updated profileFunding
* */
@Override
@Transactional
public ProfileFundingEntity updateProfileFunding(ProfileFundingEntity profileFunding) {
ProfileFundingEntity toUpdate = this.find(profileFunding.getId());
mergeProfileFunding(toUpdate, profileFunding);
toUpdate = this.merge(toUpdate);
return toUpdate;
}
private void mergeProfileFunding(ProfileFundingEntity existing, ProfileFundingEntity updated) {
existing.setContributorsJson(updated.getContributorsJson());
existing.setCurrencyCode(updated.getCurrencyCode());
existing.setDescription(updated.getDescription());
existing.setEndDate(updated.getEndDate());
existing.setExternalIdentifiersJson(updated.getExternalIdentifiersJson());
existing.setNumericAmount(updated.getNumericAmount());
existing.setOrg(updated.getOrg());
existing.setOrganizationDefinedType(updated.getOrganizationDefinedType());
existing.setStartDate(updated.getStartDate());
existing.setTitle(updated.getTitle());
existing.setTranslatedTitle(updated.getTranslatedTitle());
existing.setTranslatedTitleLanguageCode(updated.getTranslatedTitleLanguageCode());
existing.setType(updated.getType());
existing.setUrl(updated.getUrl());
existing.setVisibility(updated.getVisibility());
existing.setLastModified(new Date());
}
@Override
@Transactional
public boolean updateToMaxDisplay(String orcid, Long id) {
Query query = entityManager.createNativeQuery("UPDATE profile_funding SET display_index = (select coalesce(MAX(display_index) + 1, 0) from profile_funding where orcid=:orcid and id != :id ), last_modified=now() WHERE id = :id");
query.setParameter("orcid", orcid);
query.setParameter("id", id);
return query.executeUpdate() > 0 ? true : false;
}
@Override
@SuppressWarnings("unchecked")
public List<BigInteger> findFundingNeedingExternalIdentifiersMigration(int chunkSize) {
Query query = entityManager.createNativeQuery("SELECT id FROM profile_funding WHERE id IN (SELECT profile_funding_id FROM funding_external_identifier) AND external_identifiers_json IS NULL LIMIT :chunkSize");
query.setParameter("chunkSize", chunkSize);
List<BigInteger> results = query.getResultList();
return results;
}
@Override
@Transactional
public void setFundingExternalIdentifiersInJson(BigInteger id, String extIdsJson) {
Query query = entityManager.createNativeQuery("UPDATE profile_funding SET external_identifiers_json=:extIdsJson WHERE id=:id");
query.setParameter("id", id);
query.setParameter("extIdsJson", extIdsJson);
query.executeUpdate();
}
/**
* Deletes all funding where the source matches the give app id
* @param clientSourceId the app id
* */
@Override
@Transactional
public void removeFundingByClientSourceId(String clientSourceId) {
Query query = entityManager.createNativeQuery("DELETE FROM profile_funding WHERE client_source_id=:clientSourceId");
query.setParameter("clientSourceId", clientSourceId);
query.executeUpdate();
}
@Override
public List<ProfileFundingEntity> getByUser(String userOrcid) {
TypedQuery<ProfileFundingEntity> query = entityManager.createQuery("from ProfileFundingEntity where profile.id=:userOrcid order by displayIndex desc, dateCreated asc", ProfileFundingEntity.class);
query.setParameter("userOrcid", userOrcid);
return query.getResultList();
}
/**
* Returns a list of external ids of fundings that still have old external identifiers
* @param limit
* The batch number to fetch
* @return a list of funding ids with old ext ids
* */
@Override
@SuppressWarnings("unchecked")
public List<BigInteger> getFundingWithOldExtIds(long limit) {
Query query = entityManager.createNativeQuery("SELECT distinct(id) FROM (SELECT id, json_array_elements(json_extract_path(external_identifiers_json, 'fundingExternalIdentifier')) AS j FROM profile_funding WHERE external_identifiers_json is not null limit :limit) AS a WHERE (j->'relationship') is null;");
query.setParameter("limit", limit);
return query.getResultList();
}
@Override
@Transactional
public boolean increaseDisplayIndexOnAllElements(String orcid) {
Query query = entityManager.createNativeQuery("update profile_funding set display_index=(display_index + 1), last_modified=now() where orcid=:orcid");
query.setParameter("orcid", orcid);
return query.executeUpdate() > 0;
}
}