> The XQuery Processor
/* * Copyright 2006-2008 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. */ #include <vector> #include <iostream> #include <zorba/zorba.h> #include <zorba/external_function.h> using namespace zorba; class MySimpleExternalFunction : public StatelessExternalFunction { public: virtual String getURI() const { return "urn:foo"; } virtual String getLocalName() const { return "bar"; } virtual ItemSequence_t evaluate(const StatelessExternalFunction::Arguments_t& args) const { iv_t vec; for(int i = 0; i < 2; ++i) { ItemSequence* iseq = args[i]; Item lItem; while(iseq->next(lItem)) { vec.push_back(lItem); } } // transfer ownership of the IteratorBackedItemSequence to Zorba (using an auto_ptr) return ItemSequence_t(new IteratorBackedItemSequence(vec)); } private: typedef std::vector<Item> iv_t; typedef iv_t::iterator ii_t; class IteratorBackedItemSequence : public ItemSequence { public: IteratorBackedItemSequence(iv_t& vec) : m_vec(vec), m_i(m_vec.begin()), m_end(m_vec.end()) { } bool next(Item& val) { if (m_i == m_end) { return false; } val = *m_i; ++m_i; return true; } private: iv_t m_vec; ii_t m_i; ii_t m_end; }; }; class MyLazySimpleExternalFunction : public StatelessExternalFunction { public: virtual String getURI() const { return "urn:foo"; } virtual String getLocalName() const { return "bar2"; } virtual ItemSequence_t evaluate(const StatelessExternalFunction::Arguments_t& args) const { // transfer ownership of the IteratorBackedItemSequence to Zorba (using an auto_ptr) return ItemSequence_t(new LazyConcatItemSequence(args)); } private: class LazyConcatItemSequence : public ItemSequence { public: LazyConcatItemSequence(const StatelessExternalFunction::Arguments_t& args) : m_args(args), m_i(0) { } bool next(Item& i) { while(m_i < m_args.size() && !m_args[m_i]->next(i)) { ++m_i; } return !i.isNull(); } private: StatelessExternalFunction::Arguments_t m_args; size_t m_i; }; }; bool func_example_1(Zorba* aZorba) { StaticContext_t sctx = aZorba->createStaticContext(); MySimpleExternalFunction lFunc; sctx->registerStatelessExternalFunction(&lFunc); XQuery_t lQuery = aZorba->compileQuery("declare namespace foo=\"urn:foo\"; declare function foo:bar($a1, $a2) external; foo:bar((1,2,3), (4,5,6))", sctx); std::cout << lQuery << std::endl; return true; } bool func_example_2(Zorba* aZorba) { try { StaticContext_t lContext = aZorba->createStaticContext(); MySimpleExternalFunction lFunc; lContext->registerStatelessExternalFunction(&lFunc); lContext->registerStatelessExternalFunction(&lFunc); // only allowed to register it once } catch (ZorbaException &e) { std::cerr << "some exception " << e << std::endl; return true; } return false; } bool func_example_3(Zorba* aZorba) { StaticContext_t lContext = aZorba->createStaticContext(); MyLazySimpleExternalFunction lFunc; lContext->registerStatelessExternalFunction(&lFunc); XQuery_t lQuery = aZorba->compileQuery("declare namespace foo=\"urn:foo\"; declare function foo:bar2($a1, $a2) external; foo:bar2((1,2,3), (4,5,6))", lContext); std::cout << lQuery << std::endl; return true; } bool func_example_4(Zorba* aZorba) { StaticContext_t lContext = aZorba->createStaticContext(); MyLazySimpleExternalFunction lFunc; lContext->registerStatelessExternalFunction(&lFunc); XQuery_t lQuery = aZorba->compileQuery("declare namespace foo=\"urn:foo\"; declare function foo:bar2($a1, $a2) external; let $s1 := (1,2,3) let $s2 := (4,5,6) for $x in 1 to 6 return (foo:bar2($s1, $s2)[7-$x])", lContext); std::cout << lQuery << std::endl; return true; } int external_functions(int argc, char* argv[]) { Zorba* lZorba = Zorba::getInstance(); bool res = false; std::cout << std::endl << "executing simple external function test 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" << std::endl; res = func_example_2(lZorba); if (!res) return 1; std::cout << std::endl; std::cout << std::endl << "executing simple external function test 3" << std::endl; res = func_example_3(lZorba); if (!res) return 1; std::cout << std::endl; std::cout << std::endl << "executing simple external function test 4" << std::endl; res = func_example_4(lZorba); if (!res) return 1; std::cout << std::endl; return 0; }