home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / EasyPHP-2.0b1-setup.exe / {app} / sqlitemanager / include / SQLiteDbConnect.class.php < prev    next >
Encoding:
PHP Script  |  2006-04-18  |  11.9 KB  |  399 lines

  1. <?php
  2. /**
  3. * Web based SQLite management
  4. * Class for manage connection to a user database
  5. * @package SQLiteManager
  6. * @author FrΘdΘric HENNINOT
  7. * @version $Id: SQLiteDbConnect.class.php,v 1.32 2006/04/15 16:49:20 freddy78 Exp $ $Revision: 1.32 $
  8. */
  9.  
  10. class SQLiteDbConnect {
  11.     
  12.     /**
  13.     * Database name
  14.     *
  15.     * @access private
  16.     * @var strig
  17.     */
  18.     var $baseName;
  19.     
  20.     /**
  21.     * Resource connection
  22.     * 
  23.     * @access public
  24.     * @var resource
  25.     */
  26.     var $connId;
  27.     
  28.     /**
  29.     * Result resource
  30.     * 
  31.     * @access public
  32.     * @var resource
  33.     */
  34.     var $resId;
  35.     
  36.     /**
  37.     * Error from connection to database
  38.     *
  39.     * @access public
  40.     * @var bool
  41.     */
  42.     var $connError;
  43.     
  44.     /**
  45.     * User defines function list
  46.     *
  47.     * @access public
  48.     * @var array
  49.     */
  50.     var $functInfo;    
  51.     
  52.     /**
  53.     * Last query Execution Time (msec)
  54.     *
  55.     * @access public
  56.     * @var integer
  57.     */
  58.     var $queryTime;
  59.     
  60.     /**
  61.     * Information if the database is writable or not
  62.     * @access private
  63.     * @var boolean
  64.     */
  65.     var $readOnly;
  66.     
  67.     var $errorMessage;
  68.             
  69.     /**
  70.     * Class constructor
  71.     *
  72.     * @access public
  73.     * @param string $base database name
  74.     */
  75.     function SQLiteDbConnect($base){
  76.         $this->baseName = $base;
  77.         $this->readOnly = !is_writeable($base);
  78.         $this->connId = $GLOBALS['SQLiteFactory']->sqliteGetInstance($base);
  79.         if(is_object($this->connId)) $this->readOnly = $this->connId->isReadOnly();
  80.         return $this->connId;
  81.     }
  82.     
  83.     /**
  84.     * return true if database is writeable
  85.     *
  86.     * @access public
  87.     */
  88.     function isReadOnly(){
  89.         return $this->readOnly;
  90.     }
  91.  
  92.     function isReadable(){
  93.         if(is_object($this->connId)) return true;
  94.         else return false;
  95.     }
  96.     
  97.     /**
  98.     * Return database properties
  99.     *
  100.     * @access public
  101.     * @param string $type type of properties (table, view...)
  102.     */
  103.     function getPropList($type){
  104.         $propList = array();
  105.         if($type!='Function'){
  106.             $from = 'FROM sqlite_master WHERE type='.quotes(strtolower($type)).' ORDER BY name;';
  107.             $queryCount = 'SELECT count(*) as nb ' . $from;
  108.             
  109.             // disabled table disapear
  110.             $nbIntoItem = '';
  111.             while($nbIntoItem == '') {
  112.                 $resCount = $this->connId->query($queryCount);
  113.                 $nbIntoItem = $this->connId->fetch_single($resCount);
  114.             }
  115.             $query = 'SELECT name ' . $from;
  116.             
  117.             $tabTempProp = $this->connId->array_query($query);
  118.             if(is_array($tabTempProp)) {
  119.                 foreach($tabTempProp as $propInfo)
  120.                 $propList[] = $propInfo['name'];
  121.             }
  122.         } else {
  123.             $query = 'SELECT funct_name FROM user_function WHERE (base_id='.$GLOBALS['dbsel'].' OR base_id IS NULL)';
  124.             if( $GLOBALS['db']->query($query) ){
  125.                 while($ligne = $GLOBALS['db']->fetch_array(null, SQLITE_ASSOC)) $propList[] = $ligne['funct_name'];
  126.             }                
  127.         }
  128.         return $propList;
  129.     }
  130.     
  131.     /**
  132.     * Close connection to database
  133.     *
  134.     * @access public
  135.     */
  136.     function close(){
  137.         $this->connId = null;
  138.         return;
  139.     }
  140.     
  141.     /**
  142.     * Exec a query and return the resource result
  143.     *
  144.     * @access public
  145.     * @param string $query 
  146.     * @param bool $buffer
  147.     */
  148.     function getResId($query, $buffer=true){
  149.         $time_start = microtime();
  150.         $this->resId = $this->connId->query($query, $buffer);
  151.         $this->queryTime = round((microtime() - $time_start) * 1000,2);
  152.         return $this->resId;        
  153.     }
  154.     
  155.     /**
  156.     * return array of result
  157.     *
  158.     * @access public
  159.     * @param string $type
  160.     */
  161.     function getArray($type = ''){
  162.         if(is_resource($this->connId->resId) || is_object($this->connId->resId)){
  163.             $tabOut = array();
  164.             while($row = $this->connId->fetch_array(null, (($type=='')? SQLITE_ASSOC : $type ))) $tabOut[] = $row;
  165.             return $tabOut;
  166.         } else {
  167.             return false;
  168.         }
  169.     }
  170.     
  171.     /**
  172.     * Manage ALTER TABLE, not exist in SQLite
  173.     * 
  174.     * @access public
  175.     * @param string $table Table name
  176.     * @param string $newDefinition SQL definition of CREATE TABLE
  177.     * @param array $oldColumn Array of all the column
  178.     * @param array $newColumn Array of all new column
  179.     */
  180.     function alterTable($table, $newDefinition, $oldColumn, $newColumn, $nullToNotNull = array()){
  181.         // get the index definition
  182.         $queryIndex = "SELECT DISTINCT sql FROM sqlite_master WHERE tbl_name='".$table."' AND type='index' AND sql IS NOT NULL";
  183.         $listIndex = $GLOBALS['workDb']->connId->array_query($queryIndex);
  184.         $query[] = "BEGIN TRANSACTION;\n";
  185.         $query[] = "CREATE TEMPORARY TABLE SQLIteManager_backup AS SELECT * FROM ".brackets($table).";\n";
  186.         if(!empty($nullToNotNull)) {
  187.             foreach($nullToNotNull as $newNotNull) {
  188.                 $query[] = "UPDATE SQLIteManager_backup SET ".$newNotNull."='' WHERE ".$newNotNull." IS NULL;";
  189.             }
  190.         }
  191.         $query[] = "DROP TABLE ".brackets($table).";\n";    
  192.         $query[] = $newDefinition."\n";        
  193.         $query[] = "INSERT INTO ".brackets($table)." (".implode(", ", $newColumn).") SELECT ".implode(", ", $oldColumn)." FROM SQLIteManager_backup;\n";
  194.         $query[] = "DROP TABLE SQLIteManager_backup;\n";
  195.         $query[] = "COMMIT TRANSACTION;\n";
  196.         $error = false;
  197.         foreach($query as $req) {
  198.             if(!$error && !$this->getResId($req)) {
  199.                 $error = true;
  200.                 $this->errorMessage = '<table style="color: red;"><tr><td>'.$GLOBALS['traduct']->get(9).' :</td><td>'.$this->connId->getError().'</td></tr>';
  201.                 if($GLOBALS['phpSQLiteError'] != '') $this->errorMessage .= '<tr><td> </td><td>'.$GLOBALS['phpSQLiteError'].'</td></tr>';
  202.                 $this->errorMessage .= '</table>';
  203.                 $this->getResId("ROLLBACK TRANSACTION;");
  204.                 return $error;
  205.             }
  206.         }
  207.         if(!$error && is_array($listIndex)){
  208.             foreach($listIndex as $indexSQL=>$tabSQL){
  209.                 if(!$error && !$this->getResId($tabSQL['sql'])) {
  210.                     $error = true;
  211.                     $this->getResId("ROLLBACK TRANSACTION;");
  212.                     return $error;
  213.                 }
  214.             }
  215.         }
  216.         return $error;
  217.     }
  218.     
  219.     /**
  220.     * Return properties of all user defined function
  221.     *
  222.     * @access public
  223.     */
  224.     function getUDF(){
  225.         $query = 'SELECT id, base_id, funct_type, funct_name, funct_code, funct_final_code, funct_num_args FROM user_function WHERE (base_id='.$GLOBALS['dbsel'].' OR base_id IS NULL)';
  226.             if( $GLOBALS['db']->query($query) ){
  227.                 while($ligne = $GLOBALS['db']->fetch_array(null, SQLITE_ASSOC)) $this->functInfo[$ligne['id']] = $ligne;
  228.             }
  229.         return $this->functInfo;            
  230.     }
  231.     
  232.     /**
  233.     * Insert user defines function in the executable context to use this in SQL
  234.     *
  235.     * @access public
  236.     */
  237.     function includeUDF(){
  238.         $tabFunct = $this->getUDF();
  239.         if(!isset($GLOBALS["UDF_declared"])) $GLOBALS["UDF_declared"] = array(); 
  240.         if(is_array($tabFunct)){
  241.             foreach($tabFunct as $infoFunct){
  242.                 switch($infoFunct['funct_type']){
  243.                     case 1:    // function utilisateur standard
  244.                         $code = $infoFunct['funct_code'];
  245.                         $funcName = $this->_getPHPfunctionName($code);
  246.                         if(!in_array($funcName, $GLOBALS["UDF_declared"]) && !function_exists($funcName)) {
  247.                             $GLOBALS["UDF_declared"][] = $funcName;
  248.                             $retEval = eval($code);
  249.                         }
  250.                         if($this->connId) $this->connId->create_function($infoFunct['funct_name'], $funcName, $infoFunct['funct_num_args']);
  251.                         break;
  252.                     case 2:    // function utilisateur d'aggregation
  253.                         $codeStep = $infoFunct['funct_code'];
  254.                         $codeFinal = $infoFunct['funct_final_code'];
  255.                         $funcStepName = $this->_getPHPfunctionName($codeStep);
  256.                         if(!in_array($funcStepName, $GLOBALS["UDF_declared"]) && !function_exists($funcStepName)) {
  257.                             $GLOBALS["UDF_declared"][] = $funcStepName;                    
  258.                             eval($codeStep);
  259.                         }
  260.                         $funcFinalName = $this->_getPHPfunctionName($codeFinal);
  261.                         if(!in_array($funcFinalName, $GLOBALS["UDF_declared"]) && !function_exists($funcFinalName)) {
  262.                             $GLOBALS["UDF_declared"][] = $funcFinalName;                    
  263.                             eval($codeFinal);
  264.                         }
  265.                         if($this->connId) $this->connId->create_aggregate ($infoFunct['funct_name'], $this->_getPHPfunctionName($codeStep), $this->_getPHPfunctionName($codeFinal), $infoFunct['funct_num_args']);
  266.                         break;
  267.                 }
  268.             }
  269.         }
  270.     }
  271.     
  272.     /**
  273.     * Retreive function name from PHP code
  274.     *
  275.     * @access private
  276.     * @param string $code PHP code
  277.     */
  278.     function _getPHPfunctionName($code){
  279.         preg_match("|function[ ]+(.*)[\(](.*)[\)]|U", $code, $value);
  280.         return trim($value[1]);        
  281.     }
  282.     
  283.     /**
  284.     * Escape string To SQLite
  285.     *
  286.     * @access public
  287.     * @param string $string
  288.     */
  289.     function formatString($string){
  290.         return @$this->connId->escape(stripslashes($string));
  291.     }
  292.     
  293.     /**
  294.     * Get attach database list
  295.     *
  296.     * @access public
  297.     */
  298.     function getAttachDb(){
  299.         $query = '    SELECT attachment.id AS ATID, attach_id, location, name 
  300.                     FROM attachment 
  301.                         LEFT JOIN database ON database.id=attachment.attach_id 
  302.                     WHERE base_id='.$GLOBALS['dbsel'];
  303.         $tabAttach = $GLOBALS['db']->array_query($query, SQLITE_ASSOC);
  304.         $tabout = array();
  305.         foreach($tabAttach as $infoAttach) {
  306.           //fix when one db attached more than one time
  307.           if(isset($tabout[$infoAttach['attach_id']]))
  308.               while (count($tabout[$infoAttach['attach_id']])) $infoAttach['attach_id'].=' ';
  309.           
  310.             $tabout[$infoAttach['attach_id']]['id']         = $infoAttach['ATID'];
  311.             $tabout[$infoAttach['attach_id']]['location']     = $infoAttach['location'];
  312.             $tabout[$infoAttach['attach_id']]['name']         = $infoAttach['name'];
  313.         }
  314.         return $tabout;
  315.     }
  316.     
  317.     /**
  318.      *
  319.      */
  320.     function copyTable($source, $destination, $copy = true){
  321.         if(strpos($source, ".")){
  322.             list($srcDb, $srcTable)     = explode('.', $source);
  323.         } else {
  324.             $srcDb = "";
  325.             $srcTable = $source;
  326.         }
  327.         if(strpos($destination, ".")){
  328.             list($dstDb, $dstable)         = explode('.', $destination);
  329.         } else {
  330.             $dstDb = "";
  331.             $dstable = $destination;
  332.         }
  333.         
  334.         $res = $GLOBALS['workDb']->getResId('PRAGMA table_info('.brackets($srcTable).');');
  335.         $infoTable = $GLOBALS['workDb']->getArray();    
  336.         foreach($infoTable as $iT) $listField[$iT["cid"]] = $iT["name"];
  337.         
  338.         // backup table schema
  339.         $backupSchema = $GLOBALS['workDb']->connId->array_query("SELECT sql FROM sqlite_master WHERE tbl_name LIKE '".$srcTable."' ORDER BY ROWID", SQLITE_ASSOC);
  340.         if($dstDb) {
  341.             // create an instance on this
  342.             $GLOBALS["db"]->query("SELECT location FROM database WHERE name='".$dstDb."'");
  343.             $dbLocation = $GLOBALS["db"]->fetch_single();
  344.             if(dirname($dbLocation) == '.') $dbLocation = DEFAULT_DB_PATH . $dbLocation;
  345.             $tempDb = &new SQLiteDbConnect($dbLocation);
  346.             $query[] = "ATTACH DATABASE \"".$dbLocation."\" AS \"".$dstDb."\";\n";
  347.         }
  348.         $query[] = "BEGIN TRANSACTION;\n";
  349.         $query[] = "CREATE TABLE SQLIteManager_backup AS SELECT * FROM ".brackets($srcTable).";\n";
  350.         
  351.         if(isset($_REQUEST["dropTable"]) && ($_REQUEST["dropTable"]=="true")){
  352.             $res = $GLOBALS["workDb"]->connId->query("SELECT count(*) FROM sqlite_master WHERE name='".brackets($dstable)."'");
  353.             if($exist = $GLOBALS["workDb"]->connId->fetch_single()) $query[] = "DROP TABLE ".brackets($dstable).";\n";
  354.         }
  355.                 
  356.         if(!$copy) $query[] = "DROP TABLE ".brackets($srcTable).";\n";    
  357.  
  358.         if(!$copy || ($copy && (($_REQUEST["whatToDo"]=="structure") || ($_REQUEST["whatToDo"]=="data"))) ) {
  359.             foreach($backupSchema as $schema) {
  360.                 $tempQuery = $schema["sql"];
  361.                 if(isset($tempQuery) && eregi("CREATE[[:space:]]TABLE", $tempQuery)) {
  362.                     $tempQuery = ereg_replace("CREATE[[:space:]]TABLE[[:space:]]".$srcTable, "CREATE TABLE ".brackets($dstable), $tempQuery);
  363.                     if($dstDb) {
  364.                         if(isset($_REQUEST["dropTable"]) && ($_REQUEST["dropTable"]=="true")){
  365.                             // check if table exist and drop it
  366.                             $res = $tempDb->connId->query("SELECT count(*) FROM sqlite_master WHERE name='".brackets($dstable)."'");
  367.                             $exist = $tempDb->connId->fetch_single();
  368.                             if($exist) $query[] = "DROP TABLE ".brackets($dstable);
  369.                         }
  370.                         $tempDb->connId->query($tempQuery);
  371.                         print_r($tempDb->connId);
  372.                         unset($tempQuery);
  373.                     }
  374.                 }
  375.                 
  376.                 if(isset($tempQuery) && eregi("[[:space:]]INTO[[:space:]]", $tempQuery)) {
  377.                     $tempQuery = eregi_replace("^[[:space:]]INTO[[:space:]]".$srcTable, " INTO ".$destination, $tempQuery);            
  378.                 }
  379.                 
  380.                 if(isset($tempQuery) && eregi("CREATE[[:space:]]TRIGGER[[:space:]]", $tempQuery)) unset($tempQuery);
  381.     
  382.                 if(isset($tempQuery) && $tempQuery) $query[] = $tempQuery;
  383.             }
  384.         }
  385.         if(!$copy || ($copy && (($_REQUEST["whatToDo"]=="data") || ($_REQUEST["whatToDo"]=="dataonly"))) )
  386.             $query[] = "INSERT INTO ".brackets($destination)." (".implode(", ", $listField).") SELECT ".implode(", ", $listField)." FROM SQLIteManager_backup;\n";
  387.         $query[] = "DROP TABLE SQLIteManager_backup;\n";
  388.         $query[] = "COMMIT TRANSACTION;\n";
  389.         $noerror = false;
  390.         foreach($query as $req){
  391.             if(!$noerror) {
  392.                 if(!$this->connId->query($req) && !$this->connId->getError()) $noerror = true;
  393.             }
  394.         }
  395.         return $noerror;        
  396.     }
  397. }
  398. ?>
  399.