Content of stack module
xquery version "3.0";
(:
: Copyright 2006-2012 The FLWOR Foundation.
:
: 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.
:)
(:~
: Implementation of stack for items, using dynamic collections.<p/>
:
: Entries in the stack must be structured items - that is, either JSON
: Objects or Arrays, or XML Nodes. <p/>
:
: @author Daniel Turcanu, Sorin Nasoi
: @project Zorba/Data Store/Data Structures/Stack
:)
module namespace stack = "http://zorba.io/modules/stack";
import module namespace collections-ddl = "http://zorba.io/modules/store/dynamic/collections/ddl";
import module namespace collections-dml = "http://zorba.io/modules/store/dynamic/collections/dml";
declare namespace ann = "http://zorba.io/annotations";
declare namespace ver = "http://zorba.io/options/versioning";
declare option ver:module-version "1.0";
declare %private variable $stack:errNS as xs:string := "http://zorba.io/modules/stack";
declare %private variable $stack:NOT-EXISTS as xs:QName := fn:QName($stack:errNS, "stack:NOT-EXISTS");
declare %private variable $stack:EXISTS as xs:QName := fn:QName($stack:errNS, "stack:EXISTS");
(:~
: Create a stack with this name. If stack exists, an error is raised. <p/>
:
: @param $name name of the new stack.
: @return an empty sequence.
: @error stack:EXISTS if the stack identified by $name already exists.
:)
declare %ann:sequential function stack:create($name as xs:QName) as empty-sequence()
{
if(collections-ddl:is-available-collection($name)) then
fn:error($stack:EXISTS, "Stack already exists.");
else
collections-ddl:create($name);
};
(:~
: Return the top item in the stack, without removing it. <p/>
:
: @param $name name of the stack.
: @return the top item, or empty sequence if stack is empty.
: @example test/Queries/top1.xq
: @error stack:NOT-EXISTS if the stack identified by $name does not exist.
:)
declare function stack:top($name as xs:QName) as structured-item()?
{
if(not(collections-ddl:is-available-collection($name))) then
fn:error($stack:NOT-EXISTS, "Stack does not exist.")
else
collections-dml:collection($name)[1]
};
(:~
: Return the top item in the stack, and remove it. <p/>
:
: @param $name name of the stack.
: @return the top item, or empty sequence if stack is empty.
: @example test/Queries/pop2.xq
: @error stack:NOT-EXISTS if the stack identified by $name does not exist.
:)
declare %ann:sequential function stack:pop($name as xs:QName) as structured-item()?
{
if(not(collections-ddl:is-available-collection($name))) then
fn:error($stack:NOT-EXISTS, "Stack does not exist.")
else
{
variable $topItem := collections-dml:collection($name)[1];
collections-dml:delete-first($name);
$topItem
}
};
(:~
: Add a new item to the stack; the stack will contain a copy of the given item. <p/>
:
: @param $name name of the stack.
: @param $value the item to be added.
: @return an empty sequence.
: @example test/Queries/push1.xq
: @error stack:NOT-EXISTS if the stack identified by $name does not exist.
:)
declare %ann:sequential function stack:push($name as xs:QName, $value as structured-item()) as empty-sequence()
{
collections-dml:apply-insert-first($name, $value);
};
(:~
: Checks if a stack exists and is empty. <p/>
:
: @param $name name of the stack.
: @return true if the stack is empty or does not exist.
: @example test/Queries/empty1.xq
: @error stack:NOT-EXISTS if the stack identified by $name does not exist.
:)
declare function stack:empty($name as xs:QName) as xs:boolean
{
if(not(collections-ddl:is-available-collection($name))) then
fn:error($stack:NOT-EXISTS, "Stack does not exist.")
else
fn:empty(collections-dml:collection($name))
};
(:~
: Count of items in the stack. <p/>
:
: @param $name name of the stack.
: @return the amount of items.
: @example test/Queries/size1.xq
: @error stack:NOT-EXISTS if the stack identified by $name does not exist.
:)
declare function stack:size($name as xs:QName) as xs:integer
{
if(not(collections-ddl:is-available-collection($name))) then
fn:error($stack:NOT-EXISTS, "Stack does not exist.")
else
fn:count(collections-dml:collection($name))
};
(:~
: Copy all items from source stack to a destination stack. <p/>
: If destination stack does not exist, it is created first. <p/>
: If destination stack is not empty, the items are appended on top. <p/>
:
: @param $destName name of the destination stack.
: @param $sourceName name of the source stack.
: @return an empty sequence.
: @example test/Queries/copy1.xq
:)
declare %ann:sequential function stack:copy($destName as xs:QName, $sourceName as xs:QName) as empty-sequence()
{
if(fn:not(collections-ddl:is-available-collection($destName))) then
collections-ddl:create($destName);
else
();
collections-dml:insert-first($destName, collections-dml:collection($sourceName));
};