<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:php="http://snowboards-for-sale.com/ns/phpxb"
  xmlns:mysql="http://snowboards-for-sale.com/ns/mysqlxb"
  >
<xsl:output
  method="text"
  omit-xml-declaration="yes"
  encoding="UTF-8"
  media-type="text/plain"
/>

<xsl:template match ="/">
<xsl:variable name="classname" select="/xsd:schema/xsd:element[1]//php:className"/>
<xsl:text>&lt;?php
/**
*@author Dave Gullo: $
*$Generated-date: __DATE__ $
*$Scheminator-XSL: ___XSL___ $
*/
</xsl:text>
require_once "Cachable.php";
require_once "DBXMLObject.php";

class <xsl:value-of select="$classname"/> extends DBXMLObject implements Cachable {
  private $debug = false;
  protected $lastmodified;  //-= Member of the Cachable interface
  protected $classname = '<xsl:value-of select="/xsd:schema/xsd:element[1]/@name"/>';  //-= Magic variable not returned by the Reflection API (TBD)???
  public $id;
  <xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element">
  <xsl:value-of select=".//php:visibility"/><xsl:text> $</xsl:text><xsl:value-of select="@name"/>;
  </xsl:for-each> 
  
  function <xsl:value-of select="$classname"/>($id = null) {
    $this->setSchema("http://snowboards-for-sale.com/xsd/<xsl:value-of select="$classname"/>.xsd");
    parent::DBXMLObject(); //-= Init our DB
    if (isset($id)) {
      self::init("CALL <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.get<xsl:value-of select="$classname"/>(". $this->db->escape($id) .")");
    }
  } 

  //-= Implementation of abstract method DBXMLObject::save()
  function save() {
    <xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[xsd:simpleType/xsd:restriction/xsd:pattern]">
    //-= Perform pattern matching for `<xsl:value-of select="@name"/>`
    if (!eregi("<xsl:value-of select="xsd:simpleType/xsd:restriction/xsd:pattern/@value"/>", $this-><xsl:value-of select="@name"/>)) {
      throw new Exception("Unable to save() $this->classname, pattern facet failed: /<xsl:value-of select="xsd:simpleType/xsd:restriction/xsd:pattern/@value"/>/");
    }
    </xsl:for-each><!--
-->if (isset($this->id) &amp;&amp; strlen($this->id) > 0) {
      //-= This is already in the database, perform an UPDATE...
      $sql = "CALL <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.update<xsl:value-of select="$classname"/>(
        $this->id,
<xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]"><!--
-->        ". $this->db->nullIfEmpty($this-><xsl:value-of select="@name"/>) ."<xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))">,
</xsl:if></xsl:for-each>
      )";
      $this->db->getQuery($sql);
    } else {
      //-= This is a brand new instance, INSERT into the database...
      $sql = "CALL <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.insert<xsl:value-of select="$classname"/>(
<xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]"><!--
-->        ". $this->db->nullIfEmpty($this-><xsl:value-of select="@name"/>) ."<xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))">,
</xsl:if></xsl:for-each>
      )";
      $result = mysqli_fetch_object($this->db->getQuery($sql));
      self::__construct($result-><xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/>);
    }
    if ($this->debug) echo $sql;
  }

  //-= Cachable interface implementation
  function isCachable() {
    return true;
  }
  function getLastModified() {
    $result = $this->db->getObject("CALL <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.lastmod<xsl:value-of select="$classname"/>(". (int)$this->id .")");
    return $result->lastmodified;
  }
  function setLastModified($date) {
    if ((int)$date > 0) {
      $this->lastmodified = $date;
    } else {
      throw new Exception("<xsl:value-of select="$classname"/>:setLastModified() expects an integer-based timestamp!");
    }
    $this->db->getQuery("CALL <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.touch<xsl:value-of select="$classname"/>(". (int)$this->id .")");
  }

  //-= Your custom methods go here, and will be merged in via CVS when this class gets re-autogenerated...
}
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
  switch ($_REQUEST['action']) {
    case 'procs':
      require_once "Database.php";
      $db = new Database();
      $db->getQuery("DROP PROCEDURE IF EXISTS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.get<xsl:value-of select="$classname"/>");
      $sql = "
CREATE PROCEDURE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.get<xsl:value-of select="$classname"/>(IN id int)
BEGIN
  SELECT
    <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/> AS id, 
    UNIX_TIMESTAMP(<xsl:value-of select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:attribute[@name = 'lastmodified']//mysql:columnName"/>) AS lastmodified, /* satifies the Cachable interface */
    <xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element">
      <xsl:value-of select=".//mysql:columnName"/> AS <xsl:value-of select="@name"/><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element))">,<xsl:text>
    </xsl:text></xsl:if>
    </xsl:for-each>
  FROM <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:tableName"/>
  WHERE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/> = id; 
END
";
      $db->getQuery($sql);
      $db->getQuery("DROP PROCEDURE IF EXISTS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.update<xsl:value-of select="$classname"/>");
      $sql = "
CREATE PROCEDURE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.update<xsl:value-of select="$classname"/>(
  IN id int,
<xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]"><!--
-->  IN in_<xsl:value-of select=".//mysql:columnName"/><xsl:text> </xsl:text><xsl:value-of select=".//mysql:datatype"/><!--
  --><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))">,
</xsl:if>
</xsl:for-each>
)
BEGIN
  UPDATE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:tableName"/> SET
    <xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]">
    <xsl:value-of select=".//mysql:columnName"/> = in_<xsl:value-of select=".//mysql:columnName"/><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))"><xsl:text>,
    </xsl:text></xsl:if>
</xsl:for-each>
  WHERE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/> = id;
END
";
      $db->getQuery($sql);
      $db->getQuery("DROP PROCEDURE IF EXISTS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.insert<xsl:value-of select="$classname"/>");
      $sql = "
CREATE PROCEDURE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.insert<xsl:value-of select="$classname"/>(
<xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]"><!--
-->  IN in_<xsl:value-of select=".//mysql:columnName"/><xsl:text> </xsl:text><xsl:value-of select=".//mysql:datatype"/><!--
  --><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))"><xsl:text>,
</xsl:text>
    </xsl:if>
</xsl:for-each>
)
BEGIN
  INSERT INTO <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:tableName"/>(
    <xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]">
    <xsl:value-of select=".//mysql:columnName"/><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))"><xsl:text>,
    </xsl:text></xsl:if>
  </xsl:for-each>
  ) VALUES (
<xsl:for-each select="/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]"><!--
-->    in_<xsl:value-of select=".//mysql:columnName"/><xsl:if test="not(position() = count(/xsd:schema/xsd:element[1]/xsd:complexType/xsd:all/xsd:element[not(xsd:annotation/xsd:appinfo/php:transient)]))"><xsl:text>,
</xsl:text></xsl:if>
</xsl:for-each>
  );
  SELECT last_insert_id() AS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/>; 
END
";
      $db->getQuery($sql);
      $db->getQuery("DROP PROCEDURE IF EXISTS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.touch<xsl:value-of select="$classname"/>");
      $sql = "
CREATE PROCEDURE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.touch<xsl:value-of select="$classname"/>(IN id int)
BEGIN
  UPDATE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:tableName"/> SET lastmodified = now() WHERE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/> = id;
END
      ";
      $db->getQuery($sql);
      //-= Depending on the composite nature of this entity, this may take into consideration
      //-= children objects and relationships.
      $db->getQuery("DROP PROCEDURE IF EXISTS <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.lastmod<xsl:value-of select="$classname"/>");
      $sql = "
CREATE PROCEDURE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.lastmod<xsl:value-of select="$classname"/>(IN id int)
BEGIN
  SELECT lastmodified FROM <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:database"/>.<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:tableName"/>  WHERE <xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:primaryKey"/> = id;
END
      ";
      $db->getQuery($sql);
      header("Content-type: text/xml");
      echo $db->getXMLFromSQL("CALL procs()", 'procs')->saveXML(); 
      break;
    default:<!--
  --><xsl:if test="/xsd:schema/xsd:element[1]//mysql:testKey &gt; 0">
      //-= Default test case is to toXML using max(primarykey) from tablename
      $o = new <xsl:value-of select="$classname"/>(<xsl:value-of select="/xsd:schema/xsd:element[1]//mysql:testKey"/>);
      header("Content-type: text/xml");
      echo $o->toXML();
      break;
  </xsl:if>
  }
}
?></xsl:template>

</xsl:transform>
