/* * (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.List; import java.util.Map; import javax.resource.cci.Connection; import org.nuxeo.ecm.core.api.IterableQueryResult; import org.nuxeo.ecm.core.api.PartialList; import org.nuxeo.ecm.core.api.ScrollResult; import org.nuxeo.ecm.core.model.LockManager; import org.nuxeo.ecm.core.query.QueryFilter; /** * The session is the main high level access point to data from the underlying database. * * @author Florent Guillaume */ public interface Session extends Connection { /** * Gets the low-level Mapper for this session. * * @return the mapper */ Mapper getMapper(); /** * Checks if the session is live (not closed). * * @return {@code true} if the session is live */ boolean isLive(); /** * Gets the session repository name. * * @return the repository name */ String getRepositoryName(); /** * Gets the {@link Model} associated to this session. * * @return the model */ Model getModel(); /** * Saves the modifications to persistent storage. * <p> * Modifications will be actually written only upon transaction commit. */ void save(); /** * Gets the root node of the repository. * * @return the root node */ Node getRootNode(); /** * Gets a node given its id. * * @param id the id * @return the node, or {@code null} if not found */ Node getNodeById(Serializable id); /** * Gets several nodes given their ids. * * @param ids the ids * @return the nodes, in the same order as the ids, with elements being {@code null} if not found */ List<Node> getNodesByIds(List<Serializable> ids); /** * Gets a node given its absolute path, or given an existing node and a relative path. * * @param path the path * @param node the node (ignored for absolute paths) * @return the node, or {@code null} if not found */ Node getNodeByPath(String path, Node node); /** * Adds a mixin to a node. * <p> * Does nothing if the mixin was already present on the node. * * @param node the node * @param mixin the mixin name * @return {@code true} if the mixin was added, or {@code false} if it is already present * @since 5.8 */ boolean addMixinType(Node node, String mixin); /** * Removes a mixin from a node. * <p> * It's not possible to remove a mixin coming from the primary type. * * @param node the node * @param mixin the mixin * @return {@code true} if the mixin was removed, or {@code false} if it isn't present or is present on the type or * does not exist * @since 5.8 */ boolean removeMixinType(Node node, String mixin); /** * 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); /** * Interface for a class that knows how to resolve a node path into a node id. */ interface PathResolver { /** * Returns the node id for a given path. * * @param path the node path * @return the node id, or {@code null} */ Serializable getIdForPath(String path); } /** * Gets the parent of a node. * <p> * The root has a {@code null} parent. * * @param node the node * @return the parent node, or {@code null} for the root's parent */ Node getParentNode(Node node); /** * Gets the absolute path of a node. * * @param node the node * @return the path */ String getPath(Node node); /** * Checks if a child node with the given name exists. * <p> * There are two kinds of children, the regular children documents and the complex properties. The {@code boolean} * {@value #complexProp} allows a choice between those. * * @param parent the parent node * @param name the child name * @param complexProp whether to check complex properties or regular children * @return {@code true} if a child node with that name exists */ boolean hasChildNode(Node parent, String name, boolean complexProp); /** * Gets a child node given its parent and name. * * @param parent the parent node * @param name the child name * @param complexProp whether to check complex properties or regular children * @return the child node, or {@code null} is not found */ Node getChildNode(Node parent, String name, boolean complexProp); /** * Checks it a node has children. * * @param parent the parent node * @param complexProp whether to check complex properties or regular children * @return {@code true} if the parent has children */ boolean hasChildren(Node parent, boolean complexProp); /** * Gets the children of a node. * * @param parent the parent node * @param name the children name to get (for lists of complex properties), or {@code null} for all * @param complexProp whether to check complex properties or regular children * @return the collection of children */ List<Node> getChildren(Node parent, String name, boolean complexProp); /** * Creates a new child node. * * @param parent the parent to which the child is added * @param name the child name * @param pos the child position, or {@code null} * @param typeName the child type * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false}) * @return the new node */ Node addChildNode(Node parent, String name, Long pos, String typeName, boolean complexProp); /** * Creates a new child node with given id (used for import). * * @param id the id * @param parent the parent to which the child is added * @param name the child name * @param pos the child position, or {@code null} * @param typeName the child type * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false}) * @return the new node */ Node addChildNode(Serializable id, Node parent, String name, Long pos, String typeName, boolean complexProp); /** * Creates a proxy for a version node. * * @param targetId the target id * @param versionSeriesId the version series id * @param parent the parent to which the proxy is added * @param name the proxy name * @param pos the proxy position * @return the new proxy node */ Node addProxy(Serializable targetId, Serializable versionSeriesId, Node parent, String name, Long pos); /** * Sets a proxies' target. * * @param proxy the proxy * @param targetId the new target id * @since 5.5 */ void setProxyTarget(Node proxy, Serializable targetId); /** * Removes a node from the storage. * <p> * This is much more complex that removing a property node ( {@link #removePropertyNode}). * * @param node the node to remove * @see {@link #removePropertyNode} */ void removeNode(Node node); /** * Removes a property node from the storage. * <p> * This is much less complex that removing a generic document node ( {@link #removeNode}). * * @param node the property node to remove * @see {@link #removeNode} */ void removePropertyNode(Node node); /** * Order the given source child node before the destination child node. The source node will be placed before the * destination one. If destination is {@code null}, the source node will be appended at the end of the children * list. * * @param parent the parent node * @param source the child node to move * @param dest the child node before which to place the source node, or {@code null} to move at the end */ void orderBefore(Node parent, Node source, Node dest); /** * Moves a node to a new location with a new name. * <p> * A {@link #save} is automatically done first. * * @param source the node to move * @param parent the new parent to which the node is moved * @param name the new node name * @return the moved node */ Node move(Node source, Node parent, String name); /** * Copies a node to a new location with a new name. * <p> * A {@link #save} is automatically done first. * * @param source the node to copy * @param parent the new parent to which the node is copied * @param name the new node name * @return the copied node */ Node copy(Node source, Node parent, String name); /** * Checks in a checked-out node: creates a new version with a copy of its information. * <p> * A {@link #save} is automatically done first. * * @param node the node to check in * @param label the label for the version * @param checkinComment the description for the version * @return the created version */ Node checkIn(Node node, String label, String checkinComment); /** * Checks out a checked-in node. * * @param node the node to check out */ void checkOut(Node node); /** * Restores a node to a given version. * <p> * The restored node is checked in. * * @param node the node to restore * @param version the version to restore from */ void restore(Node node, Node version); /** * Gets a version given its version series id and label. * * @param versionSeriesId the version series id * @param label the label * @return the version node, or {@code null} if not found */ Node getVersionByLabel(Serializable versionSeriesId, String label); /** * Gets all the versions for a given version series id. * <p> * A {@link #save} is automatically done first. * * @param versionSeriesId the version series id * @return the list of versions */ List<Node> getVersions(Serializable versionSeriesId); /** * Gets the last version for a given version series id. * <p> * A {@link #save} is automatically done first. * * @param versionSeriesId the version series id * @return the last version, or {@code null} if no versions exist */ Node getLastVersion(Serializable versionSeriesId); /** * Finds the proxies for a document. If the parent is not null, the search will be limited to its direct children. * <p> * If the document is a version, then only proxies to that version will be looked up. * <p> * Otherwise all proxies to the same version series than the document are retrieved. * <p> * A {@link #save} is automatically done first. * * @param document the document * @param parent the parent, or {@code null} * @return the list of proxies */ List<Node> getProxies(Node document, Node parent); /** * Makes a NXQL query to the database. * * @param query the query * @param queryFilter the query filter * @param countTotal if {@code true}, also count the total size without offset/limit * @return the resulting list with total size included */ PartialList<Serializable> query(String query, QueryFilter queryFilter, boolean countTotal); /** * Makes a query to the database. * * @param query the query * @param queryType the query type * @param queryFilter the query filter * @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}. * @return the resulting list with total size included * @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 params optional query-type-dependent parameters * @return an iterable, which <b>must</b> be closed when done */ IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter, Object... params); /** * 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 * @since 7.10-HF04, 8.2 */ 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 lock manager for this session. * * @return the lock manager * @since 7.4 */ LockManager getLockManager(); /** * Read ACLs are optimized ACLs for the read permission, they need to be updated after document creation or ACL * change. * <p> * This method flag the current session, the read ACLs update will be done automatically at save time. */ void requireReadAclsUpdate(); /** * Update only the read ACLs that have changed. */ void updateReadAcls(); /** * Rebuild the read ACLs for the whole repository. */ void rebuildReadAcls(); /** * Gets the fulltext extracted from the binary fields. * * @since 5.9.3 */ Map<String, String> getBinaryFulltext(Serializable id); /** * Checks if change token management is enabled. * * @since 9.1 */ boolean isChangeTokenEnabled(); }