Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/feature-setvar-typed into lp:zorba.
Commit message: 1. setVariable() now supports casting elements of sequences. 2. zorba command now supports converting multiple values for the same variable into a sequence, e.g.: zorba -e x:=1 -e x:=2 -q 'declare variable $x as xs:integer+ external;' returns: 1 2 Requested reviews: Paul J. Lucas (paul-lucas) For more details, see: https://code.launchpad.net/~zorba-coders/zorba/feature-setvar-typed/+merge/217539 1. setVariable() now supports casting elements of sequences. 2. zorba command now supports converting multiple values for the same variable into a sequence, e.g.: zorba -e x:=1 -e x:=2 -q 'declare variable $x as xs:integer+ external;' returns: 1 2 -- https://code.launchpad.net/~zorba-coders/zorba/feature-setvar-typed/+merge/217539 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'bin/zorbacmd.cpp' --- bin/zorbacmd.cpp 2014-04-25 22:46:44 +0000 +++ bin/zorbacmd.cpp 2014-04-29 01:37:07 +0000 @@ -15,9 +15,11 @@ */ // standard +#include <algorithm> #include <cassert> #include <fstream> #include <iostream> +#include <memory> #include <sstream> #include <string> #include <vector> @@ -68,6 +70,63 @@ /////////////////////////////////////////////////////////////////////////////// +class VarSeqIterator : public Iterator { +public: + void push_back( Item const &item ) { + items_.push_back( item ); + } + + // inherited + void close(); + int64_t count(); + bool isOpen() const; + bool next( Item& ); + void open(); + void reset(); + bool skip( int64_t ); + +private: + typedef vector<Item> items_type; + items_type items_; + bool is_open_; + items_type::size_type pos_; +}; + +void VarSeqIterator::close() { + is_open_ = false; +} + +int64_t VarSeqIterator::count() { + return items_.size(); +} + +bool VarSeqIterator::isOpen() const { + return is_open_; +} + +bool VarSeqIterator::next( Item &result ) { + if ( pos_ < items_.size() ) { + result = items_[ pos_++ ]; + return true; + } + return false; +} + +void VarSeqIterator::open() { + pos_ = 0; + is_open_ = true; +} + +void VarSeqIterator::reset() { + pos_ = 0; +} + +bool VarSeqIterator::skip( int64_t count ) { + return (pos_ += count) < items_.size(); +} + +/////////////////////////////////////////////////////////////////////////////// + static const char copyright[] = "Copyright 2006-2014 The FLWOR Foundation.\n" "License: Apache License 2.0: <http://www.apache.org/licenses/LICENSE-2.0>"; @@ -228,7 +287,7 @@ } bool populateDynamicContext( Zorba *zorba, DynamicContext *dctx ) { - ZorbaCmdProperties const &zc_props = ZorbaCmdProperties::instance(); + ZorbaCmdProperties &zc_props = ZorbaCmdProperties::instance(); XmlDataManager_t xmlMgr; if ( !zc_props.ctx_item_.empty() ) { @@ -238,9 +297,23 @@ dctx->setContextItem( doc ); } - external_vars::const_iterator i = zc_props.external_vars_.begin(); - external_vars::const_iterator const end = zc_props.external_vars_.end(); - for ( ; i != end; ++i ) { + // sort vars: x:=1 y:=foo x:=2 --> x:=1 x:=2 y:=foo + stable_sort( zc_props.external_vars_.begin(), zc_props.external_vars_.end() ); + + external_vars::const_iterator i; + external_vars::const_iterator const end( zc_props.external_vars_.end() ); + + // + // Count how many of each variable there are to know whether there are + // multiple values for the same variable. If there are, we have to create an + // Iterator for them later. + // + typedef map<String,int> var_count_type; + var_count_type var_count; + for ( i = zc_props.external_vars_.begin(); i != end; ++i ) + ++var_count[ i->var_name ]; + + for ( i = zc_props.external_vars_.begin(); i != end; ++i ) { try { if ( i->inline_file ) { ifstream is( i->var_value.c_str() ); @@ -249,8 +322,26 @@ Item doc( xmlMgr->parseXML( is ) ); dctx->setVariable( i->var_name, doc ); } else { - Item item( zorba->getItemFactory()->createString( i->var_value ) ); - dctx->setVariable( i->var_name, item, true ); + int count = var_count[ i->var_name ]; + if ( count == 1 ) { + // easy case: only a single value + Item item( zorba->getItemFactory()->createString( i->var_value ) ); + dctx->setVariable( i->var_name, item, true ); + } else { + // hard case: multiple values -- construct an Iterator + auto_ptr<VarSeqIterator> var_seq_iter( new VarSeqIterator ); + String const var_name( i->var_name ); + while ( true ) { + Item item( zorba->getItemFactory()->createString( i->var_value ) ); + var_seq_iter->push_back( item ); + if ( !--count ) + break; + ++i; + } // while + Iterator_t iter( var_seq_iter.get() ); + var_seq_iter.release(); + dctx->setVariable( var_name, iter, true ); + } } } catch ( ... ) { === modified file 'bin/zorbacmd_props.h' --- bin/zorbacmd_props.h 2014-02-11 05:08:19 +0000 +++ bin/zorbacmd_props.h 2014-04-29 01:37:07 +0000 @@ -24,17 +24,22 @@ // Zorba #include <zorba/config.h> +#include <zorba/zorba_string.h> /////////////////////////////////////////////////////////////////////////////// struct external_var { - std::string var_name; - std::string var_value; - bool inline_file; + zorba::String var_name; + zorba::String var_value; + bool inline_file; external_var() : inline_file( false ) { } }; +inline bool operator<( external_var const &i, external_var const &j ) { + return i.var_name < j.var_name; +} + typedef std::vector<external_var> external_vars; typedef std::pair<std::string,std::string> serialization_param; === modified file 'include/zorba/dynamic_context.h' --- include/zorba/dynamic_context.h 2014-04-25 23:54:56 +0000 +++ include/zorba/dynamic_context.h 2014-04-29 01:37:07 +0000 @@ -107,13 +107,16 @@ * @param aQName the QName that identifies the external variable. * @param aIterator the Iterator producing the sequence that is assigned * to the variable. + * @param cast If \c true, attempt to cast \a each item to the type (if any) + * that the external variable was declared as. * @return true if the variable has been set successfully, false otherwise. * @throw ZorbaException if an error occured (e.g. the given Iterator is not valid). */ virtual bool setVariable( const String& aQName, - const Iterator_t& aIterator) = 0; + const Iterator_t& aIterator, + bool cast = false) = 0; /** * \brief Defines the external variable identified by an expanded QName and @@ -126,6 +129,8 @@ * @param aLocalname the local name of the variable's expanded QName * @param aIterator the Iterator producing the sequence that is assigned * to the variable. + * @param cast If \c true, attempt to cast \a each item to the type (if any) + * that the external variable was declared as. * @return true if the variable has been set successfully, false otherwise. * @throw ZorbaException if an error occured (e.g. the given Iterator is not valid). */ @@ -133,7 +138,8 @@ setVariable( const String& aNamespace, const String& aLocalname, - const Iterator_t& aIterator) = 0; + const Iterator_t& aIterator, + bool cast = false) = 0; /** \brief Returns the current value of an external * variable. Exactly one of the two return values (aItem or === modified file 'src/api/dynamiccontextimpl.cpp' --- src/api/dynamiccontextimpl.cpp 2014-04-25 23:54:56 +0000 +++ src/api/dynamiccontextimpl.cpp 2014-04-29 01:37:07 +0000 @@ -228,13 +228,62 @@ return false; } +/** + * A %VarCastIterator adapts another iterator by casting each of the elements + * to some atomic type. + */ +class VarCastIterator : public store::Iterator { +public: + VarCastIterator( store::Iterator_t &source, xqtref_t const &type, + TypeManager const *type_mgr ) : + source_( source ), + type_( TypeOps::prime_type( type_mgr, *type ) ), + type_mgr_( type_mgr ) + { + } + + // inherited + void open(); + bool next( store::Item_t& ); + void close(); + void reset(); + +private: + store::Iterator_t source_; + xqtref_t const type_; + TypeManager const *const type_mgr_; +}; + +void VarCastIterator::open() { + source_->open(); +} + +bool VarCastIterator::next( store::Item_t &result ) { + store::Item_t temp; + if ( source_->next( temp ) ) { + GenericCast::castToAtomic( + result, temp, type_, type_mgr_, /*nsCtx*/ nullptr, QueryLoc::null + ); + return true; + } + return false; +} + +void VarCastIterator::close() { + source_->close(); +} + +void VarCastIterator::reset() { + source_->reset(); +} /****************************************************************************//** ********************************************************************************/ bool DynamicContextImpl::setVariable( const String& inVarName, - const Iterator_t& inValue) + const Iterator_t& inValue, + bool cast) { ZORBA_DCTX_TRY { @@ -267,6 +316,11 @@ throw; } + if ( cast && var->getType() ) + value = new VarCastIterator( + value, var->getType(), var->getVar()->get_type_manager() + ); + ulong varId = var->getId(); theCtx->add_variable(varId, value); @@ -284,7 +338,8 @@ bool DynamicContextImpl::setVariable( const String& inNamespace, const String& inLocalname, - const Iterator_t& inValue) + const Iterator_t& inValue, + bool cast) { ZORBA_DCTX_TRY { @@ -321,6 +376,11 @@ ulong varId = var->getId(); + if ( cast && var->getType() ) + value = new VarCastIterator( + value, var->getType(), var->getVar()->get_type_manager() + ); + theCtx->add_variable(varId, value); return true; === modified file 'src/api/dynamiccontextimpl.h' --- src/api/dynamiccontextimpl.h 2014-04-25 23:54:56 +0000 +++ src/api/dynamiccontextimpl.h 2014-04-29 01:37:07 +0000 @@ -109,13 +109,15 @@ virtual bool setVariable( const String& inVarName, - const Iterator_t& inValue); + const Iterator_t& inValue, + bool cast = false); virtual bool setVariable( const String& inNamespace, const String& inLocalname, - const Iterator_t& inValue); + const Iterator_t& inValue, + bool cast = false); virtual bool setContextItem(const Item& inValue);
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp