This file shows some simple examples of external functions.
#include <vector>
#include <iostream>
#include <sstream>
#include <cassert>
#include <zorba/diagnostic_list.h>
using namespace zorba;
class MySimpleExternalFunction;
class MyLazySimpleExternalFunction;
class MyErrorReportingExternalFunction;
class MyParametrizedExternalFunction;
{
protected:
MySimpleExternalFunction * bar1;
MyLazySimpleExternalFunction * bar2;
MyErrorReportingExternalFunction * bar3;
MyParametrizedExternalFunction * bar4;
public:
MyExternalModule()
:
bar1(0),
bar2(0),
bar3(0),
bar4(0)
{
}
~MyExternalModule();
String getURI()
const {
return "urn:foo"; }
};
bool func_example_0(
Zorba* aZorba)
{
try
{
MyExternalModule lModule;
lContext->registerModule(&lModule);
lContext->registerModule(&lModule);
}
{
std::cerr << "some exception " << e << std::endl;
return true;
}
return false;
}
{
protected:
public:
:
theModule(aModule)
{
}
String getURI()
const {
return theModule->getURI(); }
String getLocalName()
const {
return "bar1"; }
{
<< std::endl;
ItemVector vec;
for (int i = 0; i < 2; ++i)
{
iter->open();
while(iter->next(item))
{
vec.push_back(item);
}
iter->close();
}
}
private:
typedef std::vector<Item> ItemVector;
typedef ItemVector::iterator ItemVectorIte;
{
class InternalIterator :
public Iterator
{
private:
IteratorBackedItemSequence *theItemSequence;
ItemVectorIte theIte;
ItemVectorIte theEnd;
bool is_open;
public:
InternalIterator(IteratorBackedItemSequence *item_sequence) :
theItemSequence(item_sequence),
{ }
void open()
{
is_open = true;
theIte = theItemSequence->theItems.begin();
theEnd = theItemSequence->theItems.end();
}
void close()
{
is_open = false;
}
bool isOpen() const
{
return is_open;
}
{
assert(is_open);
if (theIte == theEnd)
{
return false;
}
val = *theIte;
++theIte;
return true;
}
};
private:
ItemVector theItems;
public:
IteratorBackedItemSequence(ItemVector& vec)
:
theItems(vec)
{
}
Iterator_t getIterator () {
return new InternalIterator(
this);}
};
};
bool func_example_1(
Zorba* aZorba)
{
MyExternalModule module;
sctx->registerModule(&module);
std::ostringstream queryText;
queryText << "declare namespace foo=\"urn:foo\";" << std::endl
<< "declare function foo:bar1($a1, $a2) external;" << std::endl
<< "foo:bar1((1,2,3), (4,5,6))" << std::endl;
std::cout << query << std::endl;
return true;
}
{
protected:
public:
:
theModule(aModule)
{
}
String getURI()
const {
return theModule->getURI(); }
String getLocalName()
const {
return "bar2"; }
{
}
private:
{
class InternalIterator :
public Iterator
{
private:
LazyConcatItemSequence *theItemSequence;
size_t theCurrentArg;
bool is_open;
public:
InternalIterator(LazyConcatItemSequence *item_sequence) : theItemSequence(item_sequence), theCurrentArg(0), is_open(
false)
{
}
virtual void open()
{
is_open = true;
theCurrentArg = 0;
if(theCurrentArg < theItemSequence->theArgs.size())
{
args_iter = theItemSequence->theArgs[theCurrentArg]->getIterator();
args_iter->open();
}
}
virtual void close()
{
if(theCurrentArg < theItemSequence->theArgs.size())
{
args_iter->close();
}
is_open = false;
}
virtual bool isOpen() const
{
return is_open;
}
{
assert(is_open);
if(theCurrentArg == theItemSequence->theArgs.size())
return false;
while(theCurrentArg < 2 && !args_iter->next(result))
{
args_iter->close();
++theCurrentArg;
if(theCurrentArg == theItemSequence->theArgs.size())
return false;
args_iter = theItemSequence->theArgs[theCurrentArg]->getIterator();
args_iter->open();
}
}
};
private:
Arguments_t theArgs;
public:
:
theArgs(args)
{
}
Iterator_t getIterator() {
return new InternalIterator(
this);}
};
};
bool func_example_2_1(
Zorba* aZorba)
{
MyExternalModule module;
sctx->registerModule(&module);
std::ostringstream queryText;
queryText << "declare namespace foo=\"urn:foo\";" << std::endl
<< "declare function foo:bar2($a1, $a2) external;" << std::endl
<< "foo:bar2((1,2,3), (4,5,6))" << std::endl;
std::cout << query << std::endl;
return true;
}
bool func_example_2_2(
Zorba* aZorba)
{
MyExternalModule lModule;
lContext->registerModule(&lModule);
std::ostringstream lText;
lText << "declare namespace foo=\"urn:foo\";" << std::endl
<< "declare function foo:bar2($a1, $a2) external;" << std::endl
<< "let $s1 := (1,2,3)" << std::endl
<< "let $s2 := (4,5,6)" << std::endl
<< "for $x in 1 to 6 return (foo:bar2($s1, $s2)[7-$x])" << std::endl;
std::cout << lQuery << std::endl;
return true;
}
{
protected:
public:
:
theModule(aModule)
{
}
String getURI()
const {
return theModule->getURI(); }
String getLocalName()
const {
return "bar3"; }
{
}
private:
{
class InternalIterator :
public Iterator
{
private:
LazyErrorReportingItemSequence *theItemSequence;
bool is_open;
bool theIsEmpty;
public:
InternalIterator(LazyErrorReportingItemSequence *item_sequence) : theItemSequence(item_sequence), is_open(
false), theIsEmpty(
true)
{
}
virtual void open()
{
is_open = true;
arg0_iter = theItemSequence->theArgs[0]->getIterator();
arg0_iter->open();
}
virtual void close()
{
if(is_open)
arg0_iter->close();
is_open = false;
}
virtual bool isOpen() const
{
return is_open;
}
{
assert(is_open);
bool done = !arg0_iter->next(result);
if (done && theIsEmpty)
{
"argument must not be the empty sequence"
);
}
theIsEmpty = false;
return !done;
}
};
private:
public:
:
theArgs(args)
{
}
Iterator_t getIterator() {
return new InternalIterator(
this);}
};
};
bool func_example_3_1(
Zorba* aZorba)
{
MyExternalModule module;
sctx->registerModule(&module);
std::ostringstream queryText;
queryText << "declare namespace foo=\"urn:foo\";" << std::endl
<< "declare function foo:bar3($a1) external;" << std::endl
<< "let $s1 := ()" << std::endl
<< "for $x in 1 to 6 return (foo:bar3($s1))" << std::endl;
try
{
std::cout << query << std::endl;
}
{
std::cerr << ex << std::endl;
}
return false;
}
{
protected:
public:
:
theModule(aModule)
{
}
String getURI()
const {
return theModule->getURI(); }
String getLocalName()
const {
return "bar4"; }
{
void* lParam;
std::string lParamName("myparam");
{
assert(false);
}
std::cout << "the function param: " << *static_cast<std::string*>(lParam)
<< std::endl;
}
};
bool func_example_4_1(
Zorba* aZorba)
{
MyExternalModule module;
sctx->registerModule(&module);
std::ostringstream queryText;
queryText << "declare namespace foo=\"urn:foo\";" << std::endl
<< "declare function foo:bar4() external;" << std::endl
<< "for $x in 1 to 6 return (foo:bar4())" << std::endl;
std::string lFunctionParam("foo:bar");
try
{
std::cout << query << std::endl;
}
{
std::cerr << ex << std::endl;
}
return true;
}
MyExternalModule::~MyExternalModule()
{
delete bar1;
delete bar2;
delete bar3;
delete bar4;
}
{
if (aLocalname == "bar1")
{
if (!bar1)
{
bar1 = new MySimpleExternalFunction(this);
}
return bar1;
}
else if (aLocalname == "bar2")
{
if (!bar2)
{
bar2 = new MyLazySimpleExternalFunction(this);
}
return bar2;
}
else if (aLocalname == "bar3")
{
if (!bar3)
{
bar3 = new MyErrorReportingExternalFunction(this);
}
return bar3;
}
else if (aLocalname == "bar4")
{
if (!bar3)
{
bar4 = new MyParametrizedExternalFunction(this);
}
return bar4;
}
return 0;
}
static void
releaseStream(std::istream* aStream)
{
delete aStream;
}
{
public:
~MyModuleURLResolver() {}
{
aUrl == "http://www.zorba-xquery.com/mymodule")
{
std::auto_ptr<std::istream> lQuery
(new std::istringstream
("module namespace lm = 'http://www.zorba-xquery.com/mymodule'; "
"declare function lm:foo() { 'foo' }; "
"declare function lm:ext() external;"));
}
else {
return NULL;
}
}
};
class MyModuleExternalFunction;
{
protected:
MyModuleExternalFunction * theExtFunc;
public:
MyModuleExternal(
Zorba* aZorba) : theZorba(aZorba), theExtFunc(NULL) {}
~MyModuleExternal() {}
ItemFactory* getItemFactory()
const {
return theZorba->getItemFactory(); }
{
return "http://www.zorba-xquery.com/mymodule";
}
void setExternalFunction(MyModuleExternalFunction* f)
{
theExtFunc = f;
}
{
if (aLocalname == "ext")
{
}
return NULL;
}
};
{
protected:
MyModuleExternal * theModule;
std::vector<Item> theItems;
public:
MyModuleExternalFunction(MyModuleExternal* aModule)
:
theModule(aModule)
{
Item item = aModule->getItemFactory()->createString(
"ext");
theItems.push_back(item);
theModule->setExternalFunction(this);
}
{
return theModule->getURI();
}
{
return "ext";
}
{
}
};
bool func_example_5(
Zorba* aZorba)
{
MyModuleURLResolver moduleResolver;
sctx->registerURLResolver(&moduleResolver);
MyModuleExternal lExternalModule(aZorba);
sctx->registerModule(&lExternalModule);
MyModuleExternalFunction lExtFunc(&lExternalModule);
std::ostringstream queryText;
queryText << "import module namespace lm=\"http://www.zorba-xquery.com/mymodule\";"
<< "concat(lm:foo(), lm:ext())" << std::endl;
try
{
std::cout << query << std::endl;
}
{
std::cerr << ex << std::endl;
return false;
}
return true;
}
int external_functions(int argc, char* argv[])
{
bool res = false;
std::cout << std::endl << "executing simple external function test 0" << std::endl;
res = func_example_0(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 1.1" << std::endl;
res = func_example_1(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 2.1" << std::endl;
res = func_example_2_1(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 2.2" << std::endl;
res = func_example_2_2(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 3.1" << std::endl;
res = func_example_3_1(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 4.1" << std::endl;
res = func_example_4_1(lZorba);
if (!res) return 1;
std::cout << std::endl;
std::cout << std::endl << "executing simple external function test 5" << std::endl;
res = func_example_5(lZorba);
if (!res) return 1;
std::cout << std::endl;
return 0;
}