001/*
002 * (C) Copyright 2014-2016 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 */
019package org.nuxeo.ecm.core.storage.dbs;
020
021import java.io.Serializable;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025
026import org.nuxeo.ecm.core.api.PartialList;
027import org.nuxeo.ecm.core.api.ScrollResult;
028import org.nuxeo.ecm.core.blob.BlobManager;
029import org.nuxeo.ecm.core.model.LockManager;
030import org.nuxeo.ecm.core.model.Repository;
031import org.nuxeo.ecm.core.query.sql.model.OrderByClause;
032import org.nuxeo.ecm.core.storage.FulltextConfiguration;
033import org.nuxeo.ecm.core.storage.State;
034import org.nuxeo.ecm.core.storage.State.StateDiff;
035import org.nuxeo.ecm.core.storage.dbs.DBSTransactionState.ChangeTokenUpdater;
036
037/**
038 * Interface for a {@link Repository} for Document-Based Storage.
039 *
040 * @since 5.9.4
041 */
042public interface DBSRepository extends Repository, LockManager {
043
044    /**
045     * Gets the blob manager.
046     *
047     * @return the blob manager.
048     */
049    BlobManager getBlobManager();
050
051    /**
052     * Gets the fulltext configuration.
053     *
054     * @return the fulltext configuration
055     * @since 7.10-HF04, 8.1
056     */
057    FulltextConfiguration getFulltextConfiguration();
058
059    /**
060     * Checks if fulltext indexing is disabled.
061     *
062     * @return {@code true} if fulltext indexing is disabled, {@code false} if it is enabled
063     * @since 7.1, 6.0-HF02
064     */
065    boolean isFulltextDisabled();
066
067    /**
068     * Checks if database-managed document change tokens are enabled.
069     *
070     * @return {@code true} if the database maintains document change tokens
071     * @since 9.1
072     */
073    boolean isChangeTokenEnabled();
074
075    /**
076     * Gets the root id.
077     *
078     * @return the root id.
079     */
080    String getRootId();
081
082    /**
083     * Generates a new id for a document.
084     *
085     * @return the new id
086     */
087    String generateNewId();
088
089    /**
090     * Reads the state of a document.
091     *
092     * @param id the document id
093     * @return the document state, or {@code null} if not found
094     */
095    State readState(String id);
096
097    /**
098     * Reads the states of several documents.
099     * <p>
100     * The returned states may be in a different order than the ids.
101     *
102     * @param ids the document ids
103     * @return the document states, an element by be {@code null} if not found
104     */
105    List<State> readStates(List<String> ids);
106
107    /**
108     * Creates a document.
109     *
110     * @param state the document state
111     */
112    void createState(State state);
113
114    /**
115     * Creates documents.
116     *
117     * @param states the document states
118     */
119    default void createStates(List<State> states) {
120        states.forEach(this::createState);
121    }
122
123    /**
124     * Updates a document.
125     *
126     * @param id the document id
127     * @param diff the diff to apply
128     * @param changeTokenUpdater how to get and update the change token (may be {@code null})
129     */
130    void updateState(String id, StateDiff diff, ChangeTokenUpdater changeTokenUpdater);
131
132    /**
133     * Deletes a set of document.
134     *
135     * @param ids the document ids
136     */
137    void deleteStates(Set<String> ids);
138
139    /**
140     * Reads the state of a child document.
141     *
142     * @param parentId the parent document id
143     * @param name the name of the child
144     * @param ignored a set of document ids that should not be considered
145     * @return the state of the child document, or {@code null} if not found
146     */
147    State readChildState(String parentId, String name, Set<String> ignored);
148
149    /**
150     * Checks if a document has a child with the given name
151     *
152     * @param parentId the parent document id
153     * @param name the name of the child
154     * @param ignored a set of document ids that should not be considered
155     * @return {@code true} if the child exists, {@code false} if not
156     */
157    boolean hasChild(String parentId, String name, Set<String> ignored);
158
159    /**
160     * Queries the repository for documents having key = value.
161     *
162     * @param key the key
163     * @param value the value
164     * @param ignored a set of document ids that should not be considered
165     * @return the document states matching the query
166     */
167    List<State> queryKeyValue(String key, Object value, Set<String> ignored);
168
169    /**
170     * Queries the repository for documents having key1 = value1 and key2 = value2.
171     *
172     * @param key1 the first key
173     * @param value1 the first value
174     * @param key2 the second key
175     * @param value2 the second value
176     * @param ignored a set of document ids that should not be considered
177     * @return the document states matching the query
178     */
179    List<State> queryKeyValue(String key1, Object value1, String key2, Object value2, Set<String> ignored);
180
181    /**
182     * Queries the repository for document ids having value in key (an array).
183     *
184     * @param key the key
185     * @param value the value
186     * @param ids the set which receives the documents ids
187     * @param proxyTargets returns a map of proxy to target among the documents found
188     * @param targetProxies returns a map of target to proxies among the document found
189     */
190    void queryKeyValueArray(String key, Object value, Set<String> ids, Map<String, String> proxyTargets,
191            Map<String, Object[]> targetProxies);
192
193    /**
194     * Queries the repository to check if there are documents having key = value.
195     *
196     * @param key the key
197     * @param value the value
198     * @param ignored a set of document ids that should not be considered
199     * @return {@code true} if the query matches at least one document, {@code false} if the query matches nothing
200     */
201    boolean queryKeyValuePresence(String key, String value, Set<String> ignored);
202
203    /**
204     * Queries the repository for documents matching a NXQL query, and returns a projection of the documents.
205     *
206     * @param evaluator the map-based evaluator for the query
207     * @param orderByClause an ORDER BY clause
208     * @param distinctDocuments {@code true} if the projection should return a maximum of one row per document
209     * @param limit the limit on the number of documents to return
210     * @param offset the offset in the list of documents to return
211     * @param countUpTo if {@code -1}, count the total size without offset/limit.<br>
212     *            If {@code 0}, don't count the total size, set it to {@code -1} .<br>
213     *            If {@code n}, count the total number if there are less than n documents otherwise set the total size
214     *            to {@code -2}.
215     * @return a partial list of maps containing the NXQL projections requested, and the total size according to
216     *         countUpTo
217     */
218    PartialList<Map<String, Serializable>> queryAndFetch(DBSExpressionEvaluator evaluator, OrderByClause orderByClause,
219            boolean distinctDocuments, int limit, int offset, int countUpTo);
220
221    /**
222     * Gets the lock manager for this repository.
223     *
224     * @return the lock manager
225     * @since 7.4
226     */
227    LockManager getLockManager();
228
229    /**
230     * Executes the given query and returns the first batch of results, next batch must be requested
231     * within the {@code keepAliveSeconds} delay.
232     *
233     * @since 8.4
234     */
235    ScrollResult scroll(DBSExpressionEvaluator evaluator, int batchSize, int keepAliveSeconds);
236
237    /**
238     * Get the next batch of result, the {@code scrollId} is part of the previous {@link ScrollResult} response.
239     *
240     * @since 8.4
241     */
242    ScrollResult scroll(String scrollId);
243
244    /**
245     * Called when created a transaction.
246     *
247     * @since 8.10
248     */
249    default void begin() {
250
251    }
252
253    /**
254     * Saves and flushes to database.
255     *
256     * @since 8.10
257     */
258    default void commit() {
259
260    }
261
262    /**
263     * Rolls back the save state by applying the undo log.
264     *
265     * @since 8.10
266     */
267    default void rollback() {
268
269    }
270
271}