001/* 002 * (C) Copyright 2006-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.sql; 020 021import java.io.Serializable; 022import java.util.List; 023import java.util.Map; 024 025import javax.resource.cci.Connection; 026 027import org.nuxeo.ecm.core.api.IterableQueryResult; 028import org.nuxeo.ecm.core.api.PartialList; 029import org.nuxeo.ecm.core.api.ScrollResult; 030import org.nuxeo.ecm.core.model.LockManager; 031import org.nuxeo.ecm.core.query.QueryFilter; 032 033/** 034 * The session is the main high level access point to data from the underlying database. 035 * 036 * @author Florent Guillaume 037 */ 038public interface Session extends Connection { 039 040 /** 041 * Gets the low-level Mapper for this session. 042 * 043 * @return the mapper 044 */ 045 Mapper getMapper(); 046 047 /** 048 * Checks if the session is live (not closed). 049 * 050 * @return {@code true} if the session is live 051 */ 052 boolean isLive(); 053 054 /** 055 * Gets the session repository name. 056 * 057 * @return the repository name 058 */ 059 String getRepositoryName(); 060 061 /** 062 * Gets the {@link Model} associated to this session. 063 * 064 * @return the model 065 */ 066 Model getModel(); 067 068 /** 069 * Saves the modifications to persistent storage. 070 * <p> 071 * Modifications will be actually written only upon transaction commit. 072 */ 073 void save(); 074 075 /** 076 * Gets the root node of the repository. 077 * 078 * @return the root node 079 */ 080 Node getRootNode(); 081 082 /** 083 * Gets a node given its id. 084 * 085 * @param id the id 086 * @return the node, or {@code null} if not found 087 */ 088 Node getNodeById(Serializable id); 089 090 /** 091 * Gets several nodes given their ids. 092 * 093 * @param ids the ids 094 * @return the nodes, in the same order as the ids, with elements being {@code null} if not found 095 */ 096 List<Node> getNodesByIds(List<Serializable> ids); 097 098 /** 099 * Gets a node given its absolute path, or given an existing node and a relative path. 100 * 101 * @param path the path 102 * @param node the node (ignored for absolute paths) 103 * @return the node, or {@code null} if not found 104 */ 105 Node getNodeByPath(String path, Node node); 106 107 /** 108 * Adds a mixin to a node. 109 * <p> 110 * Does nothing if the mixin was already present on the node. 111 * 112 * @param node the node 113 * @param mixin the mixin name 114 * @return {@code true} if the mixin was added, or {@code false} if it is already present 115 * @since 5.8 116 */ 117 boolean addMixinType(Node node, String mixin); 118 119 /** 120 * Removes a mixin from a node. 121 * <p> 122 * It's not possible to remove a mixin coming from the primary type. 123 * 124 * @param node the node 125 * @param mixin the mixin 126 * @return {@code true} if the mixin was removed, or {@code false} if it isn't present or is present on the type or 127 * does not exist 128 * @since 5.8 129 */ 130 boolean removeMixinType(Node node, String mixin); 131 132 /** 133 * Executes the given query and returns the first batch of results containing id of documents, next batch must be 134 * requested within the {@code keepAliveSeconds} delay. 135 * 136 * @since 8.4 137 */ 138 ScrollResult<String> scroll(String query, int batchSize, int keepAliveSeconds); 139 140 /** 141 * Get the next batch of results containing id of documents, the {@code scrollId} is part of the previous 142 * {@link ScrollResult} response. 143 * 144 * @since 8.4 145 */ 146 ScrollResult<String> scroll(String scrollId); 147 148 /** 149 * Interface for a class that knows how to resolve a node path into a node id. 150 */ 151 interface PathResolver { 152 /** 153 * Returns the node id for a given path. 154 * 155 * @param path the node path 156 * @return the node id, or {@code null} 157 */ 158 Serializable getIdForPath(String path); 159 } 160 161 /** 162 * Gets the parent of a node. 163 * <p> 164 * The root has a {@code null} parent. 165 * 166 * @param node the node 167 * @return the parent node, or {@code null} for the root's parent 168 */ 169 Node getParentNode(Node node); 170 171 /** 172 * Gets the absolute path of a node. 173 * 174 * @param node the node 175 * @return the path 176 */ 177 String getPath(Node node); 178 179 /** 180 * Checks if a child node with the given name exists. 181 * <p> 182 * There are two kinds of children, the regular children documents and the complex properties. The {@code boolean} 183 * {@value #complexProp} allows a choice between those. 184 * 185 * @param parent the parent node 186 * @param name the child name 187 * @param complexProp whether to check complex properties or regular children 188 * @return {@code true} if a child node with that name exists 189 */ 190 boolean hasChildNode(Node parent, String name, boolean complexProp); 191 192 /** 193 * Gets a child node given its parent and name. 194 * 195 * @param parent the parent node 196 * @param name the child name 197 * @param complexProp whether to check complex properties or regular children 198 * @return the child node, or {@code null} is not found 199 */ 200 Node getChildNode(Node parent, String name, boolean complexProp); 201 202 /** 203 * Checks it a node has children. 204 * 205 * @param parent the parent node 206 * @param complexProp whether to check complex properties or regular children 207 * @return {@code true} if the parent has children 208 */ 209 boolean hasChildren(Node parent, boolean complexProp); 210 211 /** 212 * Gets the children of a node. 213 * 214 * @param parent the parent node 215 * @param name the children name to get (for lists of complex properties), or {@code null} for all 216 * @param complexProp whether to check complex properties or regular children 217 * @return the collection of children 218 */ 219 List<Node> getChildren(Node parent, String name, boolean complexProp); 220 221 /** 222 * Creates a new child node. 223 * 224 * @param parent the parent to which the child is added 225 * @param name the child name 226 * @param pos the child position, or {@code null} 227 * @param typeName the child type 228 * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false}) 229 * @return the new node 230 */ 231 Node addChildNode(Node parent, String name, Long pos, String typeName, boolean complexProp); 232 233 /** 234 * Creates a new child node with given id (used for import). 235 * 236 * @param id the id 237 * @param parent the parent to which the child is added 238 * @param name the child name 239 * @param pos the child position, or {@code null} 240 * @param typeName the child type 241 * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false}) 242 * @return the new node 243 */ 244 Node addChildNode(Serializable id, Node parent, String name, Long pos, String typeName, boolean complexProp); 245 246 /** 247 * Creates a proxy for a version node. 248 * 249 * @param targetId the target id 250 * @param versionSeriesId the version series id 251 * @param parent the parent to which the proxy is added 252 * @param name the proxy name 253 * @param pos the proxy position 254 * @return the new proxy node 255 */ 256 Node addProxy(Serializable targetId, Serializable versionSeriesId, Node parent, String name, Long pos); 257 258 /** 259 * Sets a proxies' target. 260 * 261 * @param proxy the proxy 262 * @param targetId the new target id 263 * @since 5.5 264 */ 265 void setProxyTarget(Node proxy, Serializable targetId); 266 267 /** 268 * Removes a node from the storage. 269 * <p> 270 * This is much more complex that removing a property node ( {@link #removePropertyNode}). 271 * 272 * @param node the node to remove 273 * @see {@link #removePropertyNode} 274 */ 275 void removeNode(Node node); 276 277 /** 278 * Removes a property node from the storage. 279 * <p> 280 * This is much less complex that removing a generic document node ( {@link #removeNode}). 281 * 282 * @param node the property node to remove 283 * @see {@link #removeNode} 284 */ 285 void removePropertyNode(Node node); 286 287 /** 288 * Order the given source child node before the destination child node. The source node will be placed before the 289 * destination one. If destination is {@code null}, the source node will be appended at the end of the children 290 * list. 291 * 292 * @param parent the parent node 293 * @param source the child node to move 294 * @param dest the child node before which to place the source node, or {@code null} to move at the end 295 */ 296 void orderBefore(Node parent, Node source, Node dest); 297 298 /** 299 * Moves a node to a new location with a new name. 300 * <p> 301 * A {@link #save} is automatically done first. 302 * 303 * @param source the node to move 304 * @param parent the new parent to which the node is moved 305 * @param name the new node name 306 * @return the moved node 307 */ 308 Node move(Node source, Node parent, String name); 309 310 /** 311 * Copies a node to a new location with a new name. 312 * <p> 313 * A {@link #save} is automatically done first. 314 * 315 * @param source the node to copy 316 * @param parent the new parent to which the node is copied 317 * @param name the new node name 318 * @return the copied node 319 */ 320 Node copy(Node source, Node parent, String name); 321 322 /** 323 * Checks in a checked-out node: creates a new version with a copy of its information. 324 * <p> 325 * A {@link #save} is automatically done first. 326 * 327 * @param node the node to check in 328 * @param label the label for the version 329 * @param checkinComment the description for the version 330 * @return the created version 331 */ 332 Node checkIn(Node node, String label, String checkinComment); 333 334 /** 335 * Checks out a checked-in node. 336 * 337 * @param node the node to check out 338 */ 339 void checkOut(Node node); 340 341 /** 342 * Restores a node to a given version. 343 * <p> 344 * The restored node is checked in. 345 * 346 * @param node the node to restore 347 * @param version the version to restore from 348 */ 349 void restore(Node node, Node version); 350 351 /** 352 * Gets a version given its version series id and label. 353 * 354 * @param versionSeriesId the version series id 355 * @param label the label 356 * @return the version node, or {@code null} if not found 357 */ 358 Node getVersionByLabel(Serializable versionSeriesId, String label); 359 360 /** 361 * Gets all the versions for a given version series id. 362 * <p> 363 * A {@link #save} is automatically done first. 364 * 365 * @param versionSeriesId the version series id 366 * @return the list of versions 367 */ 368 List<Node> getVersions(Serializable versionSeriesId); 369 370 /** 371 * Gets the last version for a given version series id. 372 * <p> 373 * A {@link #save} is automatically done first. 374 * 375 * @param versionSeriesId the version series id 376 * @return the last version, or {@code null} if no versions exist 377 */ 378 Node getLastVersion(Serializable versionSeriesId); 379 380 /** 381 * Finds the proxies for a document. If the parent is not null, the search will be limited to its direct children. 382 * <p> 383 * If the document is a version, then only proxies to that version will be looked up. 384 * <p> 385 * Otherwise all proxies to the same version series than the document are retrieved. 386 * <p> 387 * A {@link #save} is automatically done first. 388 * 389 * @param document the document 390 * @param parent the parent, or {@code null} 391 * @return the list of proxies 392 */ 393 List<Node> getProxies(Node document, Node parent); 394 395 /** 396 * Makes a NXQL query to the database. 397 * 398 * @param query the query 399 * @param queryFilter the query filter 400 * @param countTotal if {@code true}, also count the total size without offset/limit 401 * @return the resulting list with total size included 402 */ 403 PartialList<Serializable> query(String query, QueryFilter queryFilter, boolean countTotal); 404 405 /** 406 * Makes a query to the database. 407 * 408 * @param query the query 409 * @param queryType the query type 410 * @param queryFilter the query filter 411 * @param countUpTo if {@code -1}, also count the total size without offset/limit.<br> 412 * If {@code 0}, don't count the total size.<br> 413 * If {@code n}, count the total number if there are less than n documents otherwise set the size to 414 * {@code -1}. 415 * @return the resulting list with total size included 416 * @since 5.6 417 */ 418 PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, long countUpTo); 419 420 /** 421 * Makes a query to the database and returns an iterable (which must be closed when done). 422 * 423 * @param query the query 424 * @param queryType the query type 425 * @param queryFilter the query filter 426 * @param params optional query-type-dependent parameters 427 * @return an iterable, which <b>must</b> be closed when done 428 */ 429 IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter, Object... params); 430 431 /** 432 * Makes a query to the database and returns an iterable (which must be closed when done). 433 * 434 * @param query the query 435 * @param queryType the query type 436 * @param queryFilter the query filter 437 * @param distinctDocuments if {@code true} then a maximum of one row per document will be returned 438 * @param params optional query-type-dependent parameters 439 * @return an iterable, which <b>must</b> be closed when done 440 * @since 7.10-HF04, 8.2 441 */ 442 IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter, 443 boolean distinctDocuments, Object... params); 444 445 /** 446 * Makes a query to the database. 447 * 448 * @param query the query 449 * @param queryType the query type 450 * @param queryFilter the query filter 451 * @param distinctDocuments if {@code true} then a maximum of one row per document will be returned 452 * @param countUpTo if {@code -1}, also count the total size without offset/limit.<br> 453 * If {@code 0}, don't count the total size.<br> 454 * If {@code n}, count the total number if there are less than n documents otherwise set the size to 455 * {@code -1}. 456 * @param params optional query-type-dependent parameters 457 * @return a projection 458 * @since 7.10-HF-25, 8.10-HF06, 9.2 459 */ 460 PartialList<Map<String,Serializable>> queryProjection(String query, String queryType, QueryFilter queryFilter, boolean distinctDocuments, 461 long countUpTo, Object[] params); 462 463 /** 464 * Gets the lock manager for this session. 465 * 466 * @return the lock manager 467 * @since 7.4 468 */ 469 LockManager getLockManager(); 470 471 /** 472 * Read ACLs are optimized ACLs for the read permission, they need to be updated after document creation or ACL 473 * change. 474 * <p> 475 * This method flag the current session, the read ACLs update will be done automatically at save time. 476 */ 477 void requireReadAclsUpdate(); 478 479 /** 480 * Update only the read ACLs that have changed. 481 */ 482 void updateReadAcls(); 483 484 /** 485 * Rebuild the read ACLs for the whole repository. 486 */ 487 void rebuildReadAcls(); 488 489 /** 490 * Gets the fulltext extracted from the binary fields. 491 * 492 * @since 5.9.3 493 */ 494 Map<String, String> getBinaryFulltext(Serializable id); 495 496 /** 497 * Checks if change token management is enabled. 498 * 499 * @since 9.1 500 */ 501 boolean isChangeTokenEnabled(); 502 503 /** 504 * Marks the document as being modified by a user change. 505 * <p> 506 * This causes an additional change token increment and check during save. 507 * 508 * @param id the document id 509 * @since 9.2 510 */ 511 void markUserChange(Serializable id); 512 513}