001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (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 */
019
020package org.nuxeo.ecm.core.storage.sql;
021
022import java.io.Serializable;
023import java.util.Calendar;
024import java.util.Collection;
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, next batch must be requested
042     * within the {@code keepAliveSeconds} delay.
043     *
044     * @since 8.4
045     */
046    ScrollResult scroll(String query, int batchSize, int keepAliveSeconds);
047
048    /**
049     * Get the next batch of result, the {@code scrollId} is part of the previous {@link ScrollResult} response.
050     *
051     * @since 8.4
052     */
053    ScrollResult scroll(String scrollId);
054
055    /**
056     * Identifiers assigned by a server to identify a client mapper and its repository.
057     */
058    public static final class Identification implements Serializable {
059        private static final long serialVersionUID = 1L;
060
061        public final String repositoryId;
062
063        public final String mapperId;
064
065        public Identification(String repositoryId, String mapperId) {
066            this.repositoryId = repositoryId;
067            this.mapperId = mapperId;
068        }
069
070        @Override
071        public String toString() {
072            return getClass().getSimpleName() + '(' + repositoryId + ',' + mapperId + ')';
073        }
074    }
075
076    /**
077     * Returns the repository id and mapper id assigned.
078     * <p>
079     * This is used in remote stateless mode to be able to identify to which mapper an incoming connection is targeted,
080     * and from which repository instance.
081     *
082     * @return the repository and mapper identification
083     */
084    Identification getIdentification();
085
086    // used for reflection
087    String GET_IDENTIFICATION = "getIdentification";
088
089    void close();
090
091    // used for reflection
092    String CLOSE = "close";
093
094    // TODO
095    int getTableSize(String tableName);
096
097    /**
098     * Creates the necessary structures in the database.
099     *
100     * @param ddlMode the DDL execution mode
101     */
102    void createDatabase(String ddlMode);
103
104    /*
105     * ========== Methods returning non-Rows ==========
106     */
107
108    /*
109     * ----- Root -----
110     */
111
112    /**
113     * Gets the root id for a given repository, if registered.
114     *
115     * @param repositoryId the repository id
116     * @return the root id, or null if not found
117     */
118    Serializable getRootId(String repositoryId);
119
120    /**
121     * Records the newly generated root id for a given repository.
122     *
123     * @param repositoryId the repository id, usually 0
124     * @param id the root id
125     */
126    void setRootId(Serializable repositoryId, Serializable id);
127
128    /*
129     * ----- Query -----
130     */
131
132    /**
133     * Makes a NXQL query to the database.
134     *
135     * @param query the query
136     * @param query the query type
137     * @param queryFilter the query filter
138     * @param countTotal if {@code true}, count the total size without limit/offset
139     * @return the list of matching document ids
140     */
141    PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, boolean countTotal);
142
143    /**
144     * Makes a NXQL query to the database.
145     *
146     * @param query the query
147     * @param query the query type
148     * @param queryFilter the query filter
149     * @param countUpTo if {@code -1}, count the total size without offset/limit.<br>
150     *            If {@code 0}, don't count the total size.<br>
151     *            If {@code n}, count the total number if there are less than n documents otherwise set the size to
152     *            {@code -1}.
153     * @return the list of matching document ids
154     * @Since 5.6
155     */
156    PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, long countUpTo);
157
158    /**
159     * Makes a query to the database and returns an iterable (which must be closed when done).
160     *
161     * @param query the query
162     * @param queryType the query type
163     * @param queryFilter the query filter
164     * @param distinctDocuments if {@code true} then a maximum of one row per document will be returned
165     * @param params optional query-type-dependent parameters
166     * @return an iterable, which <b>must</b> be closed when done
167     */
168    // queryFilter used for principals and permissions
169    IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter,
170            boolean distinctDocuments, Object... params);
171
172    /**
173     * Gets the ids for all the ancestors of the given row ids.
174     *
175     * @param ids the ids
176     * @return the set of ancestor ids
177     */
178    Set<Serializable> getAncestorsIds(Collection<Serializable> ids);
179
180    /*
181     * ----- ACLs -----
182     */
183
184    void updateReadAcls();
185
186    void rebuildReadAcls();
187
188    /*
189     * ----- Clustering -----
190     */
191
192    int getClusterNodeIdType();
193
194    /**
195     * Informs the cluster that this node exists.
196     */
197    void createClusterNode(Serializable nodeId);
198
199    /**
200     * Removes this node from the cluster.
201     */
202    void removeClusterNode(Serializable nodeId);
203
204    /**
205     * Inserts the invalidation rows for the other cluster nodes.
206     */
207    void insertClusterInvalidations(Serializable nodeId, Invalidations invalidations);
208
209    /**
210     * Gets the invalidations from other cluster nodes.
211     */
212    Invalidations getClusterInvalidations(Serializable nodeId);
213
214    /*
215     * ----- Locking -----
216     */
217
218    /**
219     * Gets the lock state of a document.
220     * <p>
221     * If the document does not exist, {@code null} is returned.
222     *
223     * @param id the document id
224     * @return the existing lock, or {@code null} when there is no lock
225     */
226    Lock getLock(Serializable id);
227
228    /**
229     * Sets a lock on a document.
230     * <p>
231     * If the document is already locked, returns its existing lock status (there is no re-locking, {@link #removeLock}
232     * must be called first).
233     *
234     * @param id the document id
235     * @param lock the lock object to set
236     * @return {@code null} if locking succeeded, or the existing lock if locking failed, or a
237     */
238    Lock setLock(Serializable id, Lock lock);
239
240    /**
241     * Removes a lock from a document.
242     * <p>
243     * The previous lock is returned.
244     * <p>
245     * If {@code owner} is {@code null} then the lock is unconditionally removed.
246     * <p>
247     * If {@code owner} is not {@code null}, it must match the existing lock owner for the lock to be removed. If it
248     * doesn't match, the returned lock will return {@code true} for {@link Lock#getFailed}.
249     *
250     * @param id the document id
251     * @param the owner to check, or {@code null} for no check
252     * @param force {@code true} to just do the remove and not return the previous lock
253     * @return the previous lock
254     */
255    Lock removeLock(Serializable id, String owner, boolean force);
256
257    /**
258     * Marks the binaries in use by passing them to the binary manager(s)'s GC mark() method.
259     */
260    void markReferencedBinaries();
261
262    /**
263     * Cleans up (hard-delete) any rows that have been soft-deleted in the database.
264     *
265     * @param max the maximum number of rows to delete at a time
266     * @param beforeTime the maximum deletion time of the rows to delete
267     * @return the number of rows deleted
268     */
269    int cleanupDeletedRows(int max, Calendar beforeTime);
270
271    /**
272     * @since 5.9.3
273     */
274    boolean isConnected();
275
276    /**
277     * @since 5.9.3
278     */
279    void connect();
280
281    /**
282     * @since 5.9.3
283     */
284    void disconnect();
285
286}