All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marklogic.xcc.ResultSequence Maven / Gradle / Ivy

There is a newer version: 11.3.0
Show newest version
/*
 * Copyright (c) 2020 MarkLogic Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.marklogic.xcc;

import java.util.Iterator;
import java.io.Closeable;

import com.marklogic.xcc.types.XdmItem;
import com.marklogic.xcc.types.XdmSequence;

/**
 * 

* A sequence of {@link ResultItem} values as returned from a query or module execution. A * ResultSequence instance is stateful, it holds an internal positional index (cursor) which is * updated on successive accesses. It is therefore not recommended that ResultSequence objects be * accessed concurrently by multiple threads. *

*

* ResultSequence instances can operate in two modes: cached and non-cached. If a ResultSequence is * cached (default) then all {@link com.marklogic.xcc.types.XdmItem}s have been read and buffered. * If non-cached, then items may only be accessed sequentially and some values may only be fetched * once if accessed as an {@link java.io.InputStream} or {@link java.io.Reader}. *

*

* Cached ResultSequences need not be closed. Upon return, they no longer tie up any connection * resources. However, closing a cached ResultSequence will invalidate it and prevent further access * to its contents. *

*

* Streaming (non-cached) ResultSequences should always be promptly closed. They hold a server * connection until closed. If not closed, connections may be tied up indefinitely. Additionally, * you should always consume the ResultSequence in a timely manner, because the server may close the * connection if the (server-side configurable) request tiemout expires before the data is read out. *

*

* In general, it is preferable to use cached ResultSequences (this is the default) unless you have * reason to believe the amount of data returned may be too large to be fully buffered in memory. *

*/ public interface ResultSequence extends XdmSequence, Closeable { /** *

* Returns the number of {@link ResultItem}s, if known, in this ResultSequence. For streaming * (non-cached) ResultSequences, {@link ResultItem}s are processed sequentially from the * communication channel and so the size of the full sequence is not known during iteration. *

* * @return The size, if this ResultSequence is cached, otherwise -1. */ int size(); /** *

* Indicates whether this is a cached (detached) ResultSequence. A cached ResultSequence has * fully buffered all the {@link ResultItem} data values and no longer depends on an active * server connection. A cached ResultSequence may be accessed repeatedly and/or randomly. *

*

* Cached ResultSequence objects do not need to be closed because they no longer have any * reference to a server connection. But if they are closed (by invoking {@link #close()}, then * the buffered data values are released and it is no longer usable. *

* * @return True if the entire ResultSequence is cached. If this ResultSequence is closed, then * false is returned. */ boolean isCached(); /** * Release any resources being held by this ResultSequence. If cached, this is a no-op an the * cached {@link ResultItem}s are retained (let the ResultSequence go out of scope to cause the * cached data to be reclaimed). If not cached, this ResultSequence will be invalidated and its * {@link ResultItem} members will no longer be accessible. */ void close(); /** * Indicates whether this ResultSequence is closed. * * @return true if closed, false if open. */ boolean isClosed(); /** * Returns true if this sequence contains another item beyond the currently active one. * Initially, the result sequence is positioned before the first item, if any, and this method * will return false if the sequence is empty. Note that if the current item is large (node, * binary, text) and has not yet been fully consumed by the client, it's value may be flushed * and lost as the result stream is positioned to the next item. * * @return True if at least one more item exists in this ResultSequence. If closed, this method * always returns false. */ boolean hasNext(); /** *

* Advance the logical cursor to the next {@link ResultItem} in this ResultSequence and return * that item. The logical cursor is initially positioned before the first item in the sequence. *

*

* Unlike {@link java.util.Iterator#next()}, this method returns null when there is no next * item. *

* * @return The next {@link ResultItem} in this sequence, or null if the end of the sequence has * been reached. Note that the sequence may be empty and this method may return null on * the first call. * @throws IllegalStateException * If this ResultSequence is closed. */ ResultItem next(); /** *

* Fetch the current {@link ResultItem} object in the ResultSequence. The method * {@link com.marklogic.xcc.ResultItem#isFetchable()} indicates whether the value for this item * is available. Simple data values (numbers, dates, durations, etc) are cached and may always * be re-fetched. *

*

* Large data values (nodes, text, etc) that are read as a stream or a reader are not guaranteed * to be fetchable more than once. *

* * @return The currently active {@link ResultItem} in this sequence, or null if the cursor is * not currently positioned on an item. This will be the case before the first call to * {@link #next()} and after {@link #next()} returns null. * @throws IllegalStateException * If this method is called before the first call to {@link #next()} or after * {@link #next()} returns null or if closed. * @see com.marklogic.xcc.ResultItem#isFetchable() * @see #isCached() * @see com.marklogic.xcc.ResultItem#isCached() */ ResultItem current(); /** *

* Returns the {@link ResultItem} from this ResultSequence, if possible, at the given positional * index. Accessing {@link ResultItem}s randomly has restrictions if {@link #isCached()} returns * true. *

*

* For streaming ResultSequences, if index is equal to the current position, then the current * {@link ResultItem} is returned. If index is less than the current position, then an exception * is thrown. If index is greater than the current position, then items in the sequence are read * and discarded until the requested position is achieved. If the requested item is found, it is * returned. If the end of the sequence is encountered while trying to seek to the requested * position, an exception is thrown. *

* * @param index * The position (zero-based) of the {@link ResultItem} to return. * @return The {@link ResultItem} at the given index. * @throws IllegalArgumentException * If index is negative or greater than or equal to {@link #size}. * @throws IllegalStateException * If this ResultSequence is not cached ({@link #isCached()} returns false) and the * index does not match the current cursor value, or if closed. */ ResultItem resultItemAt(int index); /** * Returns the {@link XdmItem} wrapped by the {@link ResultItem} at the given index. * * @param index * The position (zero-based) of the {@link ResultItem} to return. * @return The underlying {@link XdmItem} for the {@link ResultItem} at the requested index. * @throws IllegalArgumentException * If index is negative or greater than or equal to {@link #size}. * @throws IllegalStateException * If this ResultSequence is not cached ({@link #isCached()} returns false) and the * index xdoes not match the current cursor value, or if closed. */ XdmItem itemAt(int index); /** * Reset the internal positional index (cursor) of this ResultSequence to before the first * {@link ResultItem} in the sequence. This operation is only supported if {@link #isCached()} * returns true. * * @throws IllegalStateException * If called on a non-cached (streaming) ResultSequence ({@link #isCached()} returns * false). * @throws IllegalStateException * If this ResultSequence streaming or is closed. */ void rewind(); /** * Returns a java.util.Iterator instance that may be used to iterate over this result sequence. * Each object returned by the Iterator is an instance of {@link ResultItem}. * * @return An Iterator instance for this ResultSequence. * @throws IllegalStateException * If this ResultSequence is closed. */ Iterator iterator(); /** * Produce a cached version of this ResultSequence. If the provided ResultSequence is already * cached ({@link #isCached()} returns true), then nothing is done and this instance returns * itself. Otherwise, a new, cached ResultSequence instance is created and populated with the * {@link com.marklogic.xcc.types.XdmItem}s in the sequence. If the non-cached input * ResultSequence has been partially iterated, only the remaining * {@link com.marklogic.xcc.types.XdmItem}s will be cached. If the current item is not fetchable * ({@link com.marklogic.xcc.ResultItem#isFetchable()} returns false), it will be ignored. * * @return A Cached ResultSequence. * @throws IllegalStateException * If this ResultSequence is closed. * @see #isCached() */ ResultSequence toCached(); /** *

* This method is identical to the superclass method {@link #toArray()}, but returns an array * typed as {@link ResultItem}. *

*

* Invoking {@link #toArray()} on a ResultSequence actually invokes this method. If the * ResultSequence is streaming ({@link #isCached()} returns false), then it is consumed and * closed after building the returned array. Note also that {@link #asStrings()} when called on * a ResultSequence will call this method internally, which will also result in the object being * closed automatically. *

*

* Note that for a streaming ResultSequence, all items will be loaded into memory to build the * array. If very large items (node(), text(), etc) are in the stream, it's possible that there * may not be enough memory to buffer everything. If the sequence contains too much data to * buffer, iterate over each item and use {@link com.marklogic.xcc.ResultItem#asInputStream()} * to read each item in turn as an {@link java.io.InputStream}. *

* * @return An array of {@link ResultItem} instances, all of which will be cached. * @throws IllegalStateException * If this ResultSequence is closed. * @throws com.marklogic.xcc.exceptions.StreamingResultException * If an IOException ocurrs while buffering a {@link ResultItem} */ ResultItem[] toResultItemArray(); /** * Return the {@link ResultSequence} for an alternate {@link ResultChannelName}. The * {@link ResultSequence} returned by {@link Session#submitRequest(Request)} is the sequence of * {@link com.marklogic.xcc.types.XdmItem}s representing the XQuery result. But there may be * alternate channels (each comprising a {@link ResultSequence} instance) associated with the * result. This method returns the sequence for the given channel. The {@link ResultSequence} * returned by {@link Session#submitRequest(Request)} is always * {@link ResultChannelName#PRIMARY}. A {@link ResultSequence} instance is always returned by * this method, though it may be empty. * * @param channel * An instance of {@link ResultChannelName} that indicates which channel to return. * @return An instance of {@link ResultSequence}, possibly empty. * @throws IllegalStateException * If this ResultSequence is closed. */ ResultSequence getChannel(ResultChannelName channel); /** * Return a textual description of this ResultSequence object, NOT the value of * the items in the sequence. Use the {@link #asString()} or {@link #asStrings()} methods to * obtain {@link String} representations of the item values. * * @return A textual description of this object, appropriate for use in a debug or log message. * @see #asString() * @see #asStrings() */ String toString(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy