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

Reply via email to