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