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