/** * Check if the named node type is in use in any workspace in the repository * * @param nodeTypeName the name of the node type to check * @return true if at least one node is using that type; false otherwise * @throws InvalidQueryException if there is an error searching for uses of the named node type */ boolean isNodeTypeInUse(Name nodeTypeName) throws InvalidQueryException { String nodeTypeString = nodeTypeName.getString(context.getNamespaceRegistry()); String expression = "SELECT * from [" + nodeTypeString + "] LIMIT 1"; TypeSystem typeSystem = context.getValueFactories().getTypeSystem(); // Parsing must be done now ... QueryCommand command = queryParser.parseQuery(expression, typeSystem); assert command != null : "Could not parse " + expression; Schemata schemata = getRepositorySchemata(); // Now query the entire repository for any nodes that use this node type ... RepositoryCache repoCache = repository.repositoryCache(); RepositoryQueryManager queryManager = repository.queryManager(); Set<String> workspaceNames = repoCache.getWorkspaceNames(); Map<String, NodeCache> overridden = null; NodeTypes nodeTypes = repository.nodeTypeManager().getNodeTypes(); RepositoryIndexes indexDefns = repository.queryManager().getIndexes(); CancellableQuery query = queryManager.query( context, repoCache, workspaceNames, overridden, command, schemata, indexDefns, nodeTypes, null, null); try { QueryResults result = query.execute(); if (result.isEmpty()) return false; if (result.getRowCount() < 0) { // Try to get the first row ... NodeSequence seq = result.getRows(); Batch batch = seq.nextBatch(); while (batch != null) { if (batch.hasNext()) return true; // It's not common for the first batch may be empty, but it's possible. So try the next // batch ... batch = seq.nextBatch(); } return false; } return result.getRowCount() > 0; } catch (RepositoryException e) { logger.error(e, JcrI18n.errorCheckingNodeTypeUsage, nodeTypeName, e.getLocalizedMessage()); return true; } }
/** * Load all of the rows from the supplied sequence into the buffer. * * @param sequence the node sequence; may not be null * @param extractor the extractor for the sortable value; may not be null * @param rowsWithNullKey the buffer into which should be placed all rows for which the extracted * key value is null; may be null if these are not to be kept * @return the size of the first batch, or 0 if there are no rows found */ protected int loadAll( NodeSequence sequence, ExtractFromRow extractor, DistinctBuffer<BufferedRow> rowsWithNullKey) { // Put all of the batches from the sequence into the buffer Batch batch = sequence.nextBatch(); int batchSize = 0; Object value = null; while (batch != null && batchSize == 0) { while (batch.hasNext()) { batch.nextRow(); value = extractor.getValueInRow(batch); if (value instanceof Object[]) { // Put each of the values in the buffer ... for (Object v : (Object[]) value) { buffer.put(v, createRow(batch)); } } else if (value != null) { buffer.put(value, createRow(batch)); } else if (rowsWithNullKey != null) { rowsWithNullKey.addIfAbsent(createRow(batch)); } ++batchSize; } batch = sequence.nextBatch(); } while (batch != null) { while (batch.hasNext()) { batch.nextRow(); value = extractor.getValueInRow(batch); if (value instanceof Object[]) { // Put each of the values in the buffer ... for (Object v : (Object[]) value) { buffer.put(v, createRow(batch)); } } else if (value != null) { buffer.put(value, createRow(batch)); } else if (rowsWithNullKey != null) { rowsWithNullKey.addIfAbsent(createRow(batch)); } } batch = sequence.nextBatch(); } return batchSize; }
@SuppressWarnings("unchecked") protected BufferingSequence( String workspaceName, NodeSequence delegate, ExtractFromRow extractor, BufferManager bufferMgr, CachedNodeSupplier nodeCache, boolean pack, boolean useHeap, boolean allowDuplicates) { super(delegate); assert extractor != null; this.workspaceName = workspaceName; this.width = delegate.width(); this.cache = nodeCache; this.extractor = extractor; // Set up the row factory based upon the width of the delegate sequence... this.rowFactory = BufferedRows.serializer(nodeCache, width); // Set up the buffer ... SortingBuffer<Object, BufferedRow> buffer = null; TypeFactory<?> keyType = extractor.getType(); if (allowDuplicates) { @SuppressWarnings("rawtypes") Serializer<? extends Comparable> keySerializer = (Serializer<? extends Comparable<?>>) bufferMgr.serializerFor(keyType); buffer = bufferMgr .createSortingWithDuplicatesBuffer( keySerializer, extractor.getType().getComparator(), (BufferedRowFactory<BufferedRow>) rowFactory) .keepSize(true) .useHeap(useHeap) .make(); } else { BTreeKeySerializer<Object> keySerializer = (BTreeKeySerializer<Object>) bufferMgr.bTreeKeySerializerFor(keyType, pack); if (keySerializer instanceof KeySerializerWithComparator) { keySerializer = ((KeySerializerWithComparator<Object>) keySerializer) .withComparator(extractor.getType().getComparator()); } buffer = bufferMgr .createSortingBuffer(keySerializer, (BufferedRowFactory<BufferedRow>) rowFactory) .keepSize(true) .useHeap(useHeap) .make(); } this.buffer = buffer; }
protected Batch batchFrom(final Iterator<BufferedRow> rows, final long maxBatchSize) { if (rows == null || !rows.hasNext()) return null; if (maxBatchSize == 0 || remainingRowCount.get() <= 0) return NodeSequence.emptyBatch(workspaceName, this.width); final long rowsInBatch = Math.min(maxBatchSize, remainingRowCount.get()); rowsLeftInBatch.set(rowsInBatch); return new Batch() { private BufferedRow current; @Override public int width() { return width; } @Override public long rowCount() { return rowsInBatch; } @Override public String getWorkspaceName() { return workspaceName; } @Override public boolean isEmpty() { return rowsInBatch <= 0; } @Override public boolean hasNext() { return rowsLeftInBatch.get() > 0 && rows.hasNext(); } @Override public void nextRow() { current = rows.next(); remainingRowCount.decrementAndGet(); rowsLeftInBatch.decrementAndGet(); } @Override public CachedNode getNode() { return current.getNode(); } @Override public CachedNode getNode(int index) { return current.getNode(index); } @Override public float getScore() { return current.getScore(); } @Override public float getScore(int index) { return current.getScore(index); } @Override public String toString() { return "(buffered-batch size=" + rowsInBatch + " )"; } }; }