001/*
002 * (C) Copyright 2006-2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.storage.sql;
020
021import java.io.Serializable;
022import java.util.Calendar;
023import java.util.Collection;
024import java.util.Map;
025import java.util.Set;
026
027import javax.transaction.xa.XAResource;
028
029import org.nuxeo.ecm.core.api.IterableQueryResult;
030import org.nuxeo.ecm.core.api.Lock;
031import org.nuxeo.ecm.core.api.PartialList;
032import org.nuxeo.ecm.core.api.ScrollResult;
033import org.nuxeo.ecm.core.query.QueryFilter;
034
035/**
036 * A {@link Mapper} maps {@link Row}s to and from the database.
037 */
038public interface Mapper extends RowMapper, XAResource {
039
040    /**
041     * Executes the given query and returns the first batch of results containing id of documents, next batch must be
042     * requested within the {@code keepAliveSeconds} delay.
043     *
044     * @since 8.4
045     */
046    ScrollResult<String> scroll(String query, int batchSize, int keepAliveSeconds);
047
048    /**
049     * Get the next batch of results containing id of documents, the {@code scrollId} is part of the previous
050     * {@link ScrollResult} response.
051     *
052     * @since 8.4
053     */
054    ScrollResult<String> scroll(String scrollId);
055
056    /**
057     * Identifiers assigned by a server to identify a client mapper and its repository.
058     */
059    final class Identification implements Serializable {
060
061        private static final long serialVersionUID = 1L;
062
063        public final String repositoryId;
064
065        public final String mapperId;
066
067        public Identification(String repositoryId, String mapperId) {
068            this.repositoryId = repositoryId;
069            this.mapperId = mapperId;
070        }
071
072        @Override
073        public String toString() {
074            return getClass().getSimpleName() + '(' + repositoryId + ',' + mapperId + ')';
075        }
076
077    }
078
079    /**
080     * Returns the repository id and mapper id assigned.
081     * <p>
082     * This is used in remote stateless mode to be able to identify to which mapper an incoming connection is targeted,
083     * and from which repository instance.
084     *
085     * @return the repository and mapper identification
086     */
087    Identification getIdentification();
088
089    // used for reflection
090    String GET_IDENTIFICATION = "getIdentification";
091
092    void close();
093
094    // used for reflection
095    String CLOSE = "close";
096
097    // TODO
098    int getTableSize(String tableName);
099
100    /**
101     * Creates the necessary structures in the database.
102     *
103     * @param ddlMode the DDL execution mode
104     */
105    void createDatabase(String ddlMode);
106
107    /*
108     * ========== Methods returning non-Rows ==========
109     */
110
111    /*
112     * ----- Root -----
113     */
114
115    /**
116     * Gets the root id for a given repository, if registered.
117     *
118     * @param repositoryId the repository id
119     * @return the root id, or null if not found
120     */
121    Serializable getRootId(String repositoryId);
122
123    /**
124     * Records the newly generated root id for a given repository.
125     *
126     * @param repositoryId the repository id, usually 0
127     * @param id the root id
128     */
129    void setRootId(Serializable repositoryId, Serializable id);
130
131    /*
132     * ----- Query -----
133     */
134
135    /**
136     * Makes a NXQL query to the database.
137     *
138     * @param query the query
139     * @param queryType the query type
140     * @param queryFilter the query filter
141     * @param countTotal if {@code true}, count the total size without limit/offset
142     * @return the list of matching document ids
143     */
144    PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, boolean countTotal);
145
146    /**
147     * Makes a NXQL query to the database.
148     *
149     * @param query the query
150     * @param queryType the query type
151     * @param queryFilter the query filter
152     * @param countUpTo if {@code -1}, count the total size without offset/limit.<br>
153     *            If {@code 0}, don't count the total size.<br>
154     *            If {@code n}, count the total number if there are less than n documents otherwise set the size to
155     *            {@code -1}.
156     * @return the list of matching document ids
157     * @since 5.6
158     */
159    PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, long countUpTo);
160
161    /**
162     * Makes a query to the database and returns an iterable (which must be closed when done).
163     *
164     * @param query the query
165     * @param queryType the query type
166     * @param queryFilter the query filter
167     * @param distinctDocuments if {@code true} then a maximum of one row per document will be returned
168     * @param params optional query-type-dependent parameters
169     * @return an iterable, which <b>must</b> be closed when done
170     */
171    // queryFilter used for principals and permissions
172    IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter,
173            boolean distinctDocuments, Object... params);
174
175    /**
176     * Makes a query to the database.
177     *
178     * @param query the query
179     * @param queryType the query type
180     * @param queryFilter the query filter
181     * @param distinctDocuments if {@code true} then a maximum of one row per document will be returned
182     * @param countUpTo if {@code -1}, also count the total size without offset/limit.<br>
183     *            If {@code 0}, don't count the total size.<br>
184     *            If {@code n}, count the total number if there are less than n documents otherwise set the size to
185     *            {@code -1}.
186     * @param params optional query-type-dependent parameters
187     * @return a projection
188     * @since 7.10-HF-25, 8.10-HF06, 9.2
189     */
190    PartialList<Map<String,Serializable>> queryProjection(String query, String queryType, QueryFilter queryFilter, boolean distinctDocuments,
191            long countUpTo, Object... params);
192
193    /**
194     * Gets the ids for all the ancestors of the given row ids.
195     *
196     * @param ids the ids
197     * @return the set of ancestor ids
198     */
199    Set<Serializable> getAncestorsIds(Collection<Serializable> ids);
200
201    /*
202     * ----- ACLs -----
203     */
204
205    void updateReadAcls();
206
207    void rebuildReadAcls();
208
209    /*
210     * ----- Clustering -----
211     */
212
213    int getClusterNodeIdType();
214
215    /**
216     * Informs the cluster that this node exists.
217     */
218    void createClusterNode(Serializable nodeId);
219
220    /**
221     * Removes this node from the cluster.
222     */
223    void removeClusterNode(Serializable nodeId);
224
225    /**
226     * Inserts the invalidation rows for the other cluster nodes.
227     */
228    void insertClusterInvalidations(Serializable nodeId, Invalidations invalidations);
229
230    /**
231     * Gets the invalidations from other cluster nodes.
232     */
233    Invalidations getClusterInvalidations(Serializable nodeId);
234
235    /*
236     * ----- Locking -----
237     */
238
239    /**
240     * Gets the lock state of a document.
241     * <p>
242     * If the document does not exist, {@code null} is returned.
243     *
244     * @param id the document id
245     * @return the existing lock, or {@code null} when there is no lock
246     */
247    Lock getLock(Serializable id);
248
249    /**
250     * Sets a lock on a document.
251     * <p>
252     * If the document is already locked, returns its existing lock status (there is no re-locking, {@link #removeLock}
253     * must be called first).
254     *
255     * @param id the document id
256     * @param lock the lock object to set
257     * @return {@code null} if locking succeeded, or the existing lock if locking failed, or a
258     */
259    Lock setLock(Serializable id, Lock lock);
260
261    /**
262     * Removes a lock from a document.
263     * <p>
264     * The previous lock is returned.
265     * <p>
266     * If {@code owner} is {@code null} then the lock is unconditionally removed.
267     * <p>
268     * If {@code owner} is not {@code null}, it must match the existing lock owner for the lock to be removed. If it
269     * doesn't match, the returned lock will return {@code true} for {@link Lock#getFailed}.
270     *
271     * @param id the document id
272     * @param owner the owner to check, or {@code null} for no check
273     * @param force {@code true} to just do the remove and not return the previous lock
274     * @return the previous lock
275     */
276    Lock removeLock(Serializable id, String owner, boolean force);
277
278    /**
279     * Marks the binaries in use by passing them to the binary manager(s)'s GC mark() method.
280     */
281    void markReferencedBinaries();
282
283    /**
284     * Cleans up (hard-delete) any rows that have been soft-deleted in the database.
285     *
286     * @param max the maximum number of rows to delete at a time
287     * @param beforeTime the maximum deletion time of the rows to delete
288     * @return the number of rows deleted
289     */
290    int cleanupDeletedRows(int max, Calendar beforeTime);
291
292    /**
293     * @since 5.9.3
294     */
295    boolean isConnected();
296
297    /**
298     * @since 5.9.3
299     */
300    void connect(boolean noSharing);
301
302    /**
303     * @since 5.9.3
304     */
305    void disconnect();
306
307}