Changeset 47

Show
Ignore:
Timestamp:
04/06/08 19:43:09 (2 years ago)
Author:
malko
Message:
  • first real sqlite3db version (not tested but should work so please report any problem)
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/class-sqlite3db.php

    r28 r47  
    11<?php 
    2 # load base class  
    3 if(! class_exists('db')) 
    4     require(dirname(__file__).'/class-db.php'); 
    5  
    62/** 
    7 * @author Jonathan Gotti <nathan at the-ring dot homelinux dot net> 
    8 * @copyleft (l) 2003-2004  Jonathan Gotti 
     3* @author Jonathan Gotti <jgotti at jgotti dot org> 
     4* @copyleft (l) 2008  Jonathan Gotti 
    95* @package DB 
     6* @since 2008-04 
    107* @license http://opensource.org/licenses/gpl-license.php GNU Public License 
    11 * @subpackage SQLITE 
    12 * @changelog 2006-05-12 - clean the escape_string() method 
    13 *            2006-04-17 - rewrite the class to use abstarction class db 
    14 *                       - Conditions params support on methods select_*, update, delete totally rewrite to handle smat question mark 
    15 *                         @see db::process_conds() 
    16 *                       - get_field and list_fields are now deprecated but still supported (listfield will be indexed by name whatever is $indexed_by_name) 
    17 *            2005-02-25 - now the associative_array_from_q2a_res method won't automaticly ksort the results anymore 
    18 *                       - re-enable the possibility to choose between SQLITE_ASSOC or SQLITE_NUM 
    19 *            2005-02-28 - new method optimize and vacuum 
    20 *            2005-04-05 - get_fields will now try to get fields from sqlite_master if no data found in the table 
     8* @subpackage SQLITE3 
    219* @todo add transactions support 
    22 * @todo add check_conn method 
    2310*/ 
    24 class sqlitedb extends db{ 
    25   public $buffer_on = TRUE; 
    26   public $autocreate= FALSE; 
     11 
     12class sqlite3db{ 
     13  public $autocreate= TRUE; 
     14 
    2715  public $db_file = ''; 
    2816  public $_protect_fldname = "'"; 
    29   /** use the sqlite3 version of sqlite extension */ 
    30   public $useSqlite3 = true; 
    3117  /** 
    3218  * create a sqlitedb object for managing locale data 
     
    3521  * @return sqlitedb object 
    3622  */ 
    37   function sqlitedb($db_file,$mode=null){ 
    38     # readwrite mode to open database 
    39     switch ($mode){ 
    40       case 'r': 
    41         $mod = 0444; 
    42         break; 
    43       case 'w': 
    44         $mod = 0666; 
    45         break; 
    46       default: 
    47                                 $mod = is_numeric($mode)?$mode:0666; 
    48     } 
    49     $this->mode = $mod; 
    50                 if($this->mode >= 0600) 
    51                         $this->autocreate = true; 
     23  function sqlitedb($db_file){ 
    5224    $this->host = 'localhost'; 
    5325    $this->db_file = $db_file; 
    5426    $this->conn = &$this->db; # only for better compatibility with other db implementation 
    55                 if($this->autoconnect) 
     27                if(db::$autoconnect) 
    5628                        $this->open(); 
    5729  } 
    58 ###*** REQUIRED METHODS FOR EXTENDED CLASS ***### 
     30 
     31        ###*** REQUIRED METHODS FOR EXTENDED CLASS ***### 
    5932  /** open connection to database */ 
    6033  function open(){ 
     
    6639    if(! (is_file($this->db_file) || $this->autocreate) ) 
    6740      return FALSE; 
    68     $this->db = $this->useSqlite3?sqlite3_open($this->db_file):sqlite_open($this->db_file, $this->mode); 
    69     if( $this->db){ 
     41    if( $this->db = sqlite3_open($this->db_file)){ 
    7042      return $this->db; 
    7143    }else{ 
    72       $this->verbose('Can\'t open database connection',__function__); 
    73       return FALSE; 
    74     } 
    75   } 
    76  
     44      $this->verbose(,__FUNCTION__,1); 
     45      return FALSE; 
     46    } 
     47  } 
    7748  /** close connection to previously opened database */ 
    7849  function close(){ 
    7950    if( !is_null($this->db) ){ 
    80       if($this->useSqlite3){ 
    81         if($this->last_qres) 
    82           sqlite3_query_close($this->last_qres); 
    83         sqlite3_close($this->db); 
    84       }else{ 
    85         sqlite_close($this->db); 
    86       } 
     51        if($this->last_qres) 
     52        sqlite3_query_close($this->last_qres); 
     53      sqlite3_close($this->db); 
    8754    } 
    8855    $this->db = null; 
     56  } 
     57 
     58  /** 
     59  * check and activate db connection 
     60  * @param string $action (active, kill, check) active by default 
     61  * @return bool 
     62  */ 
     63  function check_conn($action = ''){ 
     64        if(! $this->db)){ 
     65                if($action !== 'active') 
     66                        return $action==='kill'?true:false; 
     67      return $this->open()===false?false:true; 
     68    }else{ 
     69        if($action==='kill'){ 
     70                                $this->close(); 
     71                                $this->db = null; 
     72                        } 
     73        return true; 
     74    } 
    8975  } 
    9076 
     
    9884    if(! in_array($result_type,array('NUM','ASSOC','BOTH')) ) 
    9985      $result_type = 'ASSOC'; 
    100     eval('$result_type = SQLITE_'.$result_type.';'); 
    101     if($this->useSqlite3){ 
    102       if($result_type===SQLITE_ASSOC){ 
    103         while($res[]=sqlite3_fetch_array($result_set)); 
    104         unset($res[count($res)-1]);//unset last empty row 
    105       }elseif($result_type===SQLITE_NUM){ 
    106         while($res[]=sqlite3_fetch($result_set)); 
    107         unset($res[count($res)-1]);//unset last empty row 
    108       }else{ 
    109         while($row=sqlite3_fetch_array($result_set)){ 
    110           $res[] = array_merge($row,array_values($row)); 
    111         }; 
    112       } 
    113     }else{ 
    114       while($res[]=sqlite_fetch_array($result_set,$result_type)); 
    115       unset($res[count($res)-1]);//unset last empty row 
    116     } 
    117     if( empty($res) ) 
     86                if($result_type==='ASSOC'){ 
     87                        while($res[]=sqlite3_fetch_array($result_set)); 
     88                        unset($res[count($res)-1]);//unset last empty row 
     89                }elseif($result_type==='NUM'){ 
     90                        while($res[]=sqlite3_fetch($result_set)); 
     91                        unset($res[count($res)-1]);//unset last empty row 
     92                }else{ 
     93                        while($row=sqlite3_fetch_array($result_set)){ 
     94                                $res[] = array_merge($row,array_values($row)); 
     95                        }; 
     96                } 
     97                if( empty($res) ) 
    11898      return $this->last_q2a_res = false; 
    11999    $this->num_rows = count($res); 
     
    122102 
    123103  function last_insert_id(){ 
    124     return $this->db?($this->useSqlite3?sqlite3_last_insert_rowid($this->db):sqlite_last_insert_rowid($this->db)):FALSE; 
     104    return $this->db?sqlite3_last_insert_rowid($this->db):FALSE; 
    125105  } 
    126106 
     
    132112  function query($Q_str){ 
    133113    if(! $this->db ){ 
    134       if(! ($this->autoconnect && $this->open()) ) 
     114      if(! (db::$autoconnect && $this->open()) ) 
    135115        return FALSE; 
    136116    } 
    137                 if($this->beverbose) 
    138                         echo "$Q_str\n"; 
    139     if($this->buffer_on || $this->useSqlite3){ 
    140       $this->last_qres = $this->useSqlite3?sqlite3_query($this->db,$Q_str):sqlite_query($this->db,$Q_str); 
    141       #- if($this->useSqlite3 && $this->last_qres) 
    142         #- sqlite3_query_exec($this->last_qres); 
    143     }else{ 
    144       $this->last_qres = sqlite_unbuffered_query($this->db,$Q_str); 
    145     } 
     117          $this->verbose($Q_str,__FUNCTION__,2); 
     118          if($this->last_qres)#- close unclosed previous qres 
     119                sqlite3_query_close($this->last_qres); 
     120    $this->last_qres = sqlite3_query($this->db,$Q_str); 
    146121    if(! $this->last_qres) 
    147122      $this->set_error(__FUNCTION__); 
    148123    return $this->last_qres; 
    149124  } 
    150    
     125 
    151126  /** 
    152127  * perform a query on the database like query but return the affected_rows instead of result 
     
    160135    if(! $this->query($Q_str) ) 
    161136      return FALSE; 
    162     return $this->useSqlite3?sqlite3_changes($this->db):sqlite_changes($this->db); 
     137    return sqlite3_changes($this->db); 
    163138  } 
    164139 
     
    172147  function list_table_fields($table,$extended_info=FALSE){ 
    173148    # Try the simple method 
    174     if( false&& (! $extended_info) && $res = $this->query_to_array("SELECT * FROM $table LIMIT 0,1")){ 
     149    if( (! $extended_info) && $res = $this->query_to_array("SELECT * FROM $table LIMIT 0,1")){ 
    175150      return array_keys($res[0]); 
    176     }else{ # There 's no row in this table so we try an alternate method or we want extended infos             
     151    }else{ # There 's no row in this table so we try an alternate method or we want extended infos 
    177152      if(! $fields = $this->query_to_array("SELECT sql FROM sqlite_master WHERE type='table' AND name ='$table'") ) 
    178153        return FALSE; 
     
    182157      $type = "((?:[a-z]+)\s*(?:\(\s*\d+\s*(?:,\s*\d+\s*)?\))?)?\s*"; 
    183158      $default = '(?:DEFAULT\s+((["\']).*?(?<!\\\\)\\4|[^\s,]+))?\s*'; 
    184       if( preg_match_all('/\[?(\w+)\]?\s+'.$type.$default.'[^,]*(,|\))/i',$flds_str,$m,PREG_SET_ORDER) ){ 
     159      if( preg_match_all('/(\w+)\s+'.$type.$default.'[^,]*(,|\))/i',$flds_str,$m,PREG_SET_ORDER) ){ 
    185160        $key  = "PRIMARY|UNIQUE|CHECK"; 
    186161        $Extra = 'AUTOINCREMENT'; 
     
    221196  /** Verifier si cette methode peut s'appliquer a SQLite * / 
    222197  function show_table_keys($table){} 
    223    
     198 
    224199  /** 
    225200  * optimize table statement query 
     
    240215  } 
    241216 
    242   function error_no(){ 
    243     return $this->db?($this->useSqlite3?sqlite3_error($this->db):sqlite_last_error($this->db)):FALSE; 
    244   } 
    245          
    246         function error_str($errno=null){ 
    247     return sqlite_error_string($errno); 
    248   } 
    249  
    250217  /** 
    251218  * base method you should replace this one in the extended class, to use the appropriate escape func regarding the database implementation 
     
    254221  */ 
    255222  function escape_string($string,$quotestyle='both'){ 
    256     $string = sqlite_escape_string($string); 
    257     switch(strtolower($quotestyle)){ 
    258       case 'double': 
    259       case 'd': 
    260       case '"': 
    261         $string = str_replace("''","'",$string); 
    262         $string = str_replace('"','\"',$string); 
    263         break; 
    264       case 'single': 
    265       case 's': 
    266       case "'": 
    267         break; 
    268       case 'both': 
    269       case 'b': 
    270       case '"\'': 
    271       case '\'"': 
    272         $string = str_replace('"','\"',$string); 
    273         break; 
    274     } 
    275     return $string; 
    276   } 
     223 
     224                if( function_exists('sqlite_escape_string') ){ 
     225                        $string = sqlite_escape_string($string); 
     226                        $string = str_replace("''","'",$string); #- no quote escaped so will work like with no sqlite_escape_string available 
     227                }else{ 
     228                        $escapes = array("\x00", "\x0a", "\x0d", "\x1a", "\x09","\\"); 
     229                        $replace = array('\0',   '\n',    '\r',   '\Z' , '\t',  "\\\\"); 
     230                } 
     231                switch(strtolower($quotestyle)){ 
     232                        case 'double': 
     233                        case 'd': 
     234                        case '"': 
     235                                $escapes[] = '"'; 
     236                                $replace[] = '\"'; 
     237                                break; 
     238                        case 'single': 
     239                        case 's': 
     240                        case "'": 
     241                                $escapes[] = "'"; 
     242                                $replace[] = "''"; 
     243                                break; 
     244                        case 'both': 
     245                        case 'b': 
     246                        case '"\'': 
     247                        case '\'"': 
     248                                $escapes[] = '"'; 
     249                                $replace[] = '\"'; 
     250                                $escapes[] = "'"; 
     251                                $replace[] = "''"; 
     252                                break; 
     253                } 
     254                return str_replace($escapes,$replace,$string); 
     255        } 
     256 
     257  function error_no(){ 
     258        $this->verbose('sqlite3 driver doesn\'t support this method',__function__,1); 
     259  }; 
     260 
     261        function error_str($errno=null){ 
     262    return sqlite3_error($this->db); 
     263  } 
     264 
     265  protected function set_error($callingfunc=null){ 
     266                static $i=0; 
     267                if(! $this->db ){ 
     268                        $this->error[$i] = '[ERROR] No Db Handler'; 
     269                }else{ 
     270                        $this->error[$i] =  $this->error_str(); 
     271                } 
     272                $this->last_error = $this->error[$i]; 
     273    $this->verbose($this->error[$i],$callingfunc,1); 
     274                $i++; 
     275        } 
    277276} 
    278  
    279 ?>