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