Jim Schueler
and 1 contributors


NoSQL::PL2SQL::Node - Private Perl extension for NoSQL::PL2SQL


The NoSQL::PL2SQL::Node package is private. None of its methods or functions are part of the public interface.

  use NoSQL::PL2SQL::Node ;

  ## Functions with external callers

  my $recordid = NoSQL::PL2SQL::Node->factory( $dsn, $obj ) ;
  my $recordid = NoSQL::PL2SQL::Node->factory( $dsn, $objectid, $obj ) ;
  my $recordid = NoSQL::PL2SQL::Node->factory( $dsn, $objectid, $obj ) ;

  my @nodes = NoSQL::PL2SQL::Node->factory( undef, $objectid, $obj ) ;

  my @combined = combine( @nodes ) ;
  my( $lastrecno, $refs ) = insertall( $dsn, @combined ) ;

  my $datatype = typemap( $scalar ) ;

  ## Functions with only internal callers

  my @nodes = xml2sql( XML::Parser::Nodes->pl2xml( $o ), $globals = {} ) ;

  my $node = NoSQL::PL2SQL::Node->new( $xmlnodekey, $xmlnode,
                [ $parentxmlnodekey, $parentxmlnode ], $globals = {} ) ;

  my @text = stringsplit( $text ) ;

  my $node = $nodes[0]->stringfactory( %nvp_args ) ;

  my $reftype = $nodes[0]->reference( $refsource_sql ) ;

  my $ref = $nodes[0]->memory() ;

  my $parentid = $nodes[0]->parentid() ;

  my $sql = $nodes[0]->sql( $dsn ) ;


The following sequence of operation describes how NoSQL::PL2SQL::Node objects are used and when their methods are called:

1. An object that implements NoSQL::PL2SQL starts out as an ordinary PL type complex data structure. That object is converted into a tree of NoSQL::PL2SQL::Node objects and written into an RDB table; each node correlates to a table record. NoSQL::PL2SQL::Node represents the PL -> SQL phase.

2. During the next metamorphosis, the node records are read from the RDB table and converted to NoSQL::PL2SQL::Object nodes. When these nodes are tied, the result is indistinguishable from the original object. NoSQL::PL2SQL::Object represents the SQL -> PL phase.

3. After the object has been modified, some of the tree nodes are NoSQL::PL2SQL::Object's and others are untied vanilla PL data structures. When DESTROYed, the PL data elements are converted piecemeal into NoSQL::PL2SQL::Node's and written with the other records until the next iteration.

Phase 1 operation is executed with a single call to the factory method: First, the object is converted into a XML::Parser::Nodes tree using XML::Parser::Nodes->pl2xml(). Each node in this tree is converted using the xml2sql() function, which calls the new() constructor after recursing through the child nodes. (Consquently, the top node is last.)

The resulting set of nodes is passed through the combine() function. XML::Parser::Nodes->pl2xml() creates an extra data node for every container node. combine() combines these two nodes and returns a smaller set, which are passed into insertall(). insertall() does the hard work of converting child pointers into RDB references, as it calls the sql() method of each Node.

During the Phase 1 operation, insertall() encapsulates all the complexity required to link the nodes. During the Phase 3 operation, insertall() is run separately for each untied PL element, and needs to accomodate existing links. The process for determining those link values is encapsulated within the NoSQL::PL2SQL::Object package instead.

In phase 3, factory() only performs the first step of converting a PL element into a set of Nodes. The <combine()> and <insertall()> functions are called externally, and some of insertall()'s internal data is passed back to the caller.

stringsplit() and stringfactory() are called by the new() constructor. The stringsplit() function splits arbitrary string $text into contingent 512 character substrings, or smaller. The stringfactory() method returns a new Node object by cloning the XML member. The new object's SQL member is defined by the %nvp_args.

reference(), memory() and parentid() are called by insertall() to access a Node's internal properties.

A PL2SQL object may contain internal references- essentially, a child node is shared among several contaner nodes. (Scalar references are a bit more complex.) The reference() performs a little extra houskeeping to ensure consistency.

The memory() method returns the XML memory_address attribute, which indicates shared references.

The parentid() method returns one of a variety of attributes to determine nodes that are siblings.

Each Node has an sql and an xml member. The sql member is an associative array that matches the data structure of an RDB table record. The xml member is an internal pointer to an XML::Parser::Nodes structure.


None by default.



Original version; created by h2xs 1.23 with options


Cleaned perldoc formatting issues


Fixed bug: stringsplit() converted 0 length strings to undefined


Fixed bug: insertall() updating deleted records broke scalar chains


insertall() more durable approach for 0.04


insertall() initializes the deleted and intdata properties of the header node sql record.


Added %scalars to insertall() method. Needs to be separate from the %refs set.




Jim Schueler, <jim@tqis.com>


Copyright (C) 2012 by Jim Schueler

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.9 or, at your option, any later version of Perl 5 you may have available.