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