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

Source for file BitDbBase.php

Documentation is available at BitDbBase.php

  1. <?php
  2. /**
  3.  * ADOdb Library interface Class
  4.  *
  5.  * @package kernel
  6.  * @version $Header: /cvsroot/bitweaver/_bit_kernel/BitDbBase.php,v 1.36 2007/02/15 09:15:38 phoenixandy Exp $
  7.  *
  8.  *  Copyright (c) 2004 bitweaver.org
  9.  *  Copyright (c) 2003 tikwiki.org
  10.  *  Copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
  11.  *  All Rights Reserved. See copyright.txt for details and a complete list of authors.
  12.  *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details
  13.  *
  14.  * @author spider <spider@steelsun.com>
  15.  */
  16.  
  17. /**
  18.  * ensure your AdoDB install is a subdirectory off your include path
  19.  */
  20. require_onceKERNEL_PKG_PATH.'bit_error_inc.php' );
  21.  
  22. define'BIT_QUERY_DEFAULT'-);
  23.  
  24.  
  25. /**
  26.  * This class is used for database access and provides a number of functions to help
  27.  * with database portability.
  28.  *
  29.  * Currently used as a base class, this class should be optional to ensure bitweaver
  30.  * continues to function correctly, without a valid database connection.
  31.  *
  32.  * @package kernel
  33.  */
  34. class BitDb {
  35.     /**
  36.     * Used to store the ADODB db object used to access the database.
  37.     * This is just a pointer to a single global variable used by all classes.
  38.     * This limits database connections to just one per request.
  39.     * @private
  40.     */
  41.     var $mDb;
  42.     /**
  43.     * Used to identify the ADODB db object
  44.     * @private
  45.     */
  46.     var $mName;
  47.     /**
  48.     * Used to store the ADODB db object type
  49.     * @private
  50.     */
  51.     var $mType;
  52.     /**
  53.     * Used to store failed commands
  54.     * @private
  55.     */
  56.     var $mFailed = array();
  57.     /**
  58.     * Used to store the number of queries executed.
  59.     * @private
  60.     */
  61.     var $mNumQueries = 0;
  62.     /**
  63.     * Used to store the total query time for this request.
  64.     * @private
  65.     */
  66.     var $mQueryTime = 0;
  67.     /**
  68.     * Case sensitivity flag used in convertQuery
  69.     * @private
  70.     */
  71.     var $mCaseSensitive = TRUE;
  72.     /**
  73.     * Used to enable AdoDB caching
  74.     * @private
  75.     */
  76.     var $mCacheFlag;
  77.     /**
  78.     * Used to determine SQL debug output. BitDbAdodb overrides associated methods to use the debugging mechanisms built into ADODB
  79.     * @private
  80.     */
  81.     var $mDebug;
  82.     /**
  83.     * Determines if fatal query functions should terminate script execution. Defaults to TRUE. Can be deactived for things like expected duplicate inserts
  84.     * @private
  85.     */
  86.     var $mFatalActive;
  87.     /**
  88.     * During initialisation, database parameters are passed to the class.
  89.     * If these parameters are not valid, class will not be initialised.
  90.     */
  91.     function BitDb({
  92.         global $gDebug;
  93.         $this->mDebug = $gDebug;
  94.         $this->mCacheFlag = FALSE;
  95.         $this->mNumQueries = 0;
  96.         $this->mQueryTime = 0;
  97.         $this->setFatalActive();
  98.         global $gBitDbCaseSensitivity;
  99.         $this->setCaseSensitivity$gBitDbCaseSensitivity );
  100.     }
  101.     /**
  102.     * This function contains any pre-connection work
  103.     * @private
  104.     * @todo investigate if this is the correct way to do it.
  105.     */
  106.     function preDBConnection({
  107.         // Pre connection setup
  108.         if(isset($this->mType)) {
  109.             // we have a db we're gonna try to load
  110.             switch ($this->mType{
  111.                 case "sybase":
  112.                 // avoid database change messages
  113.                 ini_set("sybct.min_server_severity""11");
  114.                 break;
  115.             }
  116.         else {
  117.             die("No database type specified");
  118.         }
  119.     }
  120.     /**
  121.     * This function contains any post-connection work
  122.     * @private
  123.     * @todo investigate if this is the correct way to do it.
  124.     * @todo remove the BIT_DB_PREFIX, change to a member variable
  125.     * @todo get spiderr to explain the schema line
  126.     */
  127.     function postDBConnection({
  128.         // Post connection setup
  129.         switch ($this->mType{
  130.             case "sybase":
  131.             case "mssql":
  132.             $this->mDb->Execute("set quoted_identifier on");
  133.             break;
  134.             case "mysql":
  135.             $this->mDb->Execute("set session sql_mode='PIPES_AS_CONCAT'");
  136.             break;
  137.             case "postgres":
  138.             // Do a little prep work for postgres, no break, cause we want default case too
  139.             if (defined("BIT_DB_PREFIX"&& preg_match"/\./"BIT_DB_PREFIX) ) {
  140.                 $schema preg_replace("/[`\.]/"""BIT_DB_PREFIX);
  141.                 // Assume we want to dump in a schema, so set the search path and nuke the prefix here.
  142.                 // $result = $this->mDb->Execute( "SET search_path TO $schema,public" );
  143.             }
  144.             break;
  145.         }
  146.     }
  147.  
  148.     /**
  149.     * Determines if the database connection is valid
  150.     * @return true if DB connection is valid, false if not
  151.     */
  152.     function isValid({
  153.         return!empty$this->mDb ) );
  154.     }
  155.     /**
  156.     * Determines if the database connection is valid
  157.     * @return true if DB connection is valid, false if not
  158.     */
  159.     function isFatalActive({
  160.         return$this->mFatalActive );
  161.     }
  162.     /**
  163.     * Determines if the database connection is valid
  164.     * @return true if DB connection is valid, false if not
  165.     */
  166.     function setFatalActive$pActive=TRUE {
  167.         $this->mFatalActive = $pActive;
  168.     }
  169.     /**
  170.     * Used to start query timer if in debug mode
  171.     */
  172.     function queryStart({
  173.         global $gBitTimer;
  174.         $this->mQueryLap $gBitTimer->elapsed();
  175.     }
  176.     /** will activate ADODB like native debugging output
  177.     * @param pLevel debugging level - FALSE is off, TRUE is on, 99 is verbose
  178.     ***/
  179.     function debug$pLevel=99 {
  180.         $this->mDebug = $pLevel;
  181.     }
  182.  
  183.     /** returns the level of query debugging output
  184.     * @return pLevel debugging level - FALSE is off, TRUE is on, 99 is verbose
  185.     ***/
  186.     function getDebugLevel({
  187.         return$this->mDebug );
  188.     }
  189.     /**
  190.     * Sets the case sensitivity mode which is used in convertQuery
  191.     * @return true if DB connection is valid, false if not
  192.     */
  193.     function setCaseSensitivity$pSensitivity=TRUE {
  194.         $this->mCaseSensitive = $pSensitivity;
  195.     }
  196.     /**
  197.     * Sets the case sensitivity mode which is used in convertQuery
  198.     * @return true if DB connection is valid, false if not
  199.     */
  200.     function getCaseSensitivity$pSensitivity=TRUE {
  201.         switch ($this->mType{
  202.             case "oci8":
  203.             case "oci8po":
  204.                 // Force Oracle to always be insensitive
  205.                 $ret FALSE;
  206.                 break;
  207.             default:
  208.                 $ret $this->mCaseSensitive;
  209.                 break;
  210.         }
  211.     
  212.         return$ret );
  213.     }
  214.     /**
  215.     * Used to stop query tracking and output results if in debug mode
  216.     */
  217.     function queryComplete({
  218.         global $num_queries;
  219.         //count the number of queries made
  220.         $num_queries++;
  221.         $this->mNumQueries++;
  222.         global $gBitTimer;
  223.         $interval $gBitTimer->elapsed($this->mQueryLap;
  224.         $this->mQueryTime += $interval;
  225.         if$this->getDebugLevel() ) {
  226.             $style $interval .5 'color:red;' (( $interval .15 'color:orange;' '');
  227.             print '<p style="'.$style.'">### Query: '.$num_queries.' Start time: '.$this->mQueryLap.' ### Query run time: '.$interval.'</p>';
  228. #vd(debug_backtrace());
  229.             flush();
  230.         }
  231.         $this->mQueryLap 0;
  232.     }
  233.  
  234.     /**
  235.     * Used to create tables - most commonly from package/schema_inc.php files
  236.     * @todo remove references to BIT_DB_PREFIX, us a member function
  237.     * @param pTables an array of tables and creation information in DataDict
  238.     *  style
  239.     * @param pOptions an array of options used while creating the tables
  240.     * @return true|false
  241.     *  true if created with no errors | false if errors are stored in $this->mFailed
  242.     */
  243.     function createTables($pTables$pOptions array()) {
  244.         // PURE VIRTUAL
  245.     }
  246.  
  247.     /**
  248.     * Used to check if tables already exists.
  249.     * @todo should be used to confirm tables are already created
  250.     * @param pTable the table name
  251.     * @return true if table already exists
  252.     */
  253.     function tableExists($pTable{
  254.         // PURE VIRTUAL
  255.     }
  256.  
  257.     /**
  258.     * Used to drop tables
  259.     * @todo remove references to BIT_DB_PREFIX, us a member function
  260.     * @param pTables an array of table names to drop
  261.     * @return true | false
  262.     *  true if dropped with no errors |
  263.     *  false if errors are stored in $this->mFailed
  264.     */
  265.     function dropTables($pTables{
  266.         // PURE VIRTUAL
  267.     }
  268.  
  269.     /**
  270.     * Function to set ADODB query caching member variable
  271.     * @param pCacheExecute flag to enable or disable ADODB query caching
  272.     * @return nothing 
  273.     */
  274.     function setCaching$pCacheFlag=TRUE {
  275.         $this->mCacheFlag = $pCacheFlag;
  276.     }
  277.  
  278.     /**
  279.     * Function to set ADODB query caching member variable
  280.     * @param pCacheExecute flag to enable or disable ADODB query caching
  281.     * @return nothing 
  282.     */
  283.     function isCachingActive({
  284.         return$this->mCacheFlag );
  285.     }
  286.  
  287.     /**
  288.     * Quotes a string to be sent to the database
  289.     * @param pStr string to be quotes
  290.     * @return quoted string using AdoDB->qstr()
  291.     */
  292.     function qstr($pStr{
  293.         // PURE VIRTUAL
  294.     }
  295.  
  296.     /** Queries the database, returning an error if one occurs, rather
  297.     * than exiting while printing the error. -rlpowell
  298.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  299.     *  and attribute names for AdoDB to quote appropriately.
  300.     * @param pError the error string to modify and return
  301.     * @param pValues an array of values used in a parameterised query
  302.     * @param pNumRows the number of rows (LIMIT) to return in this query
  303.     * @param pOffset the row number to begin returning rows from. Used in
  304.     * @return an AdoDB RecordSet object
  305.     *  conjunction with $pNumRows
  306.     * @todo currently not used anywhere.
  307.     */
  308.     function queryError$pQuery&$pError$pValues NULL$pNumRows = -1$pOffset = -{
  309.         // PURE VIRTUAL
  310.     }
  311.  
  312.     /** Queries the database reporting an error if detected
  313.     * than exiting while printing the error. -rlpowell
  314.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  315.     *  and attribute names for AdoDB to quote appropriately.
  316.     * @param pValues an array of values used in a parameterised query
  317.     * @param pNumRows the number of rows (LIMIT) to return in this query
  318.     * @param pOffset the row number to begin returning rows from. Used in
  319.     *  conjunction with $pNumRows
  320.     * @return an AdoDB RecordSet object
  321.     */
  322.     function query($query$values null$numrows BIT_QUERY_DEFAULT$offset BIT_QUERY_DEFAULT$pCacheTime=BIT_QUERY_DEFAULT {
  323.         // PURE VIRTUAL
  324.     }
  325.  
  326.     /**
  327.     * ADODB compatibility functions for bitcommerce
  328.     */
  329.     function Execute($pQuery$pNumRows false$zf_cache false$pCacheTime=BIT_QUERY_DEFAULT{
  330.         if $this->mType == "firebird"{
  331.             $pQuery preg_replace("/\\\'/""''"$pQuery);
  332.             $pQuery preg_replace("/ NOW/"" 'NOW'"$pQuery);
  333.             $pQuery preg_replace("/now\(\)/""'NOW'"$pQuery);
  334.         }
  335.         return $this->query$pQueryNULL$pNumRowsNULL$pCacheTime );
  336.     }
  337.  
  338.     /**
  339.      * Create a list of tables available in the current database
  340.      *
  341.      * @param ttype can either be 'VIEW' or 'TABLE' or false.
  342.      *          If false, both views and tables are returned.
  343.      *         "VIEW" returns only views
  344.      *         "TABLE" returns only tables
  345.      * @param showSchema returns the schema/user with the table name, eg. USER.TABLE
  346.      * @param mask  is the input mask - only supported by oci8 and postgresql
  347.      *
  348.      * @return  array of tables for current database.
  349.     */
  350.     function MetaTables$ttype false$showSchema false$mask=false {
  351.         // PURE VIRTUAL
  352.     }
  353.  
  354.     /**
  355.      * List columns in a database as an array of ADOFieldObjects.
  356.      * See top of file for definition of object.
  357.      *
  358.      * @param table    table name to query
  359.      * @param upper    uppercase table name (required by some databases)
  360.      * @param schema is optional database schema to use - not supported by all databases.
  361.      *
  362.      * @return  array of ADOFieldObjects for current table.
  363.      */
  364.     function MetaColumns($table,$normalize=true$schema=false{
  365.         // PURE VIRTUAL
  366.     }
  367.  
  368.     /**
  369.      * List indexes in a database as an array of ADOFieldObjects.
  370.      * See top of file for definition of object.
  371.      *
  372.      * @param table    table name to query
  373.      * @param primary list primary indexes
  374.      * @param owner list owner of index
  375.      *
  376.      * @return  array of ADOFieldObjects for current table.
  377.      */
  378.     function MetaIndexes($table,$primary=false$owner=false{
  379.         // PURE VIRTUAL
  380.     }
  381.  
  382.  
  383.     /** Executes the SQL and returns all elements of the first column as a 1-dimensional array. The recordset is discarded for you automatically. If an error occurs, false is returned.
  384.     * See AdoDB GetCol() function for more detail.
  385.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  386.     *  and attribute names for AdoDB to quote appropriately.
  387.     * @param pValues an array of values used in a parameterised query
  388.     * @param pForceArray if set to true, when an array is created for each value
  389.     * @param pFirst2Cols if set to true, only returns the first two columns
  390.     * @return the associative array, or false if an error occurs
  391.     * @todo not currently used anywhere
  392.     */
  393.  
  394.     function getCol$pQuery$pValues=FALSE$pTrim=FALSE {
  395.         // PURE VIRTUAL
  396.     }
  397.     /** Returns an associative array for the given query.
  398.     * See AdoDB GetAssoc() function for more detail.
  399.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  400.     *  and attribute names for AdoDB to quote appropriately.
  401.     * @param pValues an array of values used in a parameterised query
  402.     * @param pForceArray if set to true, when an array is created for each value
  403.     * @param pFirst2Cols if set to true, only returns the first two columns
  404.     * @return the associative array, or false if an error occurs
  405.     */
  406.     function getArray$pQuery$pValues=FALSE$pForceArray=FALSE$pFirst2Cols=FALSE$pCacheTime=BIT_QUERY_DEFAULT {
  407.         // PURE VIRTUAL
  408.     }
  409.  
  410.     /** Returns an associative array for the given query.
  411.     * See AdoDB GetAssoc() function for more detail.
  412.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  413.     *  and attribute names for AdoDB to quote appropriately.
  414.     * @param pValues an array of values used in a parameterised query
  415.     * @param pForceArray if set to true, when an array is created for each value
  416.     * @param pFirst2Cols if set to true, only returns the first two columns
  417.     * @return the associative array, or false if an error occurs
  418.     */
  419.     function getAssoc$pQuery$pValues=FALSE$pForceArray=FALSE$pFirst2Cols=FALSE$pCacheTime=BIT_QUERY_DEFAULT {
  420.         // PURE VIRTUAL
  421.     }
  422.  
  423.     /** Executes the SQL and returns the first row as an array. The recordset and remaining rows are discarded for you automatically. If an error occurs, false is returned.
  424.     * See AdoDB GetRow() function for more detail.
  425.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  426.     *  and attribute names for AdoDB to quote appropriately.
  427.     * @param pValues an array of values used in a parameterised query
  428.     * @return returns the first row as an array, or false if an error occurs
  429.     */
  430.     function getRow$pQuery$pValues=FALSE$pCacheTime=BIT_QUERY_DEFAULT {
  431.         // PURE VIRTUAL
  432.     }
  433.  
  434.     /** Returns a single column value from the database.
  435.     * @param pQuery the SQL query. Use backticks (`) to quote all table
  436.     *  and attribute names for AdoDB to quote appropriately.
  437.     * @param pValues an array of values used in a parameterised query
  438.     * @param pReportErrors report errors to STDOUT
  439.     * @param pOffset the row number to begin returning rows from.
  440.     * @return the associative array, or false if an error occurs
  441.     */
  442.     function getOne($pQuery$pValues=NULL$pNumRows=NULL$pOffset=NULL$pCacheTime BIT_QUERY_DEFAULT {
  443.         // PURE VIRTUAL
  444.     }
  445.  
  446.     /**
  447.     * This function will take a set of fields identified by an associative array - $insertData
  448.     * generate a suitable SQL script
  449.     * and insert the data into the specified table - $insertTable
  450.     * @param insertTable Name of the table to be inserted into
  451.     * @param insertData Array of data to be inserted. Array keys provide the field names
  452.     * @return Error status of the insert
  453.     */
  454.     function associateInsert$insertTable$insertData {
  455.         $setSql '`'.implodearray_keys$insertData )'`, `' ).'`' );
  456.         //stupid little loop to generate question marks. Start at one, and tack at the end to ease dealing with comma
  457.         $valueSql '';
  458.         for$i 1$i count$insertData )$i++ {
  459.             $valueSql .= '?, ';
  460.         }
  461.         $valueSql .= '?';
  462.  
  463.         if$insertTable[0!= '`' {
  464.             $insertTable '`'.$insertTable.'`';
  465.         }
  466.  
  467.         $query "INSERT INTO $insertTable ( $setSql ) VALUES ( $valueSql )";
  468.  
  469.         $result $this->query$queryarray_values$insertData ) );
  470.  
  471.         return$result );
  472.     }
  473.  
  474.     /**
  475.     * This function will take a set of fields identified by an associative array - $updateData
  476.     * generate a suitable SQL script
  477.     * update the data into the specified table
  478.     * at the location identified in updateId which holds a name and value entry
  479.     * @param updateTable Name of the table to be updated
  480.     * @param updateData Array of data to be changed. Array keys provide the field names
  481.     *  If an array key contains an '=' it will assumed to already be properly quoted.
  482.     *  This allows use of keys like this: `column_name` = `column_name` + ?
  483.     * @param updateId Array identifying the record to update.
  484.     *         Array key 'name' provide the field name, and 'value' the record key
  485.     * @return Error status of the insert
  486.     */
  487.     function associateUpdate$updateTable$updateData$updateId {
  488.         $setSql '';
  489.         foreach$updateData as $key=>$value {
  490.             if (strpos($key,'='=== false{
  491.                 $setSql .= ", `$key` = ?";
  492.             }
  493.             else
  494.                 $setSql .= ', ' $key;
  495.             }
  496.         $setSql =     substr($setSql,1);
  497.         $bindVars array_values$updateData );
  498.         $keyNames '`'.implodearray_keys$updateId )'`=? AND `' ).'`=?' );
  499.         $keyVars array_values$updateId );
  500.         $bindVars array_merge$bindVars$keyVars );
  501.         if$updateTable[0!= '`' {
  502.             $updateTable '`'.$updateTable.'`';
  503.         }
  504.  
  505.         $query "UPDATE $updateTable SET $setSql WHERE $keyNames";
  506.         $result $this->query$query$bindVars );
  507.  
  508.         return$result );
  509.     }
  510.  
  511.     /**
  512.     * A database portable Sequence management function.
  513.     *
  514.     * @param pSequenceName Name of the sequence to be used
  515.     *         It will be created if it does not already exist
  516.     * @return        if not supported, otherwise a sequence id
  517.     */
  518.     function GenID$pSequenceName$pUseDbPrefix true {
  519.         // PURE VIRTUAL
  520.     }
  521.  
  522.     /**
  523.     * A database portable Sequence management function.
  524.     *
  525.     * @param pSequenceName Name of the sequence to be used
  526.     *         It will be created if it does not already exist
  527.     * @param pStartID Allows setting the initial value of the sequence
  528.     * @return        if not supported, otherwise a sequence id
  529.     * @todo    To be combined with GenID
  530.     */
  531.     function CreateSequence($seqname='adodbseq',$startID=1{
  532.         // PURE VIRTUAL
  533.     }
  534.  
  535.     /**
  536.     * A database portable IFNULL function.
  537.     *
  538.     * @param pField argument to compare to NULL
  539.     * @param pNullRepl the NULL replacement value
  540.     * @return string that represents the function that checks whether
  541.     *  $pField is NULL for the given database, and if NULL, change the
  542.     *  value returned to $pNullRepl.
  543.     */
  544.     function ifNull($pField$pNullRepl{
  545.         // PURE VIRTUAL
  546.     }
  547.  
  548.     /** Format the timestamp in the format the database accepts.
  549.     * @param pDate a Unix integer timestamp or an ISO format Y-m-d H:i:s
  550.     * @return the timestamp as a quoted string.
  551.     * @todo could be used to later convert all int timestamps