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