/*
* (C) Copyright 2006-2017 Nuxeo (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.storage.sql;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.transaction.xa.XAResource;
import org.nuxeo.ecm.core.api.IterableQueryResult;
import org.nuxeo.ecm.core.api.Lock;
import org.nuxeo.ecm.core.api.PartialList;
import org.nuxeo.ecm.core.api.ScrollResult;
import org.nuxeo.ecm.core.query.QueryFilter;
/**
* A {@link Mapper} maps {@link Row}s to and from the database.
*/
public interface Mapper extends RowMapper, XAResource {
/**
* Executes the given query and returns the first batch of results, next batch must be requested within the
* {@code keepAliveSeconds} delay.
*
* @since 8.4
*/
ScrollResult scroll(String query, int batchSize, int keepAliveSeconds);
/**
* Get the next batch of result, the {@code scrollId} is part of the previous {@link ScrollResult} response.
*
* @since 8.4
*/
ScrollResult scroll(String scrollId);
/**
* Identifiers assigned by a server to identify a client mapper and its repository.
*/
final class Identification implements Serializable {
private static final long serialVersionUID = 1L;
public final String repositoryId;
public final String mapperId;
public Identification(String repositoryId, String mapperId) {
this.repositoryId = repositoryId;
this.mapperId = mapperId;
}
@Override
public String toString() {
return getClass().getSimpleName() + '(' + repositoryId + ',' + mapperId + ')';
}
}
/**
* Returns the repository id and mapper id assigned.
* <p>
* This is used in remote stateless mode to be able to identify to which mapper an incoming connection is targeted,
* and from which repository instance.
*
* @return the repository and mapper identification
*/
Identification getIdentification();
// used for reflection
String GET_IDENTIFICATION = "getIdentification";
void close();
// used for reflection
String CLOSE = "close";
// TODO
int getTableSize(String tableName);
/**
* Creates the necessary structures in the database.
*
* @param ddlMode the DDL execution mode
*/
void createDatabase(String ddlMode);
/*
* ========== Methods returning non-Rows ==========
*/
/*
* ----- Root -----
*/
/**
* Gets the root id for a given repository, if registered.
*
* @param repositoryId the repository id
* @return the root id, or null if not found
*/
Serializable getRootId(String repositoryId);
/**
* Records the newly generated root id for a given repository.
*
* @param repositoryId the repository id, usually 0
* @param id the root id
*/
void setRootId(Serializable repositoryId, Serializable id);
/*
* ----- Query -----
*/
/**
* Makes a NXQL query to the database.
*
* @param query the query
* @param queryType the query type
* @param queryFilter the query filter
* @param countTotal if {@code true}, count the total size without limit/offset
* @return the list of matching document ids
*/
PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, boolean countTotal);
/**
* Makes a NXQL query to the database.
*
* @param query the query
* @param queryType the query type
* @param queryFilter the query filter
* @param countUpTo if {@code -1}, count the total size without offset/limit.<br>
* If {@code 0}, don't count the total size.<br>
* If {@code n}, count the total number if there are less than n documents otherwise set the size to
* {@code -1}.
* @return the list of matching document ids
* @since 5.6
*/
PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, long countUpTo);
/**
* Makes a query to the database and returns an iterable (which must be closed when done).
*
* @param query the query
* @param queryType the query type
* @param queryFilter the query filter
* @param distinctDocuments if {@code true} then a maximum of one row per document will be returned
* @param params optional query-type-dependent parameters
* @return an iterable, which <b>must</b> be closed when done
*/
// queryFilter used for principals and permissions
IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter,
boolean distinctDocuments, Object... params);
/**
* Makes a query to the database.
*
* @param query the query
* @param queryType the query type
* @param queryFilter the query filter
* @param distinctDocuments if {@code true} then a maximum of one row per document will be returned
* @param countUpTo if {@code -1}, also count the total size without offset/limit.<br>
* If {@code 0}, don't count the total size.<br>
* If {@code n}, count the total number if there are less than n documents otherwise set the size to
* {@code -1}.
* @param params optional query-type-dependent parameters
* @return a projection
* @since 7.10-HF-25, 8.10-HF06, 9.2
*/
PartialList<Map<String,Serializable>> queryProjection(String query, String queryType, QueryFilter queryFilter, boolean distinctDocuments,
long countUpTo, Object... params);
/**
* Gets the ids for all the ancestors of the given row ids.
*
* @param ids the ids
* @return the set of ancestor ids
*/
Set<Serializable> getAncestorsIds(Collection<Serializable> ids);
/*
* ----- ACLs -----
*/
void updateReadAcls();
void rebuildReadAcls();
/*
* ----- Clustering -----
*/
int getClusterNodeIdType();
/**
* Informs the cluster that this node exists.
*/
void createClusterNode(Serializable nodeId);
/**
* Removes this node from the cluster.
*/
void removeClusterNode(Serializable nodeId);
/**
* Inserts the invalidation rows for the other cluster nodes.
*/
void insertClusterInvalidations(Serializable nodeId, Invalidations invalidations);
/**
* Gets the invalidations from other cluster nodes.
*/
Invalidations getClusterInvalidations(Serializable nodeId);
/*
* ----- Locking -----
*/
/**
* Gets the lock state of a document.
* <p>
* If the document does not exist, {@code null} is returned.
*
* @param id the document id
* @return the existing lock, or {@code null} when there is no lock
*/
Lock getLock(Serializable id);
/**
* Sets a lock on a document.
* <p>
* If the document is already locked, returns its existing lock status (there is no re-locking, {@link #removeLock}
* must be called first).
*
* @param id the document id
* @param lock the lock object to set
* @return {@code null} if locking succeeded, or the existing lock if locking failed, or a
*/
Lock setLock(Serializable id, Lock lock);
/**
* Removes a lock from a document.
* <p>
* The previous lock is returned.
* <p>
* If {@code owner} is {@code null} then the lock is unconditionally removed.
* <p>
* If {@code owner} is not {@code null}, it must match the existing lock owner for the lock to be removed. If it
* doesn't match, the returned lock will return {@code true} for {@link Lock#getFailed}.
*
* @param id the document id
* @param owner the owner to check, or {@code null} for no check
* @param force {@code true} to just do the remove and not return the previous lock
* @return the previous lock
*/
Lock removeLock(Serializable id, String owner, boolean force);
/**
* Marks the binaries in use by passing them to the binary manager(s)'s GC mark() method.
*/
void markReferencedBinaries();
/**
* Cleans up (hard-delete) any rows that have been soft-deleted in the database.
*
* @param max the maximum number of rows to delete at a time
* @param beforeTime the maximum deletion time of the rows to delete
* @return the number of rows deleted
*/
int cleanupDeletedRows(int max, Calendar beforeTime);
/**
* @since 5.9.3
*/
boolean isConnected();
/**
* @since 5.9.3
*/
void connect(boolean noSharing);
/**
* @since 5.9.3
*/
void disconnect();
}