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-2008 qadram software S.L. <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. define('daFail','daFail');
  30. define('daAbort','daAbort');
  31.  
  32.  
  33. /**
  34.  * Encapsulates a table field
  35.  *
  36.  * This class is used to encapsulate the name of a table field and the caption
  37.  * to be shown on data-aware component.
  38.  *
  39.  */
  40. class Field extends Object
  41. {
  42.         private $_fieldname;
  43.         private $_displaylabel;
  44.  
  45.         /**
  46.         * Indicates the name of the physical column in the underlying table or query result to which a field component is bound.
  47.         *
  48.         * Use FieldName to specify which field in the underlying dataset the field component represents. FieldName is used when
  49.         * displaying references to the field to users, unless a DisplayLabel has been set.
  50.         *
  51.         * @see getDisplayLabel()
  52.         * @return string 
  53.         */
  54.         function getFieldName(return $this->_fieldname;     }
  55.         function setFieldName($value$this->_fieldname=$value}
  56.  
  57.         /**
  58.         * Contains the text to display in the corresponding column heading of a data grid.
  59.         *
  60.         * Use DisplayLabel to assign column headings to a data grid. The column headings of the data grid use
  61.         * the DisplayName property of the field whose value they represent. Setting DisplayLabel changes the
  62.         * read-only DisplayName property from FieldName to the string specified as DisplayLabel.
  63.         *
  64.         * @see getFieldName()
  65.         * @return string 
  66.         */
  67.         function getDisplayLabel(return $this->_displaylabel;       }
  68.         function setDisplayLabel($value$this->_displaylabel=$value}
  69. }
  70.  
  71. /**
  72.  * CustomConnection, a common ancestor for all Connection objects
  73.  *
  74.  * A connection must represent the object which through data objects (tables, queries, etc) perform
  75.  * their operations. Components like Database inherit from CustomConnection and implement the right
  76.  * functionality.
  77.  *
  78.  */
  79. class CustomConnection extends Component
  80. {
  81.  
  82.     protected $_datasets=null;
  83.     protected $_fstreamedconnected=false;
  84.  
  85.     /**
  86.     * Provides an indexed array of all active datasets for a database component.
  87.     *
  88.     * Use DataSets to access active datasets associated with a database component. An active dataset is one that is currently open.
  89.     *
  90.     * @see readClients()
  91.     * @return Collection 
  92.     */
  93.     function readDataSets(return $this->_datasets}
  94.     function writeDataSets($value$this->_datasets=$value}
  95.     function defaultDataSets(return null}
  96.  
  97.     protected $_clients=null;
  98.  
  99.     /**
  100.     * Returns the fieldnames for the table
  101.     *
  102.     * Use this method to get an array with the fieldnames for an specific table.
  103.     * This method can be useful if you want to explore the structure of a table.
  104.     *
  105.     * @param string $tablename Table to get the fields for
  106.     *
  107.     * @return array Array with fieldnames for $tablename
  108.     */
  109.     function MetaFields($tablename)
  110.     {
  111.     }
  112.  
  113.     /**
  114.     * Begins a new transaction against the database server.
  115.     *
  116.     * Call BeginTrans to begin a new transaction against the database server.
  117.     *
  118.     * Updates, insertions, and deletions that take place after a call to StartTransaction
  119.     * are held by the server until an application calls CompleteTrans with true to commit the changes
  120.     * or false to Rollback
  121.     *
  122.     * @see completeTrans()
  123.     */
  124.     function BeginTrans()
  125.     {
  126.         //To be overriden
  127.     }
  128.  
  129.     /**
  130.     * Permanently stores updates, insertions, and deletions of data associated with
  131.     * the current transaction, and ends the current transactions, but
  132.     * if false is sent in the autocomplete parameter, then a rollback is performed
  133.     * and then Cancels all updates, insertions, and deletions for the current
  134.     * transaction and ends the transaction.
  135.     *
  136.     * Call CompleteTrans to permanently store to the database server all updates,
  137.     * insertions, and deletions of data associated with the current transaction and
  138.     * then end the transaction. The current transaction is the last transaction
  139.     * started by calling BeginTrans.
  140.     *
  141.     * If you send false on the autocomplete parameter, then it cancels all updates,
  142.     * insertions, and deletions for the current transaction and to end the transaction.
  143.     * The current transaction is the last transaction started by calling BeginTrans.
  144.     *
  145.     * @see beginTrans()
  146.     *
  147.     * @param bool $autocomplete If true, the transaction will be commited, if false, will be rolled back
  148.     * @return bool 
  149.     */
  150.     function CompleteTrans($autocomplete=true)
  151.     {
  152.         //To be overriden
  153.     }
  154.  
  155.  
  156.  
  157.     /**
  158.     * Send a connect event to all the datasets, both for connecting and disconnecting
  159.     *
  160.     * This is an internal method used to fire a dataset connect event to all attached
  161.     * datasets.
  162.     *
  163.     * @see DataSet::dataEvent()
  164.     *
  165.     * @param $connecting boolean specifies the status of the connection
  166.     */
  167.     function SendConnectEvent($connecting)
  168.     {
  169.         for($i=0;$i<=$this->_clients->count()-1;$i++)
  170.         {
  171.             $client=$this->_clients->items[$i];
  172.             if ($client->inheritsFrom('DataSet'))
  173.             {
  174.                 $client->DataEvent(deConnectChange$connecting);
  175.             }
  176.         }
  177.     }
  178.  
  179.     /**
  180.     * Returns a date formatted to be used on this database, depending on the type
  181.     *
  182.     * You must use this method to get a data formatted in a valid format depending
  183.     * on the type of database.
  184.     *
  185.     * @see param(), quoteStr()
  186.     *
  187.     * @param string $input Date to convert
  188.     * @return string Date converted to a valid format
  189.     */
  190.     function DBDate($input)
  191.     {
  192.         return($input);
  193.     }
  194.  
  195.     /**
  196.     * Sends a query to the server for optimization prior to execution.
  197.     *
  198.     * Call Prepare to have a remote database server allocate resources for the
  199.     * query and to perform additional optimizations.
  200.     *
  201.     * If the query will only be executed once, the application does not need to
  202.     * explicitly call Prepare. Executing an unprepared query generates these
  203.     * calls automatically. However, if the same query is to be executed repeatedly,
  204.     * it is more efficient to prevent these automatic calls by calling Prepare
  205.     * explicitly.
  206.     *
  207.     * @param string $query SQL sentence to be prepared
  208.     */
  209.     function Prepare($query)
  210.     {
  211.  
  212.     }
  213.  
  214.     /**
  215.     * Returns a parameter formatted depending on the database type
  216.     *
  217.     * When writting parametrized queries, use this method to get a parameter formatted
  218.     * in a valid format for the current database type.
  219.     *
  220.     * @see DBDate(), QuoteStr()
  221.     *
  222.     * @param string $input Parameter name
  223.     * @return string $input converted to a valid parameter
  224.     */
  225.     function Param($input)
  226.     {
  227.         return($input);
  228.     }
  229.  
  230.     /**
  231.     * Quote a string depending on the database type
  232.     *
  233.     * When writting queries, use this method to get a string quoted in a format
  234.     * valid for the current database type.
  235.     *
  236.     * @see param(), dbDate()
  237.     *
  238.     * @param string $input String to quote
  239.     * @return string $input quoted with valid quotes
  240.     */
  241.     function QuoteStr($input)
  242.     {
  243.         return($input);
  244.     }
  245.  
  246.     /**
  247.     * Returns the clients of this database
  248.     *
  249.     * @see readDatasets()
  250.     *
  251.     * @return Collection 
  252.     */
  253.     function readClients(return $this->_clients}
  254.     function writeClients($value$this->_clients=$value}
  255.     function defaultClients(return null}
  256.  
  257.     protected $_onafterconnect=null;
  258.  
  259.     /**
  260.     * Occurs after a connection is established.
  261.     *
  262.     * Write an OnAfterConnect event handler to take application-specific
  263.     * actions immediately after the connection component opens a connection to
  264.     * the remote source of database information.
  265.     *
  266.     * @see readConnected(), readOnBeforeConnect()
  267.     *
  268.     * @return mixed 
  269.     */
  270.     function readOnAfterConnect(return $this->_onafterconnect}
  271.     function writeOnAfterConnect($value$this->_onafterconnect=$value}
  272.     function defaultOnAfterConnect(return null}
  273.  
  274.     protected $_onbeforeconnect=null;
  275.  
  276.     /**
  277.     * Occurs immediately before establishing a connection.
  278.     *
  279.     * Write a OnBeforeConnect event handler to take application-specific actions
  280.     * before the connection component opens a connection to the remote source of
  281.     * database information.
  282.     *
  283.     * @see readConnected(), readOnAfterConnect()
  284.     *
  285.     * @return mixed 
  286.     */
  287.     function readOnBeforeConnect(return $this->_onbeforeconnect}
  288.     function writeOnBeforeConnect($value$this->_onbeforeconnect=$value}
  289.     function defaultOnBeforeConnect(return null}
  290.  
  291.     protected $_oncustomconnect=null;
  292.  
  293.     function getOnCustomConnect(return $this->_oncustomconnect}
  294.     function setOnCustomConnect($value$this->_oncustomconnect=$value}
  295.     function defaultOnCustomConnect(return null}
  296.  
  297.     protected $_onafterdisconnect=null;
  298.  
  299.     /**
  300.     * Occurs after the connection closes.
  301.     *
  302.     * Write an OnAfterDisconnect event handler to take application-specific
  303.     * actions after the connection component drops a connection.
  304.     *
  305.     * @see readConnected(), readOnBeforeDisconnect()
  306.     *
  307.     * @return mixed 
  308.     */
  309.     function readOnAfterDisconnect(return $this->_onafterdisconnect}
  310.     function writeOnAfterDisconnect($value$this->_onafterdisconnect=$value}
  311.     function defaultOnAfterDisconnect(return null}
  312.  
  313.     protected $_onbeforedisconnect=null;
  314.  
  315.     /**
  316.     * Occurs immediately before the connection closes.
  317.     *
  318.     * Write a BeforeDisconnect event handler to take application-specific actions
  319.     * before dropping a connection.
  320.     *
  321.     * @see readConnected(), readOnAfterDisconnect()
  322.     *
  323.     * @return mixed 
  324.     */
  325.     function readOnBeforeDisconnect(return $this->_onbeforedisconnect}
  326.     function writeOnBeforeDisconnect($value$this->_onbeforedisconnect=$value}
  327.     function defaultOnBeforeDisconnect(return null}
  328.  
  329.     protected $_onlogin=null;
  330.  
  331.     /**
  332.     * Occurs when an application connects to a database.
  333.     *
  334.     * Write an OnLogin event handler to take specific actions when an application
  335.     * attempts to connect to a database.
  336.     *
  337.     * If there is no OnLogin event handler, the current UserName and Password are the ones used
  338.     * from the UserName and UserPassword properties.
  339.     *
  340.     * These values are then passed to the remote server.
  341.     *
  342.     * @return mixed 
  343.     */
  344.     function readOnLogin(return $this->_onlogin}
  345.     function writeOnLogin($value$this->_onlogin=$value}
  346.     function defaultOnLogin(return null}
  347.  
  348.         function __construct($aowner=null)
  349.         {
  350.                 //Calls inherited constructor
  351.                 parent::__construct($aowner);
  352.  
  353.                 $this->_datasets=new Collection();
  354.                 $this->_clients=new Collection();
  355.         }
  356.  
  357.         /**
  358.         * Opens the connection.
  359.         *
  360.         * Call Open to establish a connection to the remote source of database information.
  361.         * Open sets the Connected property to true.
  362.         *
  363.         * @see readConnected(), close()
  364.         */
  365.         function Open()
  366.         {
  367.             $this->Connected=true;
  368.         }
  369.  
  370.  
  371.         /**
  372.         * Closes the connection.
  373.         *
  374.         * Call Close to disconnect from the remote source of database information.
  375.         * Before the connection component is deactivated, all associated datasets are
  376.         * closed. Calling Close is the same as setting the Connected property to false.
  377.         *
  378.         * @see readConnected(), open()
  379.         */
  380.         function Close()
  381.         {
  382.             $this->Connected=false;
  383.         }
  384.  
  385.  
  386.         function loaded()
  387.         {
  388.                 parent::loaded();
  389.                 if ($this->_fstreamedconnected)
  390.                 {
  391.                     $this->Connected=true;
  392.                 }
  393.         }
  394.  
  395.         /**
  396.         * Determines whether a connection has been established to the remote source of data.
  397.         *
  398.         * Set Connected to true to open the connection. Set Connected to false to terminate the connection.
  399.         *
  400.         * Setting Connected to true generates a OnBeforeConnect event, calls the protected
  401.         * DoConnect method to establish the connection, and generates an OnAfterConnect event.
  402.         * In addition, when setting Connected to true.
  403.         *
  404.         * Setting Connected to false generates a OnBeforeDisconnect event, calls the protected
  405.         * DoConnect method to drop the connection, and generates an OnAfterDisconnect event.
  406.         *
  407.         * When deriving custom connection components from CustomConnection, override readConnected to return
  408.         * true when a connection is established, and override DoConnect and DoDisconnect to create and drop
  409.         * the connection.
  410.         *
  411.         * @see Open(), Close()
  412.         * @return boolean 
  413.         */
  414.         function readConnected(return "0"}
  415.         function writeConnected($value)
  416.         {
  417.             if (($this->ControlState csLoading)==csLoading)
  418.             {
  419.                 $this->_fstreamedconnected=$value;
  420.             }
  421.             else
  422.             {
  423.                 if ($value == $this->readConnected())
  424.                 {
  425.                 }
  426.                 else
  427.                 {
  428.                     if ($value)
  429.                     {
  430.                         $this->callEvent("onbeforeconnect",array());
  431.                         $this->DoConnect();
  432.                         $this->SendConnectEvent(true);
  433.                         $this->callEvent("onafterconnect",array());
  434.                     }
  435.                     else
  436.                     {
  437.                         $this->callEvent("onbeforedisconnect",array());
  438.                         $this->SendConnectEvent(false);
  439.                         $this->DoDisconnect();
  440.                         $this->callEvent("onafterdisconnect",array());
  441.                     }
  442.                 }
  443.             }
  444.         }
  445.         function defaultConnected(return "0"}
  446.  
  447.         /**
  448.         * Provides the interface for a method that opens a connection.
  449.         *
  450.         * The Connected property uses DoConnect to establish a connection.
  451.         * Descendant classes override the DoConnect method to establish their
  452.         * connection as appropriate. As implemented in CustomConnection,
  453.         * DoConnect does nothing.
  454.         *
  455.         * @see open(), close(), readConnected()
  456.         */
  457.         function DoConnect()
  458.         {
  459.             //Override this
  460.         }
  461.  
  462.         /**
  463.         * Provides the interface for a method that terminates the connection.
  464.         *
  465.         * The Connected property uses DoDisconnect to close a connection.
  466.         * Descendant classes override the DoDisconnect method to drop a connection.
  467.         * As implemented in CustomConnection, DoDisconnect does nothing.
  468.         *
  469.         * @see open(), close(), readConnected()
  470.         */
  471.         function DoDisconnect()
  472.         {
  473.             //Override this
  474.         }
  475. }
  476.  
  477.  
  478. define('deFieldChange',1);
  479. define('deRecordChange',2);
  480. define('deDataSetChange',3);
  481. define('deDataSetScroll',4);
  482. define('deLayoutChange',5);
  483. define('deUpdateRecord',6);
  484. define('deUpdateState',7);
  485. define('deCheckBrowseMode',8);
  486. define('dePropertyChange',9);
  487. define('deFieldListChange',10);
  488. define('deFocusControl',11);
  489. define('deParentScroll',12);
  490. define('deConnectChange',13);
  491. define('deReconcileError',14);
  492. define('deDisabledStateChange',15);
  493.  
  494. define('dsInactive'    ,1);
  495. define('dsBrowse'      ,2);
  496. define('dsEdit'        ,3);
  497. define('dsInsert'      ,4);
  498. define('dsSetKey'      ,5);
  499. define('dsCalcFields'  ,6);
  500. define('dsFilter'      ,7);
  501. define('dsNewValue'    ,8);
  502. define('dsOldValue'    ,9);
  503. define('dsCurValue'    ,10);
  504. define('dsBlockRead'   ,11);
  505. define('dsInternalCalc',12);
  506. define('dsOpening'     ,13);
  507.  
  508. /**
  509. * Exception for a DatabaseError
  510. *
  511. * This exception is raised whenever a data access component generates an error.
  512. *
  513. @see DatabaseError
  514. */
  515. class EDatabaseError extends Exception }
  516.  
  517. /**
  518. * Function to raise a Database Error
  519. *
  520. * Call DatabaseError to raise an EDatabaseError exception, using Message as the text for the exception.
  521. * If a component is provided as the second parameter, the message is prefixed by the name of the component to help
  522. * in interpreting the error message.
  523. *
  524. * Calling DatabaseError rather than creating and raising the exception directly in code reduces the overall code size of the application.
  525. *
  526. @see EDatabaseError
  527. *
  528. @param string $message Message of the exception to show
  529. @param Component $component Component is raising the exception
  530. */
  531. function databaseError($message$component=null)
  532. {
  533.   if ((assigned($component)) && ($component->Name != ''))
  534.   {
  535.     throw new EDatabaseError(sprintf('%s: %s'$component->Name$message));
  536.   }
  537.   else
  538.   {
  539.     throw new EDatabaseError($message);
  540.   }
  541. }
  542.  
  543. /**
  544. * DataSet component, base class to inherit and create dataset components
  545. *
  546. * A DataSet is a collection of information, organized in rows and fields, and this class
  547. * implement the basic interface all data-aware components will use to show information.
  548. *
  549. * A DataSet is not attached to an specific source of information, you can, for example, create a
  550. * DataSet that provide information from a memory array.
  551. *
  552. */
  553. class DataSet extends Component
  554. {
  555.         protected $_limitstart='0';
  556.         protected $_limitcount='10';
  557.  
  558.         /**
  559.         * Defines the starting record to filter the dataset with
  560.         *
  561.         * Use this property to filter the dataset and to set which is the first
  562.         * record to be added to the set.
  563.         *
  564.         * @see getLimitCount()
  565.         *
  566.         * @return integer 
  567.         */
  568.         function getLimitStart(return $this->_limitstart;   }
  569.         function setLimitStart($value$this->_limitstart=$value;     }
  570.         function defaultLimitStart(return "0"}
  571.  
  572.         /**
  573.         * Defines how many records will be shown
  574.         *
  575.         * Use this property to set how many records do you want to get on the
  576.         * set, at max.
  577.         *
  578.         * @see getLimitStart()
  579.         *
  580.         * @return integer 
  581.         */
  582.         function getLimitCount(return $this->_limitcount;   }
  583.         function setLimitCount($value$this->_limitcount=$value}
  584.         function defaultLimitCount(return "10"}
  585.  
  586.         /**
  587.         * Override this method to perform the closing of the dataset
  588.         *
  589.         * This method is called internally by the engine to close the dataset.
  590.         * Is not intended to be called directly the component user.
  591.         *
  592.         * @see Close()
  593.         *
  594.         */
  595.         function internalClose({}
  596.  
  597.         /**
  598.         * Override this method to handle exceptions
  599.         *
  600.         * This method is called internally by the engine to handle an exception using
  601.         * the dataset.
  602.         *
  603.         * Is not intended to be called directly the component user.
  604.         */
  605.         function internalHandleException({}
  606.  
  607.         /**
  608.         * Override this method to init field definitions. Not used.
  609.         */
  610.         function internalInitFieldDefs({}
  611.  
  612.         /**
  613.         * Override this method to perform the opening of the dataset
  614.         *
  615.         * This method is called internally by the engine to open the dataset.
  616.         * Is not intended to be called directly the component user.
  617.         *
  618.         * @see open()
  619.         *
  620.         */
  621.         function internalOpen({}
  622.  
  623.         /**
  624.         * Override this method to return if the cursor is open or not
  625.         *
  626.         * This method is called internally by the engine to determine if the cursor
  627.         * is open or not.
  628.         *
  629.         * Is not intended to be called directly the component user.
  630.         *
  631.         * @return boolean True if cursor is open
  632.         */
  633.         function isCursorOpen({}
  634.  
  635.         /**
  636.         * This property returns an array with the field names and values
  637.         *
  638.         * Use Fields to access fields that make up this dataset.
  639.         * The order of field components in Fields corresponds directly to the
  640.         * order of columns in the table or tables underlying a dataset.
  641.         *
  642.         * Accessing fields with the Fields property is useful for applications that:
  643.         *
  644.         * Iterate over some or all fields in a dataset.
  645.         *
  646.         * Work with underlying tables whose internal data structure is unknown at runtime.
  647.         *
  648.         * If an application knows the data types of individual fields, then it can read
  649.         * or write individual field values through the Fields property.
  650.         *
  651.         * @return array 
  652.         */
  653.         function readFields(return array()}
  654.  
  655.         /**
  656.         * Indicates the number of field components associated with the dataset.
  657.         *
  658.         * Examine FieldCount to determine the number of fields listed by the Fields property.
  659.         *
  660.         * @return integer 
  661.         */
  662.         function readFieldCount(return 0}
  663.  
  664.         /**
  665.         * Buffer to hold values for searching/filtering
  666.         */
  667.         public $fieldbuffer=array();
  668.  
  669.         protected $_recordcount=0;
  670.         protected $_state=dsInactive;
  671.         protected $_modified=false;
  672.         protected $_InternalOpenComplete=false;
  673.         protected $_DefaultFields=false;
  674.         protected $_DisableCount=0;
  675.  
  676.         protected $_datasetfield=null;
  677.  
  678.         /**
  679.         * Indicates the persistent DataSetField object that owns a nested dataset.
  680.         *
  681.         * Not used.
  682.         *
  683.         * @return Field 
  684.         */
  685.         function readDataSetField(return $this->_datasetfield}
  686.         function writeDataSetField($value$this->_datasetfield=$value}
  687.         function defaultDataSetField(return null}
  688.  
  689.         /**
  690.         * Indicates the current operating mode of the dataset.
  691.         *
  692.         * Examine State to determine the current operating mode of the dataset.
  693.         * State determines what can be done with data in a dataset, such as editing
  694.         * existing records or inserting new ones. The dataset state constantly changes
  695.         * as an application processes data.
  696.         *
  697.         * Opening a dataset changes State from dsInactive to dsBrowse. An application
  698.         * can call Edit to put a dataset into dsEdit state, or call Insert to put a
  699.         * dataset into dsInsert state.
  700.         *
  701.         * Posting or canceling edits, insertions, or deletions, changes State from
  702.         * its current state to dsBrowse. Closing a dataset changes its state to dsInactive.
  703.         *
  704.         * @return enum 
  705.         */
  706.         function readState(return $this->_state}
  707.         function writeState($value$this->_state=$value}
  708.         function defaultState(return dsInactive}
  709.  
  710.         protected $_mastersource=null;
  711.  
  712.         protected $_masterfields=array();
  713.  
  714.         /**
  715.         * Specifies one or more fields in a master table to link with corresponding
  716.         * fields in this table in order to establish a master-detail relationship
  717.         * between the tables.
  718.         *
  719.         * Use MasterFields after setting the MasterSource property to specify the
  720.         * names of one or more fields to use in establishing a detail-master
  721.         * relationship between this table and the one specified in MasterSource.
  722.         *
  723.         * MasterFields is an array containing one or more field names in the master table.
  724.         *
  725.         * Each time the current record in the master table changes, the new values in
  726.         * those fields are used to select corresponding records in this table for display.
  727.         *
  728.         * @see readMasterSource()
  729.         *
  730.         * @return array 
  731.         */
  732.         function readMasterFields(return $this->_masterfields}
  733.         function writeMasterFields($value$this->_masterfields=$value}
  734.         function defaultMasterFields(return array()}
  735.  
  736.         /**
  737.         * Specifies the name of the data source for a dataset to use as a master
  738.         * table in establishing a detail-master relationship between this table and another one.
  739.         *
  740.         * Use MasterSource to specify the name of the data source component whose DataSet
  741.         * property identifies a dataset to use as a master table in establishing a detail-master
  742.         * relationship between this table and another one.
  743.         *
  744.         * Note: At design time choose an available data source from the MasterSource property’s
  745.         * drop-down list in the Object Inspector.
  746.         *
  747.         * After setting the MasterSource property, specify which fields to use in the master
  748.         * table by setting the MasterFields property. At runtime each time the current record
  749.         * in the master table changes, the new values in those fields are used to select corresponding
  750.         * records in this table for display.
  751.         *
  752.         * @see readMasterFields()
  753.         *
  754.         * @return DataSource 
  755.         */
  756.         function readMasterSource(return $this->_mastersource;   }
  757.         function writeMasterSource($value)
  758.         {
  759.                 $this->_mastersource=$this->fixupProperty($value);
  760.         }
  761.  
  762.         protected $_recno=0;
  763.  
  764.         /**
  765.         * Indicates the current record in the dataset.
  766.         *
  767.         * Examine RecNo to determine the record number of the current record in the dataset.
  768.         * Applications might use this property with RecordCount to iterate through all
  769.         * the records in a dataset, though typically record iteration is handled with calls
  770.         * to First, Last, MoveBy, Next, and Prior.
  771.         *
  772.         * @see readRecKey()
  773.         *
  774.         * @return integer 
  775.         */
  776.         function readRecNo(return $this->_recno}
  777.         function writeRecNo($value)
  778.         {
  779.             if ($value!=$this->_recno)
  780.             {
  781.                 $diff=$value-$this->_recno;
  782.                 if ($diff>0)
  783.                 {
  784.                     $this->MoveBy($diff);
  785.                 }
  786.                 $this->_recno=$value;
  787.             }
  788.         }
  789.         function defaultRecNo(return 0}
  790.  
  791.         protected $_reckey=array();
  792.  
  793.         /**
  794.         * Specifies the record key for this dataset
  795.         *
  796.         * This property specifies the fields and values that determine
  797.         * the key of a record.
  798.         *
  799.         * @see readRecNo()
  800.         *
  801.         * @return array 
  802.         */
  803.         function readRecKey(return $this->_reckey}
  804.         function writeRecKey($value$this->_reckey=$value}
  805.         function defaultRecKey(return ""}
  806.  
  807.         function serialize()
  808.         {
  809.                 parent::serialize();
  810.  
  811.                 $owner $this->readOwner();
  812.                 if ($owner != null)
  813.                 {
  814.                         $prefix $owner->readNamePath().".".$this->_name.".";
  815.                         $_SESSION[$prefix."State"$this->_state;
  816. //                        $_SESSION[$prefix."FieldBuffer"] = serialize($this->fieldbuffer);
  817. //                        if (!empty($this->_regkey))
  818. //                        {
  819. //                            $_SESSION[$prefix."RegKey"] = serialize($this->_regkey);
  820. //                        }
  821. //                        $_SESSION[$prefix."RegKey"] = serialize($this->_regkey);
  822. //                        $_SESSION[$prefix."RecNo"] = $this->_recno;
  823.                 }
  824.         }
  825.  
  826.         function unserialize()
  827.         {
  828.                 parent::unserialize();
  829.                 $owner $this->readOwner();
  830.                 if ($owner != null)
  831.                 {
  832.                         $prefix $owner->readNamePath().".".$this->_name.".";
  833.                         if (isset($_SESSION[$prefix."State"])) $this->_state$_SESSION[$prefix."State"];
  834. //                        if (isset($_SESSION[$prefix."FieldBuffer"])) $this->fieldbuffer= unserialize($_SESSION[$prefix."FieldBuffer"]);
  835. //                        if (isset($_SESSION[$prefix."RegKey"])) $this->_regkey= unserialize($_SESSION[$prefix."RegKey"]);
  836. //                        if (isset($_SESSION[$prefix."RecNo"]))
  837. //                        {
  838. //                            $this->RecNo= $_SESSION[$prefix."RecNo"];
  839. //                        }
  840.                 }
  841.         }
  842.  
  843.         /**
  844.         * Indicates whether the active record is modified.
  845.         *
  846.         * Check Modified to determine if the active record is modified. If Modified
  847.         * is true, the active record is modified. If false, the active record is not modified.
  848.         *
  849.         * Note: In general, an application need not check the status of Modified.
  850.         * Properties, events, and methods of TDataSet and its descendants that modify records
  851.         * generally check this status automatically and take appropriate actions based on its value.
  852.         *
  853.         * @see redCanModify()
  854.         *
  855.         * @return boolean 
  856.         */
  857.         function readModified(return $this->_modified}
  858.         function writeModified($value$this->_modified=$value}
  859.         function defaultModified(return false}
  860.  
  861.         protected $_canmodify=true;
  862.  
  863.         /**
  864.         * Indicates whether an application can insert, edit, and delete data in a table.
  865.         *
  866.         * Check the status of CanModify to determine if an application can modify a
  867.         * dataset in any way. If CanModify is true, the dataset can be modified. If
  868.         * CanModify is false, the table is read-only.
  869.         *
  870.         * CanModify is set automatically when an application opens a table. If the ReadOnly
  871.         * property of a table component is true, then CanModify is set to false.
  872.         *
  873.         * Note: Even if CanModify is true, it is not a guarantee that a user will be able
  874.         * to insert or update records in a table. Other factors may come in to play,
  875.         * for example, SQL access privileges.
  876.         *
  877.         * @see readModified()
  878.         *
  879.         * @return boolean 
  880.         */
  881.         function readCanModify(return $this->_canmodify}
  882.         function writeCanModify($value$this->_canmodify=$value}
  883.         function defaultCanModify(return true}
  884.  
  885.         protected $_onbeforeopen=null;
  886.  
  887.         /**
  888.         * Occurs before an application executes a request to open a dataset.
  889.         *
  890.         * Write a OnBeforeOpen event handler to take specific action before an
  891.         * application opens a dataset for viewing or editing. OnBeforeOpen is
  892.         * triggered when an application sets the Active property to true for
  893.         * a dataset or an application calls Open.
  894.         *
  895.         * @see readOnAfterOpen()
  896.         *
  897.         * @return mixed 
  898.         */
  899.         function readOnBeforeOpen(return $this->_onbeforeopen}
  900.         function writeOnBeforeOpen($value$this->_onbeforeopen=$value}
  901.         function defaultOnBeforeOpen(return null}
  902.  
  903.         protected $_onafteropen=null;
  904.  
  905.         /**
  906.         * Occurs after an application completes opening a dataset and before any data access occurs.
  907.         *
  908.         * Write an AfterOpen event handler to take specific action immediately after an
  909.         * application opens the dataset. AfterOpen is called after the dataset establishes
  910.         * access to its data and the dataset is put into dsBrowse state. For example,
  911.         * an AfterOpen event handler might check an ini file to determine the last record
  912.         * touched in the dataset the previous time the application ran, and position the
  913.         * dataset at that record.
  914.         *
  915.         * @see readOnBeforeOpen()
  916.         *
  917.         * @return mixed 
  918.         */
  919.         function readOnAfterOpen(return $this->_onafteropen}
  920.         function writeOnAfterOpen($value$this->_onafteropen=$value}
  921.         function defaultOnAfterOpen(return null}
  922.  
  923.         protected $_onbeforeclose=null;
  924.  
  925.         /**
  926.         * Occurs immediately before the dataset closes.
  927.         *
  928.         * Write a OnBeforeClose event to take specific action before an application
  929.         * closes a dataset. Calling Close or setting the Active property to false
  930.         * results in a call to the OnBeforeClose event handler.
  931.         *
  932.         * @see readOnAfterClose()
  933.         *
  934.         * @return mixed 
  935.         */
  936.         function readOnBeforeClose(return $this->_onbeforeclose}
  937.         function writeOnBeforeClose($value$this->_onbeforeclose=$value}
  938.         function defaultOnBeforeClose(return null}
  939.  
  940.         protected $_onafterclose=null;
  941.  
  942.         /**
  943.         * Occurs after an application closes a dataset.
  944.         *
  945.         * Write an OnAfterClose event handler to take specific action immediately
  946.         * after an application closes a dataset.
  947.         *
  948.         * OnAfterClose is called after a dataset is closed and the dataset state
  949.         * is set to dsInactive.
  950.         *
  951.         * @see readOnBeforeClose()
  952.         *
  953.         * @return mixed 
  954.         */
  955.         function readOnAfterClose(return $this->_onafterclose}
  956.         function writeOnAfterClose($value$this->_onafterclose=$value}
  957.         function defaultOnAfterClose(return null}
  958.  
  959.         protected $_onbeforeinsert=null;
  960.  
  961.         /**
  962.         * Occurs before an application enters insert mode.
  963.         *
  964.         * Write a OnBeforeInsert event handler to take specific action before an
  965.         * application inserts or appends a new record. The Insert or Append method
  966.         * generates a OnBeforeInsert method before it sets the dataset into dsInsert state.
  967.         *
  968.         * @see readOnAfterInsert()
  969.         *
  970.         * @return mixed 
  971.         */
  972.         function readOnBeforeInsert(return $this->_onbeforeinsert}
  973.         function writeOnBeforeInsert($value$this->_onbeforeinsert=$value}
  974.         function defaultOnBeforeInsert(return null}
  975.  
  976.         protected $_onafterinsert=null;
  977.  
  978.         /**
  979.         * Occurs after an application inserts a new record.
  980.         *
  981.         * Write an OnAfterInsert event handler to take specific action immediately
  982.         * after an application inserts a record. The Insert and Append methods generate
  983.         * an OnAfterInsert event after inserting or appending a new record.
  984.         *
  985.         * @see readOnBeforeInsert()
  986.         *
  987.         * @return mixed 
  988.         */
  989.         function readOnAfterInsert(return $this->_onafterinsert}
  990.         function writeOnAfterInsert($value$this->_onafterinsert=$value}
  991.         function defaultOnAfterInsert(return null}
  992.  
  993.         protected $_onbeforeedit=null;
  994.  
  995.         /**
  996.         * Occurs before an application enters edit mode for the active record.
  997.         *
  998.         * Write a OnBeforeEdit event handler to take specific action before an
  999.         * application enables editing of the active record. For example, an
  1000.         * application that keeps a log of database edits could use the OnBeforeEdit
  1001.         * event to record the edit request, time, and user before entering edit state.
  1002.         *
  1003.         * @see readOnAfterEdit()
  1004.         *
  1005.         * @return mixed 
  1006.         */
  1007.         function readOnBeforeEdit(return $this->_onbeforeedit}
  1008.         function writeOnBeforeEdit($value$this->_onbeforeedit=$value}
  1009.         function defaultOnBeforeEdit(return null}
  1010.  
  1011.         protected $_onafteredit=null;
  1012.  
  1013.         /**
  1014.         * Occurs after an application starts editing a record.
  1015.         *
  1016.         * Write an OnAfterEdit event handler to take specific action immediately
  1017.         * after dataset enters edit mode. OnAfterEdit is called by Edit after it
  1018.         * enables editing of a record, recalculates calculated fields, and calls
  1019.         * the data event handler to process a record change.
  1020.         *
  1021.         * @see readOnBeforeEdit()
  1022.         *
  1023.         * @return mixed 
  1024.         */
  1025.         function readOnAfterEdit(return $this->_onafteredit}
  1026.         function writeOnAfterEdit($value$this->_onafteredit=$value}
  1027.         function defaultOnAfterEdit(return null}
  1028.  
  1029.         protected $_onbeforepost=null;
  1030.  
  1031.         /**
  1032.         * Occurs before an application posts changes for the active record to the database or change log.
  1033.         *
  1034.         * Write a OnBeforePost event handler to take specific action before an
  1035.         * application posts dataset changes. OnBeforePost is triggered when an
  1036.         * application calls the Post method. Post checks to make sure all required
  1037.         * fields are present, then calls OnBeforePost before posting the record.
  1038.         *
  1039.         * An application might use OnBeforePost to perform validity checks on data
  1040.         * changes before committing them. If it encountered a validity problem, it
  1041.         * could call Abort to cancel the Post operation.
  1042.         *
  1043.         * @see readOnAfterPost()
  1044.         *
  1045.         * @return mixed 
  1046.         */
  1047.         function readOnBeforePost(return $this->_onbeforepost}
  1048.         function writeOnBeforePost($value$this->_onbeforepost=$value}
  1049.         function defaultOnBeforePost(return null}
  1050.  
  1051.         protected $_onafterpost=null;
  1052.  
  1053.         /**
  1054.         * Occurs after an application writes the active record to the database or change log and returns to browse state.
  1055.         *
  1056.         * Write an OnAfterPost event handler to take specific action immediately
  1057.         * after an application posts a change to the active record. OnAfterPost
  1058.         * is called after a modification or insertion is made to a record.
  1059.         *
  1060.         * @see readOnBeforePost()
  1061.         *
  1062.         * @return mixed 
  1063.         */
  1064.         function readOnAfterPost(return $this->_onafterpost}
  1065.         function writeOnAfterPost($value$this->_onafterpost=$value}
  1066.         function defaultOnAfterPost(return null}
  1067.  
  1068.         protected $_onbeforecancel=null;
  1069.  
  1070.         /**
  1071.         * Occurs before an application executes a request to cancel changes to the active record.
  1072.         *
  1073.         * Write a OnBeforeCancel event to take specific action before an application
  1074.         * carries out a request to cancel changes. OnBeforeCancel is called by the
  1075.         * Cancel method before it cancels a dataset operation such as Edit, Insert, or Delete.
  1076.         *
  1077.         * An application might use the OnBeforeCancel event to record a user’s changes in an undo buffer.
  1078.         *
  1079.         * @see readOnAfterCancel()
  1080.         *
  1081.         * @return mixed 
  1082.         */
  1083.         function readOnBeforeCancel(return $this->_onbeforecancel}
  1084.         function writeOnBeforeCancel($value$this->_onbeforecancel=$value}
  1085.         function defaultOnBeforeCancel(return null}
  1086.  
  1087.         protected $_onaftercancel=null;
  1088.  
  1089.         /**
  1090.         * Occurs after an application completes a request to cancel modifications to the active record.
  1091.         *
  1092.         * Write an OnAfterCancel event handler to take specific action after an
  1093.         * application cancels changes to the active record. OnAfterCancel is called by the
  1094.         * Cancel method after it updates the current position, releases the lock on
  1095.         * the active record if necessary, and sets the dataset state to dsBrowse.
  1096.         * If an application requires additional processing before returning control to
  1097.         * a user after a Cancel event, code it in the OnAfterCancel event.
  1098.         *
  1099.         * @see readOnBeforeCancel()
  1100.         *
  1101.         * @return mixed 
  1102.         */
  1103.         function readOnAfterCancel(return $this->_onaftercancel}
  1104.         function writeOnAfterCancel($value$this->_onaftercancel=$value}
  1105.         function defaultOnAfterCancel(return null}
  1106.  
  1107.         protected $_onbeforedelete=null;
  1108.  
  1109.         /**
  1110.         * Occurs before an application attempts to delete the active record.
  1111.         *
  1112.         * Write a BeforeDelete event handler to take specific action before an
  1113.         * application deletes the active record. OnBeforeDelete is called by
  1114.         * Delete before it actually deletes a record.
  1115.         *
  1116.         * @see readOnAfterCancel()
  1117.         *
  1118.         * @return mixed 
  1119.         */
  1120.         function readOnBeforeDelete(return $this->_onbeforedelete}
  1121.         function writeOnBeforeDelete($value$this->_onbeforedelete=$value}
  1122.         function defaultOnBeforeDelete(return null}
  1123.  
  1124.         protected $_onafterdelete=null;
  1125.  
  1126.         /**
  1127.         * Occurs after an application deletes a record.
  1128.         *
  1129.         * Write an OnAfterDelete event handler to take specific action immediately
  1130.         * after an application deletes the active record in a dataset. OnAfterDelete
  1131.         * is called by Delete after it deletes the record, sets the dataset state to
  1132.         * dsBrowse, and repositions the current record.
  1133.         *
  1134.         * @see readOnBeforeDelete()
  1135.         *
  1136.         * @return mixed 
  1137.         */
  1138.         function readOnAfterDelete(return $this->_onafterdelete}
  1139.         function writeOnAfterDelete($value$this->_onafterdelete=$value}
  1140.         function defaultOnAfterDelete(return null}
  1141.  
  1142.         protected $_oncalcfields=null;
  1143.  
  1144.         /**
  1145.         * Occurs when an application recalculates calculated fields.
  1146.         *
  1147.         * (not used)
  1148.         *
  1149.         * @return mixed 
  1150.         */
  1151.         function readOnCalcFields(return $this->_oncalcfields}
  1152.         function writeOnCalcFields($value$this->_oncalcfields=$value}
  1153.         function defaultOnCalcFields(return null}
  1154.  
  1155.         protected $_ondeleteerror=null;
  1156.  
  1157.         /**
  1158.         * Not used, reserved for future use
  1159.         */
  1160.         function readOnDeleteError(return $this->_ondeleteerror}
  1161.         function writeOnDeleteError($value$this->_ondeleteerror=$value}
  1162.         function defaultOnDeleteError(return null}
  1163.  
  1164.         protected $_filter="";
  1165.  
  1166.         /**
  1167.         * Specifies the text of the current filter for a dataset.
  1168.         *
  1169.         * Use Filter to specify a dataset filter. When filtering is applied to a
  1170.         * dataset, only those records that meet a filter’s conditions are available.
  1171.         * Filter describes the filter condition.
  1172.         *
  1173.         * @return string 
  1174.         */
  1175.         function readFilter(return $this->_filter}
  1176.         function writeFilter($value)
  1177.         {
  1178.             if ($value!=$this->_filter)
  1179.             {
  1180.                 //$this->Close();
  1181.                 $this->_filter=$value;
  1182.                 //$this->Open();
  1183.             }
  1184.         }
  1185.         function defaultFilter(return ""}
  1186.  
  1187.  
  1188.  
  1189.         protected $_onfilterrecord=null;
  1190.  
  1191.         /**
  1192.         * Not used, reserved for future use
  1193.         */
  1194.         function readOnFilterRecord(return $this->_onfilterrecord}
  1195.         function writeOnFilterRecord($value$this->_onfilterrecord=$value}
  1196.         function defaultOnFilterRecord(return null}
  1197.  
  1198.         protected $_onnewrecord=null;
  1199.  
  1200.         /**
  1201.         * Not used, reserved for future use
  1202.         */
  1203.         function readOnNewRecord(return $this->_onnewrecord}
  1204.         function writeOnNewRecord($value$this->_onnewrecord=$value}
  1205.         function defaultOnNewRecord(return null}
  1206.  
  1207.         protected $_onposterror=null;
  1208.  
  1209.         /**
  1210.         * Not used, reserved for future use
  1211.         */
  1212.         function readOnPostError(return $this->_onposterror}
  1213.         function writeOnPostError($value$this->_onposterror=$value}
  1214.         function defaultOnPostError(return null}
  1215.  
  1216.  
  1217.         /**
  1218.         * Checks if an specific operation can be made, if not, calls $ErrorEvent
  1219.         * @param string $Operation Operation to perform on the dataset
  1220.         * @param string $ErrorEvent Event to call if there is any error
  1221.         */
  1222.         function checkOperation($Operation$ErrorEvent)
  1223.         {
  1224.             $Done = false;
  1225.             do
  1226.             {
  1227.                 try
  1228.                 {
  1229. //                $this->UpdateCursorPos();
  1230.                   $this->$Operation();
  1231.                   $Done=true;
  1232.                 }
  1233.                 catch (EDatabaseError $e)
  1234.                 {
  1235.                     $Action=daFail;
  1236.                     $Action=$this->callEvent($ErrorEventarray('Exception'=>$e'Action'=>$Action));
  1237.                     if ($Action===null$Action=daFail;
  1238.                     if ($Action==daFailthrow $e;
  1239.                     if ($Action==daAbortAbort();
  1240.                 }
  1241.  
  1242.             }
  1243.             while(!$Done);
  1244.         }
  1245.  
  1246.         /**
  1247.         * Used to notify attached datasets about an specific event
  1248.         * @param integer $event Event to notify
  1249.         * @param array $info Info for the event
  1250.         */
  1251.         function dataEvent($event$info)
  1252.         {
  1253.             $NotifyDataSources !(($this->ControlsDisabled()) || ($this->State == dsBlockRead));
  1254.  
  1255.             switch($event)
  1256.             {
  1257.             /*
  1258.     deFieldChange:
  1259.       begin
  1260.         if TField(Info).FieldKind in [fkData, fkInternalCalc] then
  1261.           SetModified(True);
  1262.         UpdateCalcFields;
  1263.       end;
  1264.     deFieldListChange:
  1265.       FieldList.Updated := False;
  1266.     dePropertyChange:
  1267.       FieldDefs.Updated := False;
  1268.     deCheckBrowseMode:
  1269.       CheckNestedBrowseMode;
  1270.     deDataSetChange, deDataSetScroll:
  1271.       NotifyDetails;
  1272.     deLayoutChange:
  1273.       begin
  1274.         FieldList.Updated := False;
  1275.         if ControlsDisabled then
  1276.           FEnableEvent := deLayoutChange;
  1277.       end;
  1278.     deUpdateState:
  1279.       if ControlsDisabled then
  1280.       begin
  1281.         Event := deDisabledStateChange;
  1282.         Info := Integer(State <> dsInactive);
  1283.         NotifyDataSources := True;
  1284.         FEnableEvent := deLayoutChange;
  1285.       end;
  1286.       */
  1287.       }
  1288.         /*
  1289.         if ($NotifyDataSources)
  1290.         {
  1291.             for I := 0 to FDataSources.Count - 1 do
  1292.               TDataSource(FDataSources[I]).DataEvent(Event, Info);
  1293.         }
  1294.         */
  1295.         }
  1296.  
  1297.         /**
  1298.         * Checks to see if the database connection is active.
  1299.         *
  1300.         * Call CheckActive to determine if the connection to a database server is active.
  1301.         * If the database connection is inactive, an DatabaseError exception is raised.
  1302.         *
  1303.         * @see databaseError()
  1304.         */
  1305.         function checkActive()
  1306.         {
  1307.             if ($this->State == dsInactiveDatabaseError(_("Cannot perform this operation on a closed dataset")$this);
  1308.         }
  1309.  
  1310.         /**
  1311.         * Checks to see if the dataset can be modified.
  1312.         *
  1313.         * Call CheckCanModify to determine if the dataset can be modified.
  1314.         * If the dataset cannot be modified, an DatabaseError exception is raised.
  1315.         *
  1316.         * @see databaseError()
  1317.         */
  1318.         function checkCanModify()
  1319.         {
  1320.             if (!$this->CanModifyDatabaseError(_("Cannot modify a read-only dataset"Self));
  1321.         }
  1322.  
  1323.         /**
  1324.         * Indicates whether data-aware controls update their display to reflect changes to the dataset.
  1325.         *
  1326.         * Call ControlsDisabled to ascertain whether the updating of data display in data-aware
  1327.         * controls is currently disabled. If ControlsDisabled is true, controls are currently disabled.
  1328.         * ControlsDisabled is true as long as the reference count that keeps track of disabling for the
  1329.         * dataset is greater than zero. This count is incremented every time the DisableControls method
  1330.         * is called and decremented when EnableControls is called. Applications call DisableControls to
  1331.         * improve performance and prevent constant updates during automated iterations through records in
  1332.         * the dataset.
  1333.         *
  1334.         * In complex applications, when controls may be disabled multiple times by different processes, you
  1335.         * can use ControlsDisabled as a check in a procedure to reenable controls should each call to
  1336.         * DisableControls not be paired with a subsequent call to EnableControls.
  1337.         *
  1338.         * @see disableControls(), enableControls()
  1339.         *
  1340.         * @return boolean True if controls has been disabled
  1341.         */
  1342.         function controlsDisabled()
  1343.         {
  1344.             return($this->_DisableCount!=0);
  1345.         }
  1346.  
  1347.         /**
  1348.         * Disables data display in data-aware controls associated with the dataset.
  1349.         *
  1350.         * Call DisableControls prior to iterating through a large number of records
  1351.         * in the dataset to prevent data-aware controls from updating every time
  1352.         * the active record changes. Disabling controls speeds performance because
  1353.         * data does not need to be processed by data-aware controls.
  1354.         *
  1355.         * If controls are not already disabled, DisableControls records the current
  1356.         * state of the dataset, broadcasts the state change to all associated data-aware
  1357.         * controls and detail datasets, and increments the dataset’s disabled count variable.
  1358.         * Otherwise, DisableControls just increments the disabled count variable.
  1359.         *
  1360.         * The disabled count is used internally to determine whether to display data
  1361.         * in data-aware controls. When the disable count variable is greater than zero,
  1362.         * data is not updated.
  1363.         *
  1364.         * If the dataset is the master of a master/detail relationship, calling DisableControls
  1365.         * also disables the master/detail relationship.
  1366.         *
  1367.         * Note: Calls to DisableControls can be nested. Only when all calls to DisableControls
  1368.         * is matched to a corresponding call to EnableControls does the dataset update
  1369.         * data controls and detail datasets.
  1370.         *
  1371.         * @see ControlsDisabled(), EnableControls()
  1372.         */
  1373.         function DisableControls()
  1374.         {
  1375.             if ($this->_DisableCount == 0)
  1376.             {
  1377.                 $this->_DisableState=$this->State;
  1378.                 $this->_EnableEvent=deDataSetChange;
  1379.             }
  1380.             $this->_DisableCount++;
  1381.         }
  1382.  
  1383.         /**
  1384.         * Enable controls attached to the datasource
  1385.         *
  1386.         * Call EnableControls to permit data display in data-aware controls after
  1387.         * a prior call to DisableControls. EnableControls decrements the disabled
  1388.         * count variable for the dataset if it is not already zero. If the disable
  1389.         * count variable is zero, EnableControls updates the current state of the
  1390.         * dataset, if necessary, and then tells associated controls to re-enable display.
  1391.         *
  1392.         * @see DisableControls(), EnableControls()
  1393.         *
  1394.         */
  1395.         function EnableControls()
  1396.         {
  1397.             if ($this->_DisableCount!=0)
  1398.             {
  1399.                 $this->_DisableCount--;
  1400.                 if ($this->_DisableCount==0)
  1401.                 {
  1402.                     if ($this->_DisableState!=$this->State$this->DataEvent(deUpdateState0);
  1403.                     if (($this->_DisableState!=dsInactive&& ($this->_State != dsInactive)) $this->DataEvent($this->_EnableEvent0);
  1404.                 }
  1405.             }
  1406.         }
  1407.  
  1408.         /**
  1409.         * Clear buffers associated with the dataset
  1410.         *
  1411.         * This method set the dataset buffers to the inital state, that is, recordcount
  1412.         * to 0 and bof/eof to true. The fieldbuffer is also cleared to an empty array.
  1413.         *
  1414.         */
  1415.         function clearBuffers()
  1416.         {
  1417.             $this->_recordcount = 0;
  1418. //            $this->_activerecord = 0;
  1419. //            $this->_currentrecord = -1;
  1420.             $this->_bof = true;
  1421.             $this->_eof = true;
  1422.             $this->fieldbuffer=array();
  1423.         }
  1424.  
  1425.         /**
  1426.         * Begins an insert/append operation
  1427.         *
  1428.         * This method is called by the dataset to start an insert or append
  1429.         * operation, it first checks the browse mode, after that, checks if the
  1430.         * dataset can be modified and finally, calls the OnBeforeInsert event
  1431.         *
  1432.         * @see insert(), append(), endInsertAppend()
  1433.         */
  1434.         function beginInsertAppend()
  1435.         {
  1436.             $this->CheckBrowseMode();
  1437.             $this->CheckCanModify();
  1438.             $this->callEvent('onbeforeinsert'array());
  1439.             $this->CheckParentState();
  1440.         }
  1441.  
  1442.         /**
  1443.         * Finishes an insert/append operation
  1444.         *
  1445.         * This method is called by a dataset to finish an insert or append
  1446.         * operation. It sets the dataset in insert state, calls the OnNewRecord
  1447.         * event and finally calls the OnAfterInsert.
  1448.         *
  1449.         * @see insert(), append(), endInsertAppend()
  1450.         */
  1451.         function endInsertAppend()
  1452.         {
  1453.             $this->State=dsInsert;
  1454.             try
  1455.             {
  1456.                 $this->callEvent('onnewrecord',array());
  1457.             }
  1458.             catch (Exception $e)
  1459.             {
  1460.                 $this->UpdateCursorPos();
  1461.                 $this->FreeFieldBuffers();
  1462.                 $this->State=dsBrowse;
  1463.                 throw $e;
  1464.             }
  1465.             $this->_modified = false;
  1466.             $this->DataEvent(deDataSetChange0);
  1467.             $this->callEvent('onafterinsert',array());
  1468.         }
  1469.  
  1470.         function __construct($aowner=null)
  1471.         {
  1472.                 //Calls inherited constructor
  1473.                 parent::__construct($aowner);
  1474.         }
  1475.  
  1476.         /**
  1477.         * Inserts a new, empty record in the dataset.
  1478.         *
  1479.         * Call Insert to:
  1480.         *
  1481.         * 1 - Open a new, empty record in the dataset.
  1482.         * 2 - Set the active record to the new record.
  1483.         *
  1484.         * After a call to Insert, an application can allow users to enter data
  1485.         * in the fields of the record, and then post those changes to the database
  1486.         * or change log using Post.
  1487.         *
  1488.         * @see beginInsertAppend(), endInsertAppend(), append()
  1489.         */
  1490.         function insert()
  1491.         {
  1492.             $this->BeginInsertAppend();
  1493.             //OldCurrent := Bookmark;
  1494.             //MoveBuffer(FRecordCount, FActiveRecord);
  1495.             //Buffer := ActiveBuffer;
  1496.             //InitRecord(Buffer);
  1497.             //if FRecordCount = 0 then
  1498.             //SetBookmarkFlag(Buffer, bfBOF) else
  1499.             //SetBookmarkData(Buffer, Pointer(OldCurrent));
  1500.             //if FRecordCount < FBufferCount then Inc(FRecordCount);
  1501.             $this->InternalInsert();
  1502.             $this->EndInsertAppend();
  1503.         }
  1504.  
  1505.         /**
  1506.         * Adds a new, empty record to the end of the dataset.
  1507.         *
  1508.         * For datasets that permit editing, call Append to:
  1509.         *
  1510.         * 1 - Open a new, empty record at the end of the dataset.
  1511.         * 2 - Set the active record to the new record.
  1512.         *
  1513.         * After a call to Append, an application can enable users to enter data
  1514.         * in the fields of the record, and can then post those changes to the
  1515.         * database or change log using Post
  1516.         *
  1517.         * @see beginInsertAppend(), endInsertAppend(), insert()
  1518.         */
  1519.         function append()
  1520.         {
  1521.                 $Buffer="";
  1522.                 $this->BeginInsertAppend();
  1523.                 $this->ClearBuffers();
  1524.                 $this->InitRecord($Buffer);
  1525.                 $this->_recordcount = 1;
  1526.                 $this->_bof = False;
  1527. //                $this->GetPriorRecords();
  1528.                 $this->InternalInsert();
  1529.                 $this->EndInsertAppend();
  1530.         }
  1531.  
  1532.         /**
  1533.         * Cancels modifications to the active record if those changes are not yet posted.
  1534.         *
  1535.         * Call Cancel to undo modifications made to one or more fields belonging to
  1536.         * the active record. As long as those changes are not already posted, Cancel
  1537.         * returns the record to its previous state, and sets the dataset state to dsBrowse.
  1538.         *
  1539.         * Typically Cancel is used to back out of changes in response to user request, or
  1540.         * in field validation routines that back out illegal field values.
  1541.         *
  1542.         * Note: If the dataset is not in an editing state (dsEdit or dsInsert), Cancel does nothing.
  1543.         *
  1544.         * @see edit(), insert()
  1545.         */
  1546.         function cancel()
  1547.         {
  1548.             switch($this->State)
  1549.             {
  1550.                 case dsEdit:
  1551.                 case dsInsert:
  1552.                 {
  1553.                     $this->DataEvent(deCheckBrowseMode0);
  1554.                     $this->callEvent("onbeforecancel",array());
  1555. //                    $DoScrollEvents = ($this->State == dsInsert);
  1556. //                    if ($DoScrollEvents) $this->DoBeforeScroll();
  1557. //                    $this->UpdateCursorPos();
  1558.                     $this->InternalCancel();
  1559.                     $this->fieldbuffer=array();
  1560.                     $this->State=dsBrowse;
  1561.                     //$this->Resync([]);
  1562.                     $this->callEvent("onaftercancel",array());
  1563. //                    if ($DoScrollEvents) $this->DoAfterScroll();
  1564.                     break;
  1565.                 }
  1566.             }
  1567.         }
  1568.  
  1569.         /**
  1570.         * Ensures that data-aware controls and detail datasets reflect record updates.
  1571.         *
  1572.         * UpdateRecord is used internally by some dataset methods to inform data-aware
  1573.         * controls of updates and trigger an OnUpdateRecord event if updates
  1574.         * are enabled. Applications should not need to call UpdateRecord directly unless
  1575.         * they provide custom dataset methods that bypass DataSet methods.
  1576.         *
  1577.         * @see edit(), insert()
  1578.         */
  1579.         function updateRecord()
  1580.         {
  1581.             if (($this->State!=dsEdit&& ($this->State!=dsInsert&& ($this->State!=dsSetKey)) DatabaseError(_("Dataset not in edit or insert mode")$this);
  1582.             $this->DataEvent(deUpdateRecord,0);
  1583.         }
  1584.  
  1585.         /**
  1586.         * Automatically posts or cancels data changes when the active record changes.
  1587.         *
  1588.         * CheckBrowseMode is used internally by many dataset methods to ensure that
  1589.         * modifications to the active record are posted when a dataset’s state is
  1590.         * dsEdit, dsInsert, or dsSetKey and a method switches to a different record.
  1591.         *
  1592.         * If State is dsEdit or dsInsert, CheckBrowseMode calls UpdateRecord, and,
  1593.         * if the Modified property for the dataset is true, calls Post. If Modified
  1594.         * is false, CheckBrowseMode calls Cancel.
  1595.         *
  1596.         * If State is dsSetKey, CheckBrowseMode calls Post.
  1597.         *
  1598.         * If State is dsInactive, CheckBrowseMode raises an exception.
  1599.         *
  1600.         * If an application uses existing dataset methods, CheckBrowseMode is always
  1601.         * called when necessary, so there is usually no need to call CheckBrowseMode directly.
  1602.         *
  1603.         * Applications that provide custom dataset routines may need to call CheckBrowseMode
  1604.         * inside those routines to guarantee that changes are posted when switching to a different record.
  1605.         *
  1606.         * @see edit(), insert(), checkActive(), dataEvent(), updateRecord(), post(), cancel()
  1607.         */
  1608.         function checkBrowseMode()
  1609.         {
  1610.             $this->CheckActive();
  1611.             $this->DataEvent(deCheckBrowseMode0);
  1612.             switch($this->State)
  1613.             {
  1614.                 case dsEdit:
  1615.                 case dsInsert:
  1616.                 {
  1617.                     $this->UpdateRecord();
  1618.                     if ($this->Modified$this->post();
  1619.                     else $this->cancel();
  1620.                     break;
  1621.                 }
  1622.                 case dsSetKey:
  1623.                 {
  1624.                     $this->post();
  1625.                     break;
  1626.                 }
  1627.             }
  1628.         }
  1629.  
  1630.         /**
  1631.         * Closes a dataset.
  1632.         *
  1633.         * Call Close to set the Active property of a dataset to false. When Active
  1634.         * is false, the dataset is closed; it cannot read or write data and data-aware
  1635.         * controls can’t use it to fetch data or post edits.
  1636.         *
  1637.         * An application must close the dataset before changing properties that affect the
  1638.         * status of the database or the controls that display data in an application.
  1639.         * For example, to change the DataSource property for a dataset, the dataset must
  1640.         * be closed. Closing the dataset puts it into the dsInactive state.
  1641.         *
  1642.         * @see open()
  1643.         */
  1644.         function close()
  1645.         {
  1646.             $this->Active=false;
  1647.         }
  1648.  
  1649.         /**
  1650.         * Deletes the active record and positions the dataset on the next record.
  1651.         *
  1652.         * Call Delete to remove the active record from the database. If the dataset
  1653.         * is inactive, Delete raises an exception. Otherwise, Delete:
  1654.         *
  1655.         * Verifies that the dataset is not empty (and raises an exception if it is).
  1656.         *
  1657.         * Calls CheckBrowseMode to post any pending changes to a prior record if necessary.
  1658.         *
  1659.         * Calls the OnBeforeDelete event handler.
  1660.         *
  1661.         * Deletes the record.
  1662.         *
  1663.         * Frees any buffers allocated for the record.
  1664.         *
  1665.         * Puts the dataset into dsBrowse mode.
  1666.         *
  1667.         * Resynchronizes the dataset to make the next undeleted record active.
  1668.         * If the record deleted was the last record in the dataset, then the previous record becomes the current record.
  1669.         *
  1670.         * Calls the AfterDelete event handler.
  1671.         *
  1672.         * @see readOnBeforeDelete(), readOnAfterDelete()
  1673.         */
  1674.         function delete()
  1675.         {
  1676.             $this->CheckActive();
  1677.             if (($this->State==dsInsert|| ($this->State==dsSetKey)) $this->Cancel();
  1678.             else
  1679.             {
  1680.                 if ($this->Recordcount==0DatabaseError(_("Cannot perform this operation on an empty dataset")Self);
  1681.                 $this->DataEvent(deCheckBrowseMode0);
  1682.                 $this->callevent("onbeforedelete",array());
  1683.                 $this->CheckOperation("InternalDelete""ondeleteerror");
  1684.                 $this->fieldbuffer=array();
  1685.                 $this->State=dsBrowse;
  1686.                 $this->callevent("onafterdelete",array());
  1687.             }
  1688.         }
  1689.  
  1690.         /**
  1691.         * Sets the parent dataset in edit state
  1692.         *
  1693.         * This is an internal method you don't need to call directly.
  1694.         *
  1695.         * @see edit()
  1696.         */
  1697.         function checkParentState()
  1698.         {
  1699.             if ($this->DataSetField != null$this->DataSetField->DataSet->Edit();
  1700.         }
  1701.  
  1702.         /**
  1703.         * Enables editing of data in the dataset.
  1704.         *
  1705.         * Call Edit to permit editing of the active record in a dataset. Edit
  1706.         * determines the current state of the dataset. If the dataset is empty,
  1707.         * Edit calls Insert. Otherwise Edit:
  1708.         *
  1709.         * Calls CheckBrowseMode to post any pending changes to a prior record if necessary.
  1710.         *
  1711.         * Checks the CanModify property and raises an exception if the dataset can’t be edited.
  1712.         *
  1713.         * Calls the OnBeforeEdit event handler.
  1714.         *
  1715.         * Retrieves the record.
  1716.         *
  1717.         * Puts the dataset into dsEdit state, enabling the application or user to modify fields in the record.
  1718.         *
  1719.         * Broadcasts the state change to associated controls.
  1720.         *
  1721.         * Calls the OnAfterEdit event handler.
  1722.         *
  1723.         * Modifications will go to a buffer waiting for post()/cancel()
  1724.         *
  1725.         * @see readOnBeforeEdit(), readOnAfterEdit(), post()
  1726.         */
  1727.         function edit()
  1728.         {
  1729.             if ((($this->State==dsEdit|| ($this->State==dsInsert)))
  1730.             {
  1731.             }
  1732.             else
  1733.             {
  1734. //                if ($this->_recordcount==0) $this->Insert();
  1735. //                else
  1736. //                {
  1737.                     $this->CheckBrowseMode();
  1738.                     $this->CheckCanModify();
  1739.                     $this->callevent("onbeforeedit",array());
  1740.                     $this->CheckParentState();
  1741.                     $this->CheckOperation("InternalEdit""onediterror");
  1742. //                    $this->GetCalcFields(ActiveBuffer);
  1743.                     $this->State=dsEdit;
  1744.                     $this->DataEvent(deRecordChange0);
  1745.                     $this->callevent("onafteredit",array());
  1746. //                }
  1747.             }
  1748.         }
  1749.  
  1750.         /**
  1751.         * Indicates the total number of records associated with the dataset.
  1752.         *
  1753.         * As implemented in DataSet, RecordCount is always 0. Ordinarily an application
  1754.         * does not access RecordCount at the DataSet level. Instead a redeclared and
  1755.         * implemented RecordCount property in a descendant class is accessed. RecordCount
  1756.         * provides a fallback property for derived dataset classes that do not reimplement
  1757.         * the property access method.
  1758.         *
  1759.         * @return integer 
  1760.         */
  1761.         function readRecordCount()
  1762.         {
  1763.             return $this->_recordcount;
  1764.         }
  1765.         function defaultRecordCount(return 0}
  1766.  
  1767.  
  1768.         /**
  1769.         * Moves to the first record in the dataset.
  1770.         *
  1771.         * Call First to make the first record in the dataset active. First posts
  1772.         * any changes to the active record and:
  1773.         *
  1774.         * Clears the record buffers.
  1775.         *
  1776.         * Fetches the first record and makes it the active record.
  1777.         *
  1778.         * Fetches any additional records required for display, such as those needed to
  1779.         * fill out a grid control.
  1780.         *
  1781.         * Sets the Bof property to true.
  1782.         *
  1783.         * Broadcasts the record change so that data controls and linked detail sets can update.
  1784.         *
  1785.         * Note: DataSet uses internal, protected methods to reposition the active record and
  1786.         * to fetch additional records required for display. In DataSet, these internal methods are empty
  1787.         * stubs. Descendant classes implement these methods to enable the First method to work.
  1788.         *
  1789.         * @see last(), readBof(), readEof()
  1790.         */
  1791.         function first()
  1792.         {
  1793.             $this->CheckBrowseMode();
  1794.             $FReopened = false;
  1795.             /*
  1796.             if IsUniDirectional then begin
  1797.                 if not BOF then begin             // Need to Close and Reopen dataset: (Midas)
  1798.                     Active := False;
  1799.                     Active := True;
  1800.                 end;
  1801.                 FReopened := True
  1802.             end
  1803.             else ClearBuffers;
  1804.             */
  1805.             $this->ClearBuffers();
  1806.             try
  1807.             {
  1808.                 $this->InternalFirst();
  1809.                 //if not FReopened then begin
  1810.                 //$this->GetNextRecord();
  1811.                 //$this->GetNextRecords();
  1812.                 //end;
  1813.             }
  1814.             catch (Exception $e)
  1815.             {
  1816.                 $this->_bof = true;
  1817.                 $this->DataEvent(deDataSetChange0);
  1818.                 throw $e;
  1819.             }
  1820.  
  1821.             $this->_bof = true;
  1822.             $this->DataEvent(deDataSetChange0);
  1823.         }
  1824.  
  1825.         /**
  1826.         * Performs an internal open of the dataset
  1827.         *
  1828.         * This is method called by the dataset to perform an open of the data.
  1829.         * It calls InternalOpen, a method you should implement if you are deriving
  1830.         * from Dataset.
  1831.         *
  1832.         * @see open(), readBof()
  1833.         */
  1834.         function doInternalOpen()
  1835.         {
  1836.             $this->_DefaultFields = ($this->FieldCount == 0);
  1837.             $this->InternalOpen();
  1838.             $this->_InternalOpenComplete = true;
  1839.             //$this->UpdateBufferCount();
  1840.             $this->_bof = true;
  1841.         }
  1842.  
  1843.         /**
  1844.         * Opens the cursor for the dataset
  1845.         *
  1846.         * This method is called to open the cursor for this dataset by calling
  1847.         * DoInternalOpen.
  1848.         *
  1849.         * @see doInternalOpen(), open()
  1850.         *
  1851.         * @param boolean $InfoQuery If true, initialize internal field defs
  1852.         */
  1853.         function openCursor($InfoQuery= False)
  1854.         {
  1855.             if ($InfoQuery$this->InternalInitFieldDefs();
  1856.             else if ($this->State!=dsOpening$this->DoInternalOpen();
  1857.         }
  1858.  
  1859.         /**
  1860.         * Finishes the open cursor operation
  1861.         *
  1862.         * This method is called when opening a cursor to complete the open operation,
  1863.         * it first calls DoInternalOpen and fires the OnAfterOpen event.
  1864.         *
  1865.         * @see DoInternalOpen(), Open(), OpenCursor()
  1866.         */
  1867.         function OpenCursorComplete()
  1868.         {
  1869.             try
  1870.             {
  1871.                 if ($this->State == dsOpening$this->DoInternalOpen();
  1872.             }
  1873.             catch(Exception $e)
  1874.             {
  1875.                 if ($this->_InternalOpenComplete)
  1876.                 {
  1877.                     $this->State=dsBrowse;
  1878.                     $this->callEvent("onafteropen"array());
  1879.                 }
  1880.                 else
  1881.                 {
  1882.                     $this->State=dsInactive;
  1883.                     $this->CloseCursor();
  1884.                 }
  1885.                 throw $e;
  1886.             }
  1887.             if ($this->_InternalOpenComplete)
  1888.             {
  1889.                 if ($this->_state==dsInactive$this->_state=dsBrowse;
  1890.                 $this->callEvent("onafteropen"array());
  1891.             }
  1892.             else
  1893.             {
  1894.                 $this->State=dsInactive;
  1895.                 $this->CloseCursor();
  1896.             }
  1897.         }
  1898.  
  1899.         /**
  1900.         * Close the cursor for this dataset
  1901.         *
  1902.         * This method is used to close the cursor attached to the dataset, it
  1903.         * calls InternalClose, a method you need to override if you are deriving
  1904.         * from Dataset.
  1905.         *
  1906.         * @see internalClose(), close()
  1907.         */
  1908.         function closeCursor()
  1909.         {
  1910. //            BlockReadSize := 0;
  1911.             $this->_InternalOpenComplete = false;
  1912. //            FreeFieldBuffers;
  1913. //            ClearBuffers;
  1914. //            SetBufListSize(0);
  1915.             $this->InternalClose();
  1916. //            FBufferCount := 0;
  1917. //            FDefaultFields := False;
  1918.         }
  1919.  
  1920.         /**
  1921.         * To be overriden to perform a first() operation
  1922.         *
  1923.         * This method is called when a first operation is atempted, so if you are
  1924.         * creating new types of datasets, you need to override this method.
  1925.         *
  1926.         * @see first()
  1927.         */
  1928.         function internalFirst()
  1929.         {
  1930.         }
  1931.  
  1932.         /**
  1933.         * To be overriden to perform a last() operation
  1934.         *
  1935.         * This method is called when a last operation is atempted, so if you are
  1936.         * creating new types of datasets, you need to override this method.
  1937.         *
  1938.         * @see last()
  1939.         */
  1940.         function internalLast()
  1941.         {
  1942.           databaseError("Last operations are not implemented for this type dataset",$this);
  1943.         }
  1944.  
  1945.         /**
  1946.         * To initialize the current record
  1947.         * @param array $Buffer Initial values
  1948.         *
  1949.         * @see internalInitRecord()
  1950.         */
  1951.         function initRecord($Buffer)
  1952.         {
  1953.             $this->InternalInitRecord($Buffer);
  1954. //            $this->ClearCalcFields($Buffer);
  1955. //            $this->SetBookmarkFlag($Buffer, bfInserted);
  1956.         }
  1957.  
  1958.         function internalInitRecord($buffer)
  1959.         {
  1960.         }
  1961.  
  1962.         function internalAddRecord($buffer$append)
  1963.         {
  1964.         }
  1965.  
  1966.         /**
  1967.         * To be overriden to perform a delete() operation
  1968.         *
  1969.         * This method is called when a delete operation is atempted, so if you are
  1970.         * creating new types of datasets, you need to override this method.
  1971.         *
  1972.         * @see delete()
  1973.         */
  1974.         function internalDelete()
  1975.         {
  1976.         }
  1977.  
  1978.         /**
  1979.         * To be overriden to perform a post() operation
  1980.         *
  1981.         * This method is called when a post operation is atempted, so if you are
  1982.         * creating new types of datasets, you need to override this method.
  1983.         *
  1984.         * @see post()
  1985.         */
  1986.         function internalPost()
  1987.         {
  1988. //            $this->CheckRequiredFields();
  1989.         }
  1990.  
  1991.         /**
  1992.         * To be overriden to perform a cancel() operation
  1993.         *
  1994.         * This method is called when a cancel operation is atempted, so if you are
  1995.         * creating new types of datasets, you need to override this method.
  1996.         *
  1997.         * @see cancel()
  1998.         */
  1999.         function internalCancel()
  2000.         {
  2001.         }
  2002.  
  2003.         /**
  2004.         * To be overriden to perform a edit() operation
  2005.         *
  2006.         * This method is called when a edit operation is atempted, so if you are
  2007.         * creating new types of datasets, you need to override this method.
  2008.         *
  2009.         * @see edit()
  2010.         */
  2011.         function internalEdit()
  2012.         {
  2013.         }
  2014.  
  2015.         /**
  2016.         * To be overriden to perform a insert() operation
  2017.         *
  2018.         * This method is called when a insert operation is atempted, so if you are
  2019.         * creating new types of datasets, you need to override this method.
  2020.         *
  2021.         * @see insert()
  2022.         */
  2023.         function internalInsert()
  2024.         {
  2025.         }
  2026.  
  2027.         /**
  2028.         * To be overriden to perform a refresh() operation
  2029.         *
  2030.         * This method is called when a refresh operation is atempted, so if you are
  2031.         * creating new types of datasets, you need to override this method.
  2032.         *
  2033.         * @see refresh()
  2034.         */
  2035.         function internalRefresh()
  2036.         {
  2037.         }
  2038.  
  2039.         /**
  2040.         * Moves to the last record in the dataset.
  2041.         *
  2042.         * Call Last to make the last record in the dataset active.
  2043.         * Last posts any changes to the active record and
  2044.         *
  2045.         * Clears the record buffers.
  2046.         *
  2047.         * Fetches the last record and makes it the active record.
  2048.         *
  2049.         * Fetches any additional records required for display, such as those needed to fill out a grid control.
  2050.         *
  2051.         * Sets the Eof property to true.
  2052.         *
  2053.         * Broadcasts the record change so that data controls and linked detail sets can update.
  2054.         *
  2055.         *
  2056.         * Note: DataSet uses internal, protected methods to reposition the active record
  2057.         * and to fetch additional records required for display. In DataSet, these internal methods
  2058.         * are empty stubs. Descendant classes implement these methods to enable the Last method to work.
  2059.         *
  2060.         * @see internalLast(), first()
  2061.         */
  2062.         function last()
  2063.         {
  2064.             //$this->CheckBiDirectional();
  2065.             $this->CheckBrowseMode();
  2066.             $this->ClearBuffers();
  2067.             try
  2068.             {
  2069.                 $this->InternalLast();
  2070. //                $this->GetPriorRecord();
  2071. //                $this->GetPriorRecords();
  2072.             }
  2073.             catch (Exception $e)
  2074.             {
  2075.                 $this->_eof = true;
  2076.                 $this->DataEvent(deDataSetChange0);
  2077.                 throw $e;
  2078.             }
  2079.  
  2080.             $this->_eof = true;
  2081.             $this->DataEvent(deDataSetChange0);
  2082.         }
  2083.  
  2084.         /**
  2085.         * Re-fetches data from the database to update a dataset’s view of data.
  2086.         *
  2087.         * Call Refresh to ensure that an application has the latest data from a database.
  2088.         * For example, when an application turns off filtering for a dataset, it should immediately
  2089.         * call Refresh to display all records in the dataset, not just those that used to meet the filter condition.
  2090.         *
  2091.         * DataSet generates a OnBeforeRefresh event before refreshing the records and an OnAfterRefresh event afterwards.
  2092.         *
  2093.         * Warning: Dataset refresh the data by closing and reopening the cursor. This can have unintended side effects if,
  2094.         * for example, you have code in the OnBeforeClose, OnAfterClose, OnBeforeOpen, or OnAfterOpen event handlers.
  2095.         *
  2096.         * @see readActive()
  2097.         */
  2098.         function refresh()
  2099.         {
  2100.             $this->Active=false;
  2101.             $this->Active=true;
  2102.         }
  2103.  
  2104.         /**
  2105.         * Moves to the next record in the dataset.
  2106.         *
  2107.         * Call Next to move to the next record in the dataset, making it the
  2108.         * active record. Next posts any changes to the active record and
  2109.         *
  2110.         * Sets the Bof and Eof properties to false.
  2111.         *
  2112.         * Fetches the next record and makes it the active record.
  2113.         *
  2114.         * Fetches any additional records required for display, such as those needed to fill out a grid control.
  2115.         *
  2116.         * Sets the Eof property to true if the last record in the dataset was already active.
  2117.         *
  2118.         * Broadcasts the record change so that data controls and linked detail sets can update.
  2119.         *
  2120.         * Note: DataSet uses internal, protected methods to move the active record and
  2121.         * to fetch additional records required for display. In DataSet, these internal methods are empty stubs.
  2122.         * Descendant classes implement these methods to enable the Next method to work.
  2123.         *
  2124.         * @see prior()
  2125.         */
  2126.         function next()
  2127.         {
  2128. //            if ($this->BlockReadSize > 0) $this->BlockReadNext();
  2129. //            else
  2130.               $this->MoveBy(1);
  2131.               if (!$this->EOF$this->fieldbuffer=$this->_rs->fields;
  2132.         }
  2133.  
  2134.         /**
  2135.         * Opens the dataset.
  2136.         *
  2137.         * Call Open to set the Active property for the dataset to true. When Active
  2138.         * is true, dataset can be populated with data. It can read data from a database
  2139.         * or other source (such as a provider). Depending on the CanModify property,
  2140.         * active datasets can post changes.
  2141.         *
  2142.         * Setting Active to true:
  2143.         *
  2144.         * Triggers the OnBeforeOpen event handler if one is defined for the dataset.
  2145.         *
  2146.         * Sets the dataset state to dsBrowse.
  2147.         *
  2148.         * Establishes a way to fetch data (typically by opening a cursor).
  2149.         *
  2150.         * Triggers the After Open event handler if one is defined for the dataset.
  2151.         *
  2152.         * If an error occurs during the dataset open, dataset state is set to dsInactive, and any cursor is closed.
  2153.         *
  2154.         * @see close(), readActive()
  2155.         */
  2156.         function open()
  2157.         {
  2158.             $this->Active=true;
  2159.         }
  2160.  
  2161.         /**
  2162.         * Implements a virtual method to write a modified record to the database or change log.
  2163.         *
  2164.         * DataSet implements a virtual method to write a modified record to the database or
  2165.         * change log. Dataset methods that change the dataset state, such as Edit, Insert, or Append,
  2166.         * or that move from one record to another, such as First, Last, Next, and Prior automatically call Post.
  2167.         *
  2168.         * Designers of custom datasets can choose whether to implement Post by writing records to the
  2169.         * database server or to an internal change log.
  2170.         *
  2171.         * @see cancel(), edit(), insert()
  2172.         */
  2173.         function post()
  2174.         {
  2175.             $this->UpdateRecord();
  2176.             switch ($this->State)
  2177.             {
  2178.                 case dsEdit:
  2179.                 case dsInsert:
  2180.                 {
  2181.                     $this->DataEvent(deCheckBrowseMode0);
  2182.                     $this->callevent("onbeforepost",array());
  2183.                     $this->CheckOperation("InternalPost""onposterror");
  2184.                     $this->fieldbuffer=array();
  2185.                     //$this->FreeFieldBuffers();
  2186.                     $this->State=dsBrowse;
  2187.                     $this->callevent("onafterpost",array());
  2188.                     break;
  2189.                 }
  2190.             }
  2191.         }
  2192.  
  2193.         /**
  2194.         * Moves to another record relative to the active record in the dataset.
  2195.         *
  2196.         * Call MoveBy to move the active record by the number of records specified by
  2197.         * Distance. A positive value for Distance indicates forward progress through
  2198.         * the dataset, while a negative value indicates backward progress.
  2199.         *
  2200.         * MoveBy posts any changes to the active record and
  2201.         *
  2202.         * Sets the Bof and Eof properties to false.
  2203.         *
  2204.         * If Distance is positive, repeatedly fetches Distance subsequent records
  2205.         * (if possible), and makes the last record fetched active. If an attempt is
  2206.         * made to move past the end of the file, MoveBy sets Eof to true.
  2207.         *
  2208.         * If Distance is negative, repeatedly fetches the appropriate number of
  2209.         * previous records (if possible), and makes the last record fetched active.
  2210.         * If an attempt is made to move past the start of the file, MoveBy sets Bof
  2211.         * to true. If the dataset is unidirectional, the dataset raises an EDatabaseError
  2212.         * exception when MoveBy tries to fetch a prior record.
  2213.         *
  2214.         * Broadcasts information about the record change so that data-aware controls and
  2215.         * linked datasets can update.
  2216.         *
  2217.         * @param integer $distance Records to move the pointer
  2218.         *
  2219.         * @see first(), last(), prior(), next()
  2220.         */
  2221.         function moveBy($distance)
  2222.         {
  2223.             $this->_recno+=$distance;
  2224.         }
  2225.  
  2226.         /**
  2227.         * Moves to the previous record in the dataset.
  2228.         *
  2229.         * Call Prior to move to the previous record in the dataset, making it the
  2230.         * active record. Prior posts any changes to the active record and
  2231.         *
  2232.         * Sets the Bof and Eof properties to false.
  2233.         *
  2234.         * Fetches the previous record and makes it the active record. If the dataset
  2235.         * is unidirectional, it raises an EDatabaseError exception at this point.
  2236.         *
  2237.         * Fetches any additional records required for display, such as those needed to
  2238.         * fill out a grid control.
  2239.         *
  2240.         * Sets the Bof property to true if the first record in the dataset was already active.
  2241.         *
  2242.         * Broadcasts the record change so that data controls and linked detail sets can update.
  2243.         *
  2244.         * Note: DataSet uses internal, protected methods to move the active record and
  2245.         * to fetch additional records required for display. In DataSet, these internal
  2246.         * methods are empty stubs. Descendant classes implement these methods to enable the Prior
  2247.         * method to work.
  2248.         *
  2249.         * @see next(), moveBy()
  2250.         */
  2251.         function prior()
  2252.         {
  2253.             $this->MoveBy(-1);
  2254.         }
  2255.  
  2256.         /**
  2257.         * Specifies whether or not a dataset is open.
  2258.         *
  2259.         * Use Active to determine or set whether a dataset is populated with data.
  2260.         * When Active is false, the dataset is closed; the dataset cannot read or write
  2261.         * data and data-aware controls can not use it to fetch data or post edits.
  2262.         * When Active is true, the dataset can be populated with data. It can read data
  2263.         * from a database or other source (such as a provider). Depending on the
  2264.         * CanModify property, active datasets can post changes.
  2265.         *
  2266.         * Setting Active to true:
  2267.         *
  2268.         * Generates a OnBeforeOpen event.
  2269.         *
  2270.         * Sets the dataset state to dsBrowse.
  2271.         *
  2272.         * Establishes a way to fetch data (typically by opening a cursor).
  2273.         *
  2274.         * Generates an OnAfterOpen event.
  2275.         *
  2276.         * If an error occurs while opening the dataset, dataset state is set to
  2277.         * dsInactive, and any cursor is closed.
  2278.         *
  2279.         *
  2280.         *
  2281.         * Setting Active to false:
  2282.         *
  2283.         * 1 - Triggers a BeforeClose event.
  2284.         *
  2285.         * 2 - Sets the State property to dsInactive.
  2286.         *
  2287.         * 3 - Closes the cursor.
  2288.         *
  2289.         * 4 - Triggers an AfterClose event.
  2290.         *
  2291.         * An application must set Active to false before changing other properties
  2292.         * that affect the status of a database or the controls that display data in
  2293.         * an application.
  2294.         *
  2295.         * Note: Calling the Open method sets Active to true; calling the Close method
  2296.         * sets Active to false.
  2297.         *
  2298.         * @see open(), close(), readState()
  2299.         *
  2300.         * @return boolean 
  2301.         */
  2302.         function readActive()
  2303.         {
  2304.             if (($this->readState()==dsInactive|| ($this->readState()==dsOpening|| ($this->_rs==null))
  2305.             {
  2306.                 return(0);
  2307.             }
  2308.             else return(true);
  2309.         }
  2310.  
  2311.         protected $_fstreamedactive=false;
  2312.  
  2313.         function loaded()
  2314.         {
  2315.             parent::loaded();
  2316.             $this->writeMasterSource($this->_mastersource);
  2317.             if ($this->_fstreamedactive)
  2318.             {
  2319.                 $this->Active=true;
  2320.             }
  2321.         }
  2322.  
  2323.         function writeActive($value)
  2324.         {
  2325.             if (($this->ControlState csLoading)==csLoading)
  2326.             {
  2327.                 $this->_fstreamedactive=$value;
  2328.             }
  2329.             else
  2330.             {
  2331.                 if ($this->Active != $value)
  2332.                 {
  2333.                     if ($value==true)
  2334.                     {
  2335.                         $this->callevent("onbeforeopen",array());
  2336.                         try
  2337.                         {
  2338.                             $this->OpenCursor();
  2339.                             if ($this->State!=dsOpening)
  2340.                             {
  2341.                                 $this->OpenCursorComplete();
  2342.                             }
  2343.                         }
  2344.                         catch (Exception $e)
  2345.                         {
  2346.                             if ($this->State!=dsOpening)
  2347.                             {
  2348.                                 $this->OpenCursorComplete();
  2349.                             }
  2350.                             throw $e;
  2351.                         }
  2352.                     }
  2353.                     else
  2354.                     {
  2355.                         $this->callevent("onbeforeclose",array());
  2356.                         $this->State=dsInactive;
  2357.                         $this->CloseCursor();
  2358.                         $this->callevent("onafterclose",array());
  2359.                     }
  2360.                 }
  2361.             }
  2362.         }
  2363.  
  2364.         function defaultActive(return "0"}
  2365.  
  2366.  
  2367.         protected $_bof=false;
  2368.         protected $_eof=false;
  2369.  
  2370.         /**
  2371.         * Indicates whether the first record in the dataset is active.
  2372.         *
  2373.         * Test Bof (beginning of file) to determine if the dataset is positioned
  2374.         * at the first record. If Bof is true, the active record is unequivocally
  2375.         * the first row in the dataset. Bof is true when an application.
  2376.         *
  2377.         * Opens a dataset.
  2378.         *
  2379.         * Calls a dataset’s First method.
  2380.         *
  2381.         * Call a dataset’s Prior method, and the method fails because the first row is already active.
  2382.         *
  2383.         * Bof is false in all other cases.
  2384.         *
  2385.         * @see EOF(), First()
  2386.         *
  2387.         * @return boolean 
  2388.         */
  2389.         function readBOF(return $this->_bof}
  2390.         function defaultBOF(return false}
  2391.  
  2392.         /**
  2393.         * Indicates whether a dataset is positioned at the last record.
  2394.         *
  2395.         * Test Eof (end-of-file) to determine if the active record in a dataset
  2396.         * is the last record. If Eof is true, the current record is unequivocally
  2397.         * the last row in the dataset. Eof is true when an application:
  2398.         *
  2399.         * Opens an empty dataset.
  2400.         *
  2401.         * Calls a dataset’s Last method. (Unless it is a unidirectional dataset)
  2402.         *
  2403.         * Call a dataset’s Next method, and the method fails because the current record is already the last row in the dataset.
  2404.         *
  2405.         *
  2406.         *
  2407.         * Eof is false in all other cases.
  2408.         *
  2409.         * Tip: If both Eof and Bof are true, the dataset is empty.
  2410.         *
  2411.         * @see BOF(), Last(), Next()
  2412.         *
  2413.         * @return boolean 
  2414.         */
  2415.         function readEOF(return $this->_eof}
  2416.         function defaultEOF(return false}
  2417. }
  2418.  
  2419. /**
  2420.  * DataSource provides an interface between a dataset component and data-aware controls on a form.
  2421.  *
  2422.  * Use DataSource to
  2423.  *
  2424.  * provide a conduit between a dataset and data-aware controls on a form that enable display,
  2425.  * navigation, and editing of the data underlying the dataset.
  2426.  *
  2427.  * link two datasets in a master/detail relationship.
  2428.  *
  2429.  * All datasets must be associated with a data source component if their data is to be displayed and
  2430.  * manipulated in data-aware controls. Similarly, each data-aware control needs to be associated with
  2431.  * a data source component in order for the control to receive and manipulate data.
  2432.  *
  2433.  * Data source components also link datasets in master-detail relationships.
  2434.  */
  2435. class Datasource extends Component
  2436. {
  2437.         protected $_dataset;
  2438.  
  2439.         function __construct($aowner=null)
  2440.         {
  2441.                 //Calls inherited constructor
  2442.                 parent::__construct($aowner);
  2443.         }
  2444.  
  2445.         /**
  2446.         * Specifies the dataset for which the data source component serves as
  2447.         * a conduit to data-aware controls or other datasets.
  2448.         *
  2449.         * Set DataSet to the name of an existing dataset component either at
  2450.         * design time, or at runtime. By changing the value of DataSet at runtime
  2451.         * an application can effectively use the same data-aware controls to
  2452.         * display and edit data in different datasets.
  2453.         *
  2454.         *
  2455.         * Note: To link a dataset that resides in a data module to a form at
  2456.         * design-time, choose File | Use unit
  2457.         *
  2458.         * @return DataSet 
  2459.         */
  2460.         function getDataSet(return $this->_dataset}
  2461.         function setDataSet($value)
  2462.         {
  2463.                 $this->_dataset=$this->fixupProperty($value);
  2464.         }
  2465.  
  2466.         function loaded()
  2467.         {
  2468.                 parent::loaded();
  2469.                 $this->setDataSet($this->_dataset);
  2470.         }
  2471. }
  2472.  
  2473. ?>

Documentation generated on Fri, 26 Dec 2008 11:44:35 +0100 by phpDocumentor 1.4.0a2