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