VCL
[ class tree: VCL ] [ index: VCL ] [ all elements ]

Source for file db.inc.php

Documentation is available at db.inc.php

  1. <?php
  2. /**
  3. *  This file is part of the VCL for PHP project
  4. *
  5. *  Copyright (c) 2004-2007 qadram software <support@qadram.com>
  6. *
  7. *  Checkout AUTHORS file for more information on the developers
  8. *
  9. *  This library is free software; you can redistribute it and/or
  10. *  modify it under the terms of the GNU Lesser General Public
  11. *  License as published by the Free Software Foundation; either
  12. *  version 2.1 of the License, or (at your option) any later version.
  13. *
  14. *  This library is distributed in the hope that it will be useful,
  15. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. *  Lesser General Public License for more details.
  18. *
  19. *  You should have received a copy of the GNU Lesser General Public
  20. *  License along with this library; if not, write to the Free Software
  21. *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  22. *  USA
  23. *
  24. */
  25.  
  26. use_unit("classes.inc.php");
  27. use_unit("rtl.inc.php");
  28.  
  29.  
  30. /**
  31.  * Field class
  32.  *
  33.  * Encapsulates a table field
  34.  */
  35. class Field extends Object
  36. {
  37.         private $_fieldname;
  38.         private $_displaylabel;
  39.  
  40.         //Fieldname property
  41.         
  42.         function getFieldName(return $this->_fieldname;     }
  43.         function setFieldName($value$this->_fieldname=$value}
  44.  
  45.         //DisplayLabel property
  46.         
  47.         function getDisplayLabel(return $this->_displaylabel;       }
  48.         function setDisplayLabel($value$this->_displaylabel=$value}
  49. }
  50.  
  51. /*
  52. * CustomConnection, a common ancestor for all Connection objects
  53. */
  54. class CustomConnection extends Component
  55. {
  56.  
  57.     protected $_datasets=null;
  58.     protected $_fstreamedconnected=false;
  59.  
  60.     /*
  61.     * List of attached DataSets
  62.     *
  63.     * @return collection
  64.     */
  65.     function readDataSets(return $this->_datasets}
  66.     function writeDataSets($value$this->_datasets=$value}
  67.     function defaultDataSets(return null}
  68.  
  69.     protected $_clients=null;
  70.  
  71.     /**
  72.     * Returns the fieldnames for the table
  73.     * @param string $tablename Table to get the fields for
  74.     * @return array 
  75.     */
  76.     function MetaFields($tablename)
  77.     {
  78.     }
  79.  
  80.     /**
  81.     * Begins a transaction
  82.     */
  83.     function BeginTrans()
  84.     {
  85.         //To be overriden
  86.     }
  87.  
  88.     /**
  89.     * Completes a transaction
  90.     * @param bool $autocomplete If true, the transaction will be commited, if false, will be rolled back
  91.     */
  92.     function CompleteTrans($autocomplete=true)
  93.     {
  94.         //To be overriden
  95.     }
  96.  
  97.  
  98.  
  99.     /*
  100.     * Send a connect event to all the datasets, both for connecting and disconnecting
  101.     * @param $connecting boolean specifies the status of the connection
  102.     */
  103.     function SendConnectEvent($connecting)
  104.     {
  105.         for($i=0;$i<=$this->_clients->count()-1;$i++)
  106.         {
  107.             $client=$this->_clients->items[$i];
  108.             if ($client->inheritsFrom('DataSet'))
  109.             {
  110.                 $client->DataEvent(deConnectChange$connecting);
  111.             }
  112.         }
  113.     }
  114.  
  115.     /**
  116.     * Returns a date formatted to be used on this database, depending on the type
  117.     * @param string $input Date to convert
  118.     * @return string 
  119.     */
  120.     function DBDate($input)
  121.     {
  122.         return($input);
  123.     }
  124.  
  125.     /**
  126.     * Prepares the query, to optimize it
  127.     * @param string $query SQL sentence to be prepared
  128.     */
  129.     function Prepare($query)
  130.     {
  131.  
  132.     }
  133.  
  134.     /**
  135.     * Returns a parameter formatted depending on the database type
  136.     * @param string $input Parameter name
  137.     * @return string 
  138.     */
  139.     function Param($input)
  140.     {
  141.         return($input);
  142.     }
  143.  
  144.     /**
  145.     * Quote a string depending on the database type
  146.     */
  147.     function QuoteStr($input)
  148.     {
  149.         return($input);
  150.     }
  151.  
  152.     /**
  153.     * Returns the clients of this database
  154.     * @return collection 
  155.     */
  156.     function readClients(return $this->_clients}
  157.     function writeClients($value$this->_clients=$value}
  158.     function defaultClients(return null}
  159.  
  160.     protected $_onafterconnect=null;
  161.  
  162.     /**
  163.     * Fired after the database is connected
  164.     */
  165.     function readOnAfterConnect(return $this->_onafterconnect}
  166.     function writeOnAfterConnect($value$this->_onafterconnect=$value}
  167.     function defaultOnAfterConnect(return null}
  168.  
  169.     protected $_onbeforeconnect=null;
  170.  
  171.     /**
  172.     * Fired before the database is connected
  173.     */
  174.     function readOnBeforeConnect(return $this->_onbeforeconnect}
  175.     function writeOnBeforeConnect($value$this->_onbeforeconnect=$value}
  176.     function defaultOnBeforeConnect(return null}
  177.  
  178.     protected $_onafterdisconnect=null;
  179.  
  180.     /**
  181.     * Fired after the database is disconnected
  182.     */
  183.     function readOnAfterDisconnect(return $this->_onafterdisconnect}
  184.     function writeOnAfterDisconnect($value$this->_onafterdisconnect=$value}
  185.     function defaultOnAfterDisconnect(return null}
  186.  
  187.     protected $_onbeforedisconnect=null;
  188.  
  189.     /**
  190.     * Fired before the database is disconnected
  191.     */
  192.     function readOnBeforeDisconnect(return $this->_onbeforedisconnect}
  193.     function writeOnBeforeDisconnect($value$this->_onbeforedisconnect=$value}
  194.     function defaultOnBeforeDisconnect(return null}
  195.  
  196.     protected $_onlogin=null;
  197.  
  198.     /**
  199.     * Fired when requesting login information for this database
  200.     */
  201.     function readOnLogin(return $this->_onlogin}
  202.     function writeOnLogin($value$this->_onlogin=$value}
  203.     function defaultOnLogin(return null}
  204.  
  205.         function __construct($aowner=null)
  206.         {
  207.                 //Calls inherited constructor
  208.                 parent::__construct($aowner);
  209.  
  210.                 $this->_datasets=new Collection();
  211.                 $this->_clients=new Collection();
  212.         }
  213.  
  214.         /**
  215.         * Open the database
  216.         */
  217.         function Open()
  218.         {
  219.             $this->Connected=true;
  220.         }
  221.  
  222.  
  223.         /**
  224.         * Close the database
  225.         */
  226.         function Close()
  227.         {
  228.             $this->Connected=false;
  229.         }
  230.  
  231.  
  232.         function loaded()
  233.         {
  234.                 parent::loaded();
  235.                 if ($this->_fstreamedconnected)
  236.                 {
  237.                     $this->Connected=true;
  238.                 }
  239.         }
  240.  
  241.         /**
  242.         * Determines if the database is connected or not
  243.         *
  244.         * @return boolean 
  245.         */
  246.         function readConnected(return "0"}
  247.         function writeConnected($value)
  248.         {
  249.             if (($this->ControlState csLoading)==csLoading)
  250.             {
  251.                 $this->_fstreamedconnected=$value;
  252.             }
  253.             else
  254.             {
  255.                 if ($value == $this->readConnected())
  256.                 {
  257.                 }
  258.                 else
  259.                 {
  260.                     if ($value)
  261.                     {
  262.                         $this->callEvent("onbeforeconnect",array());
  263.                         $this->DoConnect();
  264.                         $this->SendConnectEvent(true);
  265.                         $this->callEvent("onafterconnect",array());
  266.                     }
  267.                     else
  268.                     {
  269.                         $this->callEvent("onbeforedisconnect",array());
  270.                         $this->SendConnectEvent(false);
  271.                         $this->DoDisconnect();
  272.                         $this->callEvent("onafterdisconnect",array());
  273.                     }
  274.                 }
  275.             }
  276.         }
  277.         function defaultConnected(return "0"}
  278.  
  279.         /**
  280.         * Place here the connection code
  281.         */
  282.         function DoConnect()
  283.         {
  284.             //Override this
  285.         }
  286.  
  287.         /**
  288.         * Place here the disconnection code
  289.         */
  290.         function DoDisconnect()
  291.         {
  292.             //Override this
  293.         }
  294. }
  295.  
  296.  
  297. /**
  298.  * DataSet class
  299.  *
  300.  * Base class to encapsulate a data set
  301.  */
  302. /*
  303. class DataSet extends Component
  304. {
  305.         public $fields=null;
  306.         private $_limitstart='0';
  307.         private $_limitcount='10';
  308.  
  309.         //LimitStart property
  310.         function getLimitStart() { return $this->_limitstart;   }
  311.         function setLimitStart($value) { $this->_limitstart=$value;     }
  312.         function defaultLimitStart() { return "0"; }
  313.  
  314.         function getLimitCount() { return $this->_limitcount;   }
  315.         function setLimitCount($value) { $this->_limitcount=$value; }
  316.         function defaultLimitCount() { return "10"; }
  317.  
  318.         function __construct($aowner=null)
  319.         {
  320.                 //Calls inherited constructor
  321.                 parent::__construct($aowner);
  322.  
  323.                 $this->fields=new Collection();
  324.         }
  325.  
  326.         function dumpContents()
  327.         {
  328.                 //Dump here code if any
  329.         }
  330.  
  331.         function readFields()
  332.         {
  333.         }
  334.  
  335.         function readFieldValues()
  336.         {
  337.         }
  338.  
  339.         function first()
  340.         {
  341.         }
  342.  
  343.         function next()
  344.         {
  345.         }
  346.         
  347.         function eof()
  348.         {
  349.         }
  350.         
  351.         function __get($nm)
  352.   {
  353.   }
  354.   
  355.   function __set($nm, $val)
  356.   {
  357.   }
  358.  
  359. }
  360. */
  361.  
  362. define('deFieldChange',1);
  363. define('deRecordChange',2);
  364. define('deDataSetChange',3);
  365. define('deDataSetScroll',4);
  366. define('deLayoutChange',5);
  367. define('deUpdateRecord',6);
  368. define('deUpdateState',7);
  369. define('deCheckBrowseMode',8);
  370. define('dePropertyChange',9);
  371. define('deFieldListChange',10);
  372. define('deFocusControl',11);
  373. define('deParentScroll',12);
  374. define('deConnectChange',13);
  375. define('deReconcileError',14);
  376. define('deDisabledStateChange',15);
  377.  
  378. define('dsInactive'    ,1);
  379. define('dsBrowse'      ,2);
  380. define('dsEdit'        ,3);
  381. define('dsInsert'      ,4);
  382. define('dsSetKey'      ,5);
  383. define('dsCalcFields'  ,6);
  384. define('dsFilter'      ,7);
  385. define('dsNewValue'    ,8);
  386. define('dsOldValue'    ,9);
  387. define('dsCurValue'    ,10);
  388. define('dsBlockRead'   ,11);
  389. define('dsInternalCalc',12);
  390. define('dsOpening'     ,13);
  391.  
  392. /**
  393. * Exception for a DatabaseError
  394. */
  395. class EDatabaseError extends Exception }
  396.  
  397. /**
  398. * Function to raise a Database Error
  399. @param string $message Message of the exception to show
  400. @param Component $component Component is raising the exception
  401. */
  402. function DatabaseError($message$component=null)
  403. {
  404.   if ((assigned($component)) && ($component->Name != ''))
  405.   {
  406.     throw new EDatabaseError(sprintf('%s: %s'$component->Name$message));
  407.   }
  408.   else
  409.   {
  410.     throw new EDatabaseError($message);
  411.   }
  412. }
  413.  
  414. /**
  415. * DataSet component, base class to inherit and create dataset components
  416. */
  417. class DataSet extends Component
  418. {
  419.         protected $_limitstart='0';
  420.         protected $_limitcount='10';
  421.  
  422.         /**
  423.         * Defines the starting record to filter the dataset with
  424.         */
  425.         function getLimitStart(return $this->_limitstart;   }
  426.         function setLimitStart($value$this->_limitstart=$value;     }
  427.         function defaultLimitStart(return "0"}
  428.  
  429.         /**
  430.         * Defines how many records will be shown
  431.         */
  432.         function getLimitCount(return $this->_limitcount;   }
  433.         function setLimitCount($value$this->_limitcount=$value}
  434.         function defaultLimitCount(return "10"}
  435.  
  436.         /**
  437.         * Override this method to perform the closing of the dataset
  438.         */
  439.         function InternalClose({}
  440.  
  441.         /**
  442.         * Override this method to handle exceptions
  443.         */
  444.         function InternalHandleException({}
  445.  
  446.         /**
  447.         * Override this method to init field definitions
  448.         */
  449.         function InternalInitFieldDefs({}
  450.  
  451.         /**
  452.         * Override this method to perform the opening of the dataset
  453.         */
  454.         function InternalOpen({}
  455.  
  456.         /**
  457.         * Override this method to return if the cursor is open or not
  458.         * @return boolean 
  459.         */
  460.         function IsCursorOpen({}
  461.  
  462.         /**
  463.         * This property returns an array with the field names and values
  464.         * @return array 
  465.         */
  466.         function readFields(return array()}
  467.  
  468.         /**
  469.         * Specifies how many fields has the dataset
  470.         *
  471.         * @return integer 
  472.         */
  473.         function readFieldCount(return 0}
  474.  
  475.         /**
  476.         * Buffer to hold values for searching/filtering
  477.         */
  478.         public $fieldbuffer=array();
  479.  
  480.         protected $_recordcount=0;
  481.         protected $_state=dsInactive;
  482.         protected $_modified=false;
  483.         protected $_InternalOpenComplete=false;
  484.         protected $_DefaultFields=false;
  485.         protected $_DisableCount=0;
  486.  
  487.         protected $_datasetfield=null;
  488.  
  489.         function readDataSetField(return $this->_datasetfield}
  490.         function writeDataSetField($value$this->_datasetfield=$value}
  491.         function defaultDataSetField(return null}
  492.  
  493.         /**
  494.         * Specifies the state of the dataset, i.e. dsNone, dsEdit, etc
  495.         * @return enum 
  496.         */
  497.         function readState(return $this->_state}
  498.         function writeState($value$this->_state=$value}
  499.         function defaultState(return dsInactive}
  500.  
  501.         protected $_mastersource=null;
  502.  
  503.         protected $_masterfields=array();
  504.  
  505.         /**
  506.         * Specifies the associations with fields on this dataset and fields on the dataset attached to the MasterSource property
  507.         * @return array 
  508.         */
  509.         function readMasterFields(return $this->_masterfields}
  510.         function writeMasterFields($value$this->_masterfields=$value}
  511.         function defaultMasterFields(return array()}
  512.  
  513.         /**
  514.         * Specifies the dataset is going to act as master for this datasource
  515.         * @return object 
  516.         */
  517.         function readMasterSource(return $this->_mastersource;   }
  518.         function writeMasterSource($value)
  519.         {
  520.                 $this->_mastersource=$this->fixupProperty($value);
  521.         }
  522.  
  523.         protected $_recno=0;
  524.  
  525.         /**
  526.         * Specifies the current record number
  527.         * @return integer 
  528.         */
  529.         function readRecNo(return $this->_recno}
  530.         function writeRecNo($value)
  531.         {
  532.             if ($value!=$this->_recno)
  533.             {
  534.                 $diff=$value-$this->_recno;
  535.                 if ($diff>0)
  536.                 {
  537.                     $this->MoveBy($diff);
  538.                 }
  539.                 $this->_recno=$value;
  540.             }
  541.         }
  542.         function defaultRecNo(return 0}
  543.  
  544.         protected $_reckey=array();
  545.  
  546.         /**
  547.         * Specifies the record key for thid dataset
  548.         *
  549.         * @return array 
  550.         */
  551.         function readRecKey(return $this->_reckey}
  552.         function writeRecKey($value$this->_reckey=$value}
  553.         function defaultRecKey(return ""}
  554.  
  555.         function serialize()
  556.         {
  557.                 parent::serialize();
  558.  
  559.                 $owner $this->readOwner();
  560.                 if ($owner != null)
  561.                 {
  562.                         $prefix $owner->readNamePath().".".$this->_name.".";
  563.                         $_SESSION[$prefix."State"$this->_state;
  564. //                        $_SESSION[$prefix."FieldBuffer"] = serialize($this->fieldbuffer);
  565. //                        if (!empty($this->_regkey))
  566. //                        {
  567. //                            $_SESSION[$prefix."RegKey"] = serialize($this->_regkey);
  568. //                        }
  569. //                        $_SESSION[$prefix."RegKey"] = serialize($this->_regkey);
  570. //                        $_SESSION[$prefix."RecNo"] = $this->_recno;
  571.                 }
  572.         }
  573.  
  574.         function unserialize()
  575.         {
  576.                 parent::unserialize();
  577.                 $owner $this->readOwner();
  578.                 if ($owner != null)
  579.                 {
  580.                         $prefix $owner->readNamePath().".".$this->_name.".";
  581.                         if (isset($_SESSION[$prefix."State"])) $this->_state$_SESSION[$prefix."State"];
  582. //                        if (isset($_SESSION[$prefix."FieldBuffer"])) $this->fieldbuffer= unserialize($_SESSION[$prefix."FieldBuffer"]);
  583. //                        if (isset($_SESSION[$prefix."RegKey"])) $this->_regkey= unserialize($_SESSION[$prefix."RegKey"]);
  584. //                        if (isset($_SESSION[$prefix."RecNo"]))
  585. //                        {
  586. //                            $this->RecNo= $_SESSION[$prefix."RecNo"];
  587. //                        }
  588.                 }
  589.         }
  590.  
  591.         /**
  592.         * Specifies if the dataset has been modified or not
  593.         * @return boolean 
  594.         */
  595.         function readModified(return $this->_modified}
  596.         function writeModified($value$this->_modified=$value}
  597.         function defaultModified(return false}
  598.  
  599.         protected $_canmodify=true;
  600.  
  601.         /**
  602.         * Specifies if the dataset can be modified or not
  603.         * @return boolean 
  604.         */
  605.         function readCanModify(return $this->_canmodify}
  606.         function writeCanModify($value$this->_canmodify=$value}
  607.         function defaultCanModify(return true}
  608.  
  609.         protected $_onbeforeopen=null;
  610.  
  611.         /**
  612.         * Fired before the dataset is open
  613.         */
  614.         function readOnBeforeOpen(return $this->_onbeforeopen}
  615.         function writeOnBeforeOpen($value$this->_onbeforeopen=$value}
  616.         function defaultOnBeforeOpen(return null}
  617.  
  618.         protected $_onafteropen=null;
  619.  
  620.         /**
  621.         * Fired after the dataset is open
  622.         */
  623.         function readOnAfterOpen(return $this->_onafteropen}
  624.         function writeOnAfterOpen($value$this->_onafteropen=$value}
  625.         function defaultOnAfterOpen(return null}
  626.  
  627.         protected $_onbeforeclose=null;
  628.  
  629.         /**
  630.         * Fired before the dataset is closed
  631.         */
  632.         function readOnBeforeClose(return $this->_onbeforeclose}
  633.         function writeOnBeforeClose($value$this->_onbeforeclose=$value}
  634.         function defaultOnBeforeClose(return null}
  635.  
  636.         protected $_onafterclose=null;
  637.  
  638.         /**
  639.         * Fired after the dataset is closed
  640.         */
  641.         function readOnAfterClose(return $this->_onafterclose}
  642.         function writeOnAfterClose($value$this->_onafterclose=$value}
  643.         function defaultOnAfterClose(return null}
  644.  
  645.         protected $_onbeforeinsert=null;
  646.  
  647.         /**
  648.         * Fired before a record is inserted
  649.         */
  650.         function readOnBeforeInsert(return $this->_onbeforeinsert}
  651.         function writeOnBeforeInsert($value$this->_onbeforeinsert=$value}
  652.         function defaultOnBeforeInsert(return null}
  653.  
  654.         protected $_onafterinsert=null;
  655.  
  656.         /**
  657.         * Fired after a record is inserted
  658.         */
  659.         function readOnAfterInsert(return $this->_onafterinsert}
  660.         function writeOnAfterInsert($value$this->_onafterinsert=$value}
  661.         function defaultOnAfterInsert(return null}
  662.  
  663.         protected $_onbeforeedit=null;
  664.  
  665.         /**
  666.         * Fired before the dataset enters in edit mode
  667.         */
  668.         function readOnBeforeEdit(return $this->_onbeforeedit}
  669.         function writeOnBeforeEdit($value$this->_onbeforeedit=$value}
  670.         function defaultOnBeforeEdit(return null}
  671.  
  672.         protected $_onafteredit=null;
  673.  
  674.         /**
  675.         * Fired after the dataset enters in edito mode
  676.         */
  677.         function readOnAfterEdit(return $this->_onafteredit}
  678.         function writeOnAfterEdit($value$this->_onafteredit=$value}
  679.         function defaultOnAfterEdit(return null}
  680.  
  681.         protected $_onbeforepost=null;
  682.  
  683.         /**
  684.         * Fired before a record is posted
  685.         */
  686.         function readOnBeforePost(return $this->_onbeforepost}
  687.         function writeOnBeforePost($value$this->_onbeforepost=$value}
  688.         function defaultOnBeforePost(return null}
  689.  
  690.         protected $_onafterpost=null;
  691.  
  692.         /**
  693.         * Fired after a record is posted
  694.         */
  695.         function readOnAfterPost(return $this->_onafterpost}
  696.         function writeOnAfterPost($value$this->_onafterpost=$value}
  697.         function defaultOnAfterPost(return null}
  698.  
  699.         protected $_onbeforecancel=null;
  700.  
  701.         /**
  702.         * Fired before changes are cancelled
  703.         */
  704.         function readOnBeforeCancel(return $this->_onbeforecancel}
  705.         function writeOnBeforeCancel($value$this->_onbeforecancel=$value}
  706.         function defaultOnBeforeCancel(return null}
  707.  
  708.         protected $_onaftercancel=null;
  709.  
  710.         /**
  711.         * Fired after changes are cancelled
  712.         */
  713.         function readOnAfterCancel(return $this->_onaftercancel}
  714.         function writeOnAfterCancel($value$this->_onaftercancel=$value}
  715.         function defaultOnAfterCancel(return null}
  716.  
  717.         protected $_onbeforedelete=null;
  718.  
  719.         /**
  720.         * Fired before a record is deleted
  721.         */
  722.         function readOnBeforeDelete(return $this->_onbeforedelete}
  723.         function writeOnBeforeDelete($value$this->_onbeforedelete=$value}
  724.         function defaultOnBeforeDelete(return null}
  725.  
  726.         protected $_onafterdelete=null;
  727.  
  728.         /**
  729.         * Fired after a record is deleted
  730.         */
  731.         function readOnAfterDelete(return $this->_onafterdelete}
  732.         function writeOnAfterDelete($value$this->_onafterdelete=$value}
  733.         function defaultOnAfterDelete(return null}
  734.  
  735.         protected $_oncalcfields=null;
  736.  
  737.         function readOnCalcFields(return $this->_oncalcfields}
  738.         function writeOnCalcFields($value$this->_oncalcfields=$value}
  739.         function defaultOnCalcFields(return null}
  740.  
  741.         protected $_ondeleteerror=null;
  742.  
  743.         function readOnDeleteError(return $this->_ondeleteerror}
  744.         function writeOnDeleteError($value$this->_ondeleteerror=$value}
  745.         function defaultOnDeleteError(return null}
  746.  
  747.         protected $_filter="";
  748.  
  749.         /**
  750.         * Specifies the filter to apply to this dataset
  751.         * @return string 
  752.         */
  753.         function readFilter(return $this->_filter}
  754.         function writeFilter($value)
  755.         {
  756.             if ($value!=$this->_filter)
  757.             {
  758.                 //$this->Close();
  759.                 $this->_filter=$value;
  760.                 //$this->Open();
  761.             }
  762.         }
  763.         function defaultFilter(return ""}
  764.  
  765.  
  766.  
  767.         protected $_onfilterrecord=null;
  768.  
  769.         function readOnFilterRecord(return $this->_onfilterrecord}
  770.         function writeOnFilterRecord($value$this->_onfilterrecord=$value}
  771.         function defaultOnFilterRecord(return null}
  772.  
  773.         protected $_onnewrecord=null;
  774.  
  775.         function readOnNewRecord(return $this->_onnewrecord}
  776.         function writeOnNewRecord($value$this->_onnewrecord=$value}
  777.         function defaultOnNewRecord(return null}
  778.  
  779.         protected $_onposterror=null;
  780.  
  781.         function readOnPostError(return $this->_onposterror}
  782.         function writeOnPostError($value$this->_onposterror=$value}
  783.         function defaultOnPostError(return null}
  784.  
  785.  
  786.         /**
  787.         * Checks if an specific operation can be made, if not, calls $ErrorEvent
  788.         * @param string $Operation Operation to perform on the dataset
  789.         * @param string $ErrorEvent Event to call if there is any error
  790.         */
  791.         function CheckOperation($Operation$ErrorEvent)
  792.         {
  793.             $Done false;
  794.             do
  795.             {
  796.                 try
  797.                 {
  798. //                $this->UpdateCursorPos();
  799.                   $this->$Operation();
  800.                   $Done=true;
  801.                 }
  802.                 catch (EDatabaseError $e)
  803.                 {
  804.                     $Action=daFail;
  805.                     $Action=$this->callEvent($ErrorEventarray('Exception'=>$e'Action'=>$Action));
  806.                     if ($Action==daFailthrow $e;
  807.                     if ($Action==daAbortAbort();
  808.                 }
  809.  
  810.             }
  811.             while(!$Done);
  812.         }
  813.         //***********************
  814.  
  815.         
  816.  
  817.         /**
  818.         * Used to notify attached datasets about an specific event
  819.         * @param integer $event Event to notify
  820.         * @param array $info Info for the event
  821.         */
  822.         function DataEvent($event$info)
  823.         {
  824.             $NotifyDataSources !(($this->ControlsDisabled()) || ($this->State == dsBlockRead));
  825.  
  826.             switch($event)
  827.             {
  828.             /*
  829.     deFieldChange:
  830.       begin
  831.         if TField(Info).FieldKind in [fkData, fkInternalCalc] then
  832.           SetModified(True);
  833.         UpdateCalcFields;
  834.       end;
  835.     deFieldListChange:
  836.       FieldList.Updated := False;
  837.     dePropertyChange:
  838.       FieldDefs.Updated := False;
  839.     deCheckBrowseMode:
  840.       CheckNestedBrowseMode;
  841.     deDataSetChange, deDataSetScroll:
  842.       NotifyDetails;
  843.     deLayoutChange:
  844.       begin
  845.         FieldList.Updated := False;
  846.         if ControlsDisabled then
  847.           FEnableEvent := deLayoutChange;
  848.       end;
  849.     deUpdateState:
  850.       if ControlsDisabled then
  851.       begin
  852.         Event := deDisabledStateChange;
  853.         Info := Integer(State <> dsInactive);
  854.         NotifyDataSources := True;
  855.         FEnableEvent := deLayoutChange;
  856.       end;
  857.       */
  858.       }
  859.         /*
  860.         if ($NotifyDataSources)
  861.         {
  862.             for I := 0 to FDataSources.Count - 1 do
  863.               TDataSource(FDataSources[I]).DataEvent(Event, Info);
  864.         }
  865.         */
  866.         }
  867.  
  868.         /**
  869.         * Checks if the dataset is active, if not, raises an exception
  870.         */
  871.         function CheckActive()
  872.         {
  873.             if ($this->State == dsInactiveDatabaseError(_("Cannot perform this operation on a closed dataset")$this);
  874.         }
  875.  
  876.         /**
  877.         * Checks if the dataset can be modified, if not, raises an exception
  878.         */
  879.         function CheckCanModify()
  880.         {
  881.             if (!$this->CanModifyDatabaseError(_("Cannot modify a read-only dataset"Self));
  882.         }
  883.  
  884.         /**
  885.         * Returns if attached controls are disabled
  886.         * @return boolean 
  887.         */
  888.         function ControlsDisabled()
  889.         {
  890.             return($this->_DisableCount!=0);
  891.         }
  892.  
  893.         /**
  894.         * Disables controls attached to the datasource
  895.         */
  896.         function DisableControls()
  897.         {
  898.             if ($this->_DisableCount == 0)
  899.             {
  900.                 $this->_DisableState=$this->State;
  901.                 $this->_EnableEvent=deDataSetChange;
  902.             }
  903.             $this->_DisableCount++;
  904.         }
  905.  
  906.         /**
  907.         * Enable controls attached to the datasource
  908.         */
  909.         function EnableControls()
  910.         {
  911.             if ($this->_DisableCount!=0)
  912.             {
  913.                 $this->_DisableCount--;
  914.                 if ($this->_DisableCount==0)
  915.                 {
  916.                     if ($this->_DisableState!=$this->State$this->DataEvent(deUpdateState0);
  917.                     if (($this->_DisableState!=dsInactive&& ($this->_State != dsInactive)) $this->DataEvent($this->_EnableEvent0);
  918.                 }
  919.             }
  920.         }
  921.  
  922.         /**
  923.         * Clear buffers associated with the dataset
  924.         */
  925.         function ClearBuffers()
  926.         {
  927.             $this->_recordcount = 0;
  928. //            $this->_activerecord = 0;
  929. //            $this->_currentrecord = -1;
  930.             $this->_bof = true;
  931.             $this->_eof = true;
  932.             $this->fieldbuffer=array();
  933.         }
  934.  
  935.         /**
  936.         * Begins an insert/append operation
  937.         */
  938.         function BeginInsertAppend()
  939.         {
  940.             $this->CheckBrowseMode();
  941.             $this->CheckCanModify();
  942.             $this->callEvent('onbeforeinsert'array());
  943.             $this->CheckParentState();
  944.         }
  945.  
  946.         /**
  947.         * Finishes an insert/append operation
  948.         */
  949.         function EndInsertAppend()
  950.         {
  951.             $this->State=dsInsert;
  952.             try
  953.             {
  954.                 $this->callEvent('onnewrecord',array());
  955.             }
  956.             catch (Exception $e)
  957.             {
  958.                 $this->UpdateCursorPos();
  959.                 $this->FreeFieldBuffers();
  960.                 $this->State=dsBrowse;
  961.                 throw $e;
  962.             }
  963.             $this->_modified = false;
  964.             $this->DataEvent(deDataSetChange0);
  965.             $this->callEvent('onafterinsert',array());
  966.         }
  967.  
  968.         function __construct($aowner=null)
  969.         {
  970.                 //Calls inherited constructor
  971.                 parent::__construct($aowner);
  972.         }
  973.  
  974.         /**
  975.         * Inserts a record on the dataset
  976.         */
  977.         function Insert()
  978.         {
  979.             $this->BeginInsertAppend();
  980.             //OldCurrent := Bookmark;
  981.             //MoveBuffer(FRecordCount, FActiveRecord);
  982.             //Buffer := ActiveBuffer;
  983.             //InitRecord(Buffer);
  984.             //if FRecordCount = 0 then
  985.             //SetBookmarkFlag(Buffer, bfBOF) else
  986.             //SetBookmarkData(Buffer, Pointer(OldCurrent));
  987.             //if FRecordCount < FBufferCount then Inc(FRecordCount);
  988.             $this->InternalInsert();
  989.             $this->EndInsertAppend();
  990.         }
  991.  
  992.         /**
  993.         * Appends a record to the dataset
  994.         */
  995.         function Append()
  996.         {
  997.                 $this->BeginInsertAppend();
  998.                 $this->ClearBuffers();
  999.                 $this->InitRecord(Buffer);
  1000.                 $this->_recordcount = 1;
  1001.                 $this->_bof = False;
  1002. //                $this->GetPriorRecords();
  1003.                 $this->InternalInsert();
  1004.                 $this->EndInsertAppend();
  1005.         }
  1006.  
  1007.         /**
  1008.         * Cancel changes performed on the current record
  1009.         */
  1010.         function Cancel()
  1011.         {
  1012.             switch($this->State)
  1013.             {
  1014.                 case dsEdit:
  1015.                 case dsInsert:
  1016.                 {
  1017.                     $this->DataEvent(deCheckBrowseMode0);
  1018.                     $this->callEvent("onbeforecancel",array());
  1019. //                    $DoScrollEvents = ($this->State == dsInsert);
  1020. //                    if ($DoScrollEvents) $this->DoBeforeScroll();
  1021. //                    $this->UpdateCursorPos();
  1022.                     $this->InternalCancel();
  1023.                     $this->fieldbuffer=array();
  1024.                     $this->State=dsBrowse;
  1025.                     //$this->Resync([]);
  1026.                     $this->callEvent("onaftercancel",array());
  1027. //                    if ($DoScrollEvents) $this->DoAfterScroll();
  1028.                     break;
  1029.                 }
  1030.             }
  1031.         }
  1032.  
  1033.         /**
  1034.         * Updates the current record
  1035.         */
  1036.         function UpdateRecord()
  1037.         {
  1038.             if (($this->State!=dsEdit&& ($this->State!=dsInsert&& ($this->State!=dsSetKey)) DatabaseError(_("Dataset not in edit or insert mode")$this);
  1039.             $this->DataEvent(deUpdateRecord,0);
  1040.         }
  1041.  
  1042.         /**
  1043.         * Checks if the dataset is in browse mode or not
  1044.         */
  1045.         function CheckBrowseMode()
  1046.         {
  1047.             $this->CheckActive();
  1048.             $this->DataEvent(deCheckBrowseMode0);
  1049.             switch($this->State)
  1050.             {
  1051.                 case dsEdit:
  1052.                 case dsInsert:
  1053.                 {
  1054.                     $this->UpdateRecord();
  1055.                     if ($this->Modified$this->post();
  1056.                     else $this->cancel();
  1057.                     break;
  1058.                 }
  1059.                 case dsSetKey:
  1060.                 {
  1061.                     $this->post();
  1062.                     break;
  1063.                 }
  1064.             }
  1065.         }
  1066.  
  1067.         /**
  1068.         * Closes the dataset
  1069.         */
  1070.         function Close()
  1071.         {
  1072.             $this->Active=false;
  1073.         }
  1074.  
  1075.         /**
  1076.         * Deletes a record on the dataset, depending on the values set in the buffer
  1077.         */
  1078.         function Delete()
  1079.         {
  1080.             $this->CheckActive();
  1081.             if (($this->State==dsInsert|| ($this->State==dsSetKey)) $this->Cancel();
  1082.             else
  1083.             {
  1084.                 if ($this->Recordcount==0DatabaseError(_("Cannot perform this operation on an empty dataset")Self);
  1085.                 $this->DataEvent(deCheckBrowseMode0);
  1086.                 $this->callevent("onbeforedelete",array());
  1087.                 $this->CheckOperation("InternalDelete""ondeleteerror");
  1088.                 $this->fieldbuffer=array();
  1089.                 $this->State=dsBrowse;
  1090.                 $this->callevent("onafterdelete",array());
  1091.             }
  1092.         }
  1093.  
  1094.         /**
  1095.         * Sets the parent dataset in edit state
  1096.         */
  1097.         function CheckParentState()
  1098.         {
  1099.             if ($this->DataSetField != null$this->DataSetField->DataSet->Edit();
  1100.         }
  1101.  
  1102.         /**
  1103.         * Sets the dataset in edit mode, modifications will go to a buffer waiting for post()/cancel()
  1104.         */
  1105.         function Edit()
  1106.         {
  1107.             if ((($this->State==dsEdit|| ($this->State==dsInsert)))
  1108.             {
  1109.             }
  1110.             else
  1111.             {
  1112. //                if ($this->_recordcount==0) $this->Insert();
  1113. //                else
  1114. //                {
  1115.                     $this->CheckBrowseMode();
  1116.                     $this->CheckCanModify();
  1117.                     $this->callevent("onbeforeedit",array());
  1118.                     $this->CheckParentState();
  1119.                     $this->CheckOperation("InternalEdit""onediterror");
  1120. //                    $this->GetCalcFields(ActiveBuffer);
  1121.                     $this->State=dsEdit;
  1122.                     $this->DataEvent(deRecordChange0);
  1123.                     $this->callevent("onafteredit",array());
  1124. //                }
  1125.             }
  1126.         }
  1127.  
  1128.         /**
  1129.         * Specifies how many records holds this dataset
  1130.         * @return integer 
  1131.         */
  1132.         function readRecordCount()
  1133.         {
  1134.             return $this->_recordcount;
  1135.         }
  1136.         function defaultRecordCount(return 0}
  1137.  
  1138.  
  1139.         /**
  1140.         * Moves the internal pointer of the dataset to the first record
  1141.         */
  1142.         function First()
  1143.         {
  1144.             $this->CheckBrowseMode();
  1145.             $FReopened false;
  1146.             /*
  1147.             if IsUniDirectional then begin
  1148.                 if not BOF then begin             // Need to Close and Reopen dataset: (Midas)
  1149.                     Active := False;
  1150.                     Active := True;
  1151.                 end;
  1152.                 FReopened := True
  1153.             end
  1154.             else ClearBuffers;
  1155.             */
  1156.             $this->ClearBuffers();
  1157.             try
  1158.             {
  1159.                 $this->InternalFirst();
  1160.                 //if not FReopened then begin
  1161.                 //$this->GetNextRecord();
  1162.                 //$this->GetNextRecords();
  1163.                 //end;
  1164.             }
  1165.             catch (Exception $e)
  1166.             {
  1167.                 $this->_bof = true;
  1168.                 $this->DataEvent(deDataSetChange0);
  1169.                 throw $e;
  1170.             }
  1171.  
  1172.             $this->_bof = true;
  1173.             $this->DataEvent(deDataSetChange0);
  1174.         }
  1175.  
  1176.         /**
  1177.         * Performs an internal open of the dataset
  1178.         */
  1179.         function DoInternalOpen()
  1180.         {
  1181.             $this->_DefaultFields = ($this->FieldCount == 0);
  1182.             $this->InternalOpen();
  1183.             $this->_InternalOpenComplete = true;
  1184.             //$this->UpdateBufferCount();
  1185.             $this->_bof = true;
  1186.         }
  1187.  
  1188.         /**
  1189.         * Opens the cursor for the dataset
  1190.         * @param boolean $InfoQuery If true, initialize internal field defs
  1191.         */
  1192.         function OpenCursor($InfoQueryFalse)
  1193.         {
  1194.             if ($InfoQuery$this->InternalInitFieldDefs();
  1195.             else if ($this->State!=dsOpening$this->DoInternalOpen();
  1196.         }
  1197.  
  1198.         /**
  1199.         * Opens the cursor for this dataset
  1200.         */
  1201.         function OpenCursorComplete()
  1202.         {
  1203.             try
  1204.             {
  1205.                 if ($this->State == dsOpening$this->DoInternalOpen();
  1206.             }
  1207.             catch(Exception $e)
  1208.             {
  1209.                 if ($this->_InternalOpenComplete)
  1210.                 {
  1211.                     $this->State=dsBrowse;
  1212.                     $this->callEvent("onafteropen"array());
  1213.                 }
  1214.                 else
  1215.                 {
  1216.                     $this->State=dsInactive;
  1217.                     $this->CloseCursor();
  1218.                 }
  1219.                 throw $e;
  1220.             }
  1221.             if ($this->_InternalOpenComplete)
  1222.             {
  1223.                 if ($this->_state==dsInactive$this->_state=dsBrowse;
  1224.                 $this->callEvent("onafteropen"array());
  1225.             }
  1226.             else
  1227.             {
  1228.                 $this->State=dsInactive;
  1229.                 $this->CloseCursor();
  1230.             }
  1231.         }
  1232.  
  1233.         /**
  1234.         * Close the cursor for this dataset
  1235.         */
  1236.         function CloseCursor()
  1237.         {
  1238. //            BlockReadSize := 0;
  1239.             $this->_InternalOpenComplete = false;
  1240. //            FreeFieldBuffers;
  1241. //            ClearBuffers;
  1242. //            SetBufListSize(0);
  1243.             $this->InternalClose();
  1244. //            FBufferCount := 0;
  1245. //            FDefaultFields := False;
  1246.         }
  1247.  
  1248.         /**
  1249.         * To be overriden to perform a first() operation
  1250.         */
  1251.         function InternalFirst()
  1252.         {
  1253.         }
  1254.  
  1255.         /**
  1256.         * To be overriden to perform a last() operation
  1257.         */
  1258.         function InternalLast()
  1259.         {
  1260.         }
  1261.  
  1262.         /**
  1263.         * To initialize the current record
  1264.         * @param array $Buffer Initial values
  1265.         */
  1266.         function InitRecord($Buffer)
  1267.         {
  1268.             $this->InternalInitRecord($Buffer);
  1269. //            $this->ClearCalcFields($Buffer);
  1270. //            $this->SetBookmarkFlag($Buffer, bfInserted);
  1271.         }
  1272.  
  1273.         function InternalInitRecord($buffer)
  1274.         {
  1275.         }
  1276.  
  1277.         function InternalAddRecord($buffer$append)
  1278.         {
  1279.         }
  1280.  
  1281.         /**
  1282.         * To be overriden to perform a delete() operation
  1283.         */
  1284.         function InternalDelete()
  1285.         {
  1286.         }
  1287.  
  1288.         /**
  1289.         * To be overriden to perform a post() operation
  1290.         */
  1291.         function InternalPost()
  1292.         {
  1293. //            $this->CheckRequiredFields();
  1294.         }
  1295.  
  1296.         /**
  1297.         * To be overriden to perform a cancel() operation
  1298.         */
  1299.         function InternalCancel()
  1300.         {
  1301.         }
  1302.  
  1303.         /**
  1304.         * To be overriden to perform a edit() operation
  1305.         */
  1306.         function InternalEdit()
  1307.         {
  1308.         }
  1309.  
  1310.         /**
  1311.         * To be overriden to perform a insert() operation
  1312.         */
  1313.         function InternalInsert()
  1314.         {
  1315.         }
  1316.  
  1317.         /**
  1318.         * To be overriden to perform a refresh() operation
  1319.         */
  1320.         function InternalRefresh()
  1321.         {
  1322.         }
  1323.  
  1324.         /**
  1325.         * Moves the internal pointer to the last record on the dataset
  1326.         */
  1327.         function Last()
  1328.         {
  1329.             //$this->CheckBiDirectional();
  1330.             $this->CheckBrowseMode();
  1331.             $this->ClearBuffers();
  1332.             try
  1333.             {
  1334.                 $this->InternalLast();
  1335. //                $this->GetPriorRecord();
  1336. //                $this->GetPriorRecords();
  1337.             }
  1338.             catch (Exception $e)
  1339.             {
  1340.                 $this->_eof = true;
  1341.                 $this->DataEvent(deDataSetChange0);
  1342.                 throw $e;
  1343.             }
  1344.  
  1345.             $this->_eof = true;
  1346.             $this->DataEvent(deDataSetChange0);
  1347.         }
  1348.  
  1349.         /**
  1350.         * Refresh the dataset by opening and closing
  1351.         */
  1352.         function Refresh()
  1353.         {
  1354.             $this->Active=false;
  1355.             $this->Active=true;
  1356.         }
  1357.  
  1358.         /**
  1359.         * Moves the internal pointer to the next record
  1360.         */
  1361.         function Next()
  1362.         {
  1363. //            if ($this->BlockReadSize > 0) $this->BlockReadNext();
  1364. //            else
  1365.               $this->MoveBy(1);
  1366.               if (!$this->EOF$this->fieldbuffer=$this->_rs->fields;
  1367.         }
  1368.  
  1369.         /**
  1370.         * Open the dataset
  1371.         */
  1372.         function Open()
  1373.         {
  1374.             $this->Active=true;
  1375.         }
  1376.  
  1377.         /**
  1378.         * Updates or Inserts a record, depending on the current state of the dataset
  1379.         */
  1380.         function Post()
  1381.         {
  1382.             $this->UpdateRecord();
  1383.             switch ($this->State)
  1384.             {
  1385.                 case dsEdit:
  1386.                 case dsInsert:
  1387.                 {
  1388.                     $this->DataEvent(deCheckBrowseMode0);
  1389.                     $this->callevent("onbeforepost",array());
  1390.                     $this->CheckOperation("InternalPost""onposterror");
  1391.                     $this->fieldbuffer=array();
  1392.                     //$this->FreeFieldBuffers();
  1393.                     $this->State=dsBrowse;
  1394.                     $this->callevent("onafterpost",array());
  1395.                     break;
  1396.                 }
  1397.             }
  1398.         }
  1399.  
  1400.         /**
  1401.         * Move the internal pointer by an specific distance
  1402.         * @param integer $distance Records to move the pointer
  1403.         */
  1404.         function MoveBy($distance)
  1405.         {
  1406.             $this->_recno+=$distance;
  1407.         }
  1408.  
  1409.         /**
  1410.         * Moves the pointer one record before
  1411.         */
  1412.         function Prior()
  1413.         {
  1414.             $this->MoveBy(-1);
  1415.         }
  1416.  
  1417.         /**
  1418.         * Specifies if the dataset is active or not
  1419.         * @return boolean 
  1420.         */
  1421.         function readActive()
  1422.         {
  1423.             if (($this->State==dsInactive|| ($this->State==dsOpening|| ($this->_rs==null))
  1424.             {
  1425.                 return(0);
  1426.             }
  1427.             else return(true);
  1428.         }
  1429.  
  1430.         protected $_fstreamedactive=false;
  1431.  
  1432.         function loaded()
  1433.         {
  1434.             parent::loaded();
  1435.             $this->writeMasterSource($this->_mastersource);
  1436.             if ($this->_fstreamedactive)
  1437.             {
  1438.                 $this->Active=true;
  1439.             }
  1440.         }
  1441.  
  1442.         function writeActive($value)
  1443.         {
  1444.             if (($this->ControlState csLoading)==csLoading)
  1445.             {
  1446.                 $this->_fstreamedactive=$value;
  1447.             }
  1448.             else
  1449.             {
  1450.                 if ($this->Active != $value)
  1451.                 {
  1452.                     if ($value==true)
  1453.                     {
  1454.                         $this->callevent("onbeforeopen",array());
  1455.                         try
  1456.                         {
  1457.                             $this->OpenCursor();
  1458.                             if ($this->State!=dsOpening)
  1459.                             {
  1460.                                 $this->OpenCursorComplete();
  1461.                             }
  1462.                         }
  1463.                         catch (Exception $e)
  1464.                         {
  1465.                             if ($this->State!=dsOpening)
  1466.                             {
  1467.                                 $this->OpenCursorComplete();
  1468.                             }
  1469.                             throw $e;
  1470.                         }
  1471.                     }
  1472.                     else
  1473.                     {
  1474.                         $this->callevent("onbeforeclose",array());
  1475.                         $this->State=dsInactive;
  1476.                         $this->CloseCursor();
  1477.                         $this->callevent("onafterclose",array());
  1478.                     }
  1479.                 }
  1480.             }
  1481.         }
  1482.  
  1483.         function defaultActive(return "0"}
  1484.  
  1485.  
  1486.         protected $_bof=false;
  1487.         protected $_eof=false;
  1488.  
  1489.         /**
  1490.         * If true, the pointer is at the beginning of the buffer
  1491.         * @return boolean 
  1492.         */
  1493.         function readBOF(return $this->_bof}
  1494.         function defaultBOF(return false}
  1495.  
  1496.         /**
  1497.         * If true, the pointer is at the last record of the buffer
  1498.         * @return boolean 
  1499.         */
  1500.         function readEOF(return $this->_eof}
  1501.         function defaultEOF(return false}
  1502. }
  1503.  
  1504. /**
  1505.  * Datasource class
  1506.  *
  1507.  * A class to link controls with datasets
  1508.  */
  1509. class Datasource extends Component
  1510. {
  1511.         protected $_dataset;
  1512.  
  1513.         function __construct($aowner=null)
  1514.         {
  1515.                 //Calls inherited constructor
  1516.                 parent::__construct($aowner);
  1517.         }
  1518.  
  1519.         /**
  1520.         * Dataset this Datasource is attached to
  1521.         * @return DataSet 
  1522.         */
  1523.         function getDataSet(return $this->_dataset}
  1524.         function setDataSet($value)
  1525.         {
  1526.                 $this->_dataset=$this->fixupProperty($value);
  1527.         }
  1528.  
  1529.         function loaded()
  1530.         {
  1531.                 parent::loaded();
  1532.                 $this->setDataSet($this->_dataset);
  1533.         }
  1534. }
  1535.  
  1536. ?>

Documentation generated on Tue, 27 Mar 2007 13:34:09 +0200 by phpDocumentor 1.3.1