/* * Copyright Siemens AG, 2014-2016. Part of the SW360 Portal Project. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.sw360.datahandler.couchdb; import org.ektorp.*; import org.ektorp.support.CouchDbRepositorySupport; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Access the database in a CRUD manner, for a generic class * * @author cedric.bodet@tngtech.com * @author stefan.jaeger@evosoft.com */ public class DatabaseRepository<T> extends CouchDbRepositorySupport<T> { private static final char HIGH_VALUE_UNICODE_CHARACTER = '\uFFF0'; private final Class<T> type; private final DatabaseConnector connector; public static Set<String> getIds(ViewResult rows) { HashSet<String> ids = new HashSet<>(); for (ViewResult.Row row : rows.getRows()) { ids.add(row.getId()); } return ids; } public static Set<String> getStringValue(ViewResult rows) { HashSet<String> ids = new HashSet<>(); for (ViewResult.Row row : rows.getRows()) { ids.add(row.getValue()); } return ids; } public DatabaseRepository(Class<T> type, DatabaseConnector databaseConnector) { super(type, databaseConnector); this.connector = databaseConnector; this.type = type; } public Set<String> queryForIds(ViewQuery query) { ViewResult rows = connector.queryView(query.includeDocs(false)); return getIds(rows); } public Set<String> queryForIdsAsValue(ViewQuery query) { ViewResult rows = connector.queryView(query.includeDocs(false)); return getStringValue(rows); } public Set<String> queryForIds(String queryName, String key) { ViewQuery query = createQuery(queryName).key(key); return queryForIds(query); } public Set<String> queryForIdsAsValue(String queryName, String key) { ViewQuery query = createQuery(queryName).key(key); return queryForIdsAsValue(query); } public Set<String> queryForIdsAsComplexValue(String queryName, String ... keys) { ViewQuery query = createQuery(queryName).key(ComplexKey.of(keys)); return queryForIds(query); } public Set<String> queryForIdsAsValue(String queryName, Set<String> keys) { ViewQuery query = createQuery(queryName).keys(keys); return queryForIdsAsValue(query); } public Set<String> queryForIds(String queryName, String startKey, String endKey) { ViewQuery query = createQuery(queryName).startKey(startKey).endKey(endKey); return queryForIds(query); } public Set<String> queryForIds(String queryName, String startKey, String endKey, Integer skip, Integer limit) { ViewQuery query = createQuery(queryName).startKey(startKey).endKey(endKey).skip(skip).limit(limit); return queryForIds(query); } public Set<String> getAllIdsByView(String queryName, boolean descending) { ViewQuery query = createQuery(queryName).descending(descending); return queryForIds(query); } public Set<String> getAllIds() { ViewQuery query = createQuery("all"); return queryForIds(query); } public List<T> queryByIds(String viewName, Collection<String> ids) { ViewQuery query = createQuery(viewName).includeDocs(true).keys(ids); return queryView(query); } public List<T> queryByPrefix(String viewName, String key) { return queryView(viewName, key, key + HIGH_VALUE_UNICODE_CHARACTER); } public Set<String> queryForIdsByPrefix(String viewName, String prefix) { return queryForIds(viewName, prefix, prefix + HIGH_VALUE_UNICODE_CHARACTER); } public List<T> queryView(String viewName, String startKey, String endKey) { ViewQuery query = createQuery(viewName).startKey(startKey).endKey(endKey).includeDocs(true); return queryView(query); } public List<T> queryView(ViewQuery query) { return db.queryView(query, type); } @Override public T get(String id) { try { return super.get(id); } catch (DocumentNotFoundException e) { log.error("Document ID " + id + " not found!", e); return null; } catch (DbAccessException e) { log.error("Document ID " + id + " could not be successfully converted.", e); return null; } } @Override public List<T> getAll() { try { return super.getAll(); } catch (DocumentNotFoundException e) { log.error("Nothing found!", e); return null; } catch (DbAccessException e) { log.error("Documents could not be successfully converted.", e); return null; } catch (Exception e) { log.error("Problem in getAll", e); return null; } } public boolean remove(String id) { return connector.deleteById(id); } public List<T> get(Collection<String> ids) { return connector.get(type, ids); } /** * Creates, updates all objects in the supplied collection. * <p/> * If the object has no revision set, it will be created, otherwise it will be updated. * <p/> * Some documents may successfully be saved and some may not. The response will tell the application which documents * were saved or not. In the case of a power failure, when the database restarts some may have been saved and some * not. * * @param list , all objects will have their id and revision set. * @return The list will only contain entries for documents that has any kind of error code returned from CouchDB. * i.e. the list will be empty if everything was completed successfully. */ public List<DocumentOperationResult> executeBulk(Collection<?> list) { try { return connector.executeBulk(list); } catch (Exception e) { log.error("Problem in executeBulk with " + list, e); return null; } } /** * Deletes all objects in the supplied collection. * * @param deletionCandidates , the objects that will be deleted * @return The list will only contain entries for documents that has any kind of error code returned from CouchDB. * i.e. the list will be empty if everything was completed successfully. */ protected List<DocumentOperationResult> deleteBulk(Collection<?> deletionCandidates) { return connector.deleteBulk(deletionCandidates); } public List<DocumentOperationResult> deleteIds(Collection<String> ids) { final List<T> deletionCandidates = get(ids); return deleteBulk(deletionCandidates); } }