source: github/program/include/rcube_db.inc @ d7cb774

HEADcourier-fixdev-browser-capabilitiespdorelease-0.6release-0.7release-0.8
Last change on this file since d7cb774 was d7cb774, checked in by svncommit <devs@…>, 8 years ago

more pear/mdb2 integration

  • Property mode set to 100755
File size: 8.5 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/include/rcube_db.inc                                          |
6 |                                                                       |
7 | This file is part of the RoundCube Webmail client                     |
8 | Copyright (C) 2005, RoundCube Dev. - Switzerland                      |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   PEAR:DB wrapper class that implements PEAR DB functions             |
13 |   See http://pear.php.net/package/DB                                  |
14 |                                                                       |
15 +-----------------------------------------------------------------------+
16 | Author: David Saez Padros <david@ols.es>                              |
17 +-----------------------------------------------------------------------+
18
19 $Id$
20
21*/
22
23require_once('DB.php');
24
25class rcube_db
26{
27    var $db_dsnw;               // DSN for write operations
28    var $db_dsnr;               // DSN for read operations
29    var $db_connected=false;    // Already connected ?
30    var $db_mode='';            // Connection mode
31    var $db_handle=0;           // Connection handle
32
33    var $a_query_results = array('dummy');
34    var $last_res_id = 0;
35
36    // PHP 5 constructor
37    function __construct($db_dsnw,$db_dsnr='')
38    {
39        if ($db_dsnr=='') $db_dsnr=$db_dsnw;
40       
41        $this->db_dsnw = $db_dsnw;
42        $this->db_dsnr = $db_dsnr;
43       
44        $dsn_array = DB::parseDSN($db_dsnw);
45        $this->db_provider = $dsn_array['phptype'];       
46    }
47
48    // PHP 4 compatibility
49    function rcube_db($db_dsnw,$db_dsnr='')
50    {
51        $this->__construct($db_dsnw,$db_dsnr);
52    }
53
54    // Connect to specific database
55    function dsn_connect($dsn)
56    {
57        // Use persistent connections if available
58        $dbh = DB::connect($dsn, array('persistent' => $true));
59       
60        if (DB::isError($dbh))
61            raise_error(array('code' => 500,
62                        'type' => 'db',
63                        'line' => __LINE__,
64                        'file' => __FILE__,
65                        'message' => $dbh->getMessage()), TRUE, FALSE);
66
67        else if ($this->db_provider=='sqlite')
68        {
69            $dsn_array = DB::parseDSN($dsn);
70            if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials))
71                $this->_sqlite_create_database($dbh, $this->sqlite_initials);
72        }
73       
74        return $dbh;
75    }
76
77    // Connect to appropiate databse   
78    function db_connect ($mode)
79    {
80        $this->db_mode = $mode;
81
82        // Already connected
83        if ($this->db_connected)
84            {
85            // no replication, current connection is ok
86            if ($this->db_dsnw==$this->db_dsnr) return;
87           
88            // connected to master, current connection is ok
89            if ($this->db_mode=='w') return;
90
91            // Same mode, current connection is ok
92            if ($this->db_mode==$mode) return;
93            }
94           
95        if ($mode=='r')
96            $dsn=$this->db_dsnr;
97        else
98            $dsn=$this->db_dsnw;
99
100        $this->db_handle = $this->dsn_connect($dsn);
101        $this->db_connected = true;
102    }
103
104    // Query database
105   
106    function query()
107    {
108                $params = func_get_args();
109                $query = array_shift($params);
110               
111                return $this->_query($query, 0, 0, $params);
112    }
113   
114        function limitquery()
115    {
116                $params = func_get_args();
117                $query = array_shift($params);
118                $offset = array_shift($params);
119                $numrows = array_shift($params);
120               
121                return $this->_query($query, $offset, $numrows, $params);
122    }
123   
124    function _query($query, $offset, $numrows, $params)
125    {
126        // Read or write ?
127        if (strtolower(trim(substr($query,0,6)))=='select')
128            $mode='r';
129        else
130            $mode='w';
131       
132        $this->db_connect($mode);
133
134        if ($this->db_provider == 'sqlite')
135            $query = $this->_sqlite_prepare_query($query);
136       
137        if ($numrows || $offset)
138                        {
139                        $result = $this->db_handle->limitQuery($query,$offset,$numrows,$params);
140                        }
141        else   
142                        $result = $this->db_handle->query($query,$params);
143
144        if (DB::isError($result))
145                        {
146            raise_error(array('code' => 500,
147                              'type' => 'db',
148                              'line' => __LINE__,
149                              'file' => __FILE__,
150                              'message' => $result->getMessage()), TRUE, FALSE);
151             return false;
152            }
153
154        return $this->_add_result($result, $query);
155    }
156   
157    function num_rows($res_id=NULL)
158    {
159        if (!$this->db_handle)
160            return FALSE;
161
162        $result = $this->_get_result($res_id);
163   
164        if ($result)   
165              return $result->numRows();
166        else
167              return FALSE;
168    }
169
170    function affected_rows($res_id=NULL)
171    {
172        if (!$this->db_handle)
173            return FALSE;
174   
175        return $this->db_handle->affectedRows();
176    }
177
178    function insert_id($sequence = '')
179    {
180        if (!$this->db_handle || $this->db_mode=='r')
181            return FALSE;
182
183        switch($this->db_provider)
184        {
185            case 'pgsql':
186                // PostgreSQL uses sequences
187                $result =& $this->db_handle->getOne("SELECT CURRVAL('$sequence')");   
188                if (DB::isError($result)) {
189                    raise_error( array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
190                    'message' => $result->getMessage()), TRUE, TRUE);
191                }
192                return $result;
193               
194            case 'mysql': // This is unfortuneate
195                return mysql_insert_id();
196
197            case 'sqlite':
198                return sqlite_last_insert_rowid($this->db_handle->connection);
199
200            default:
201                die("portability issue with this database, please have the developer fix");
202        }
203    }
204
205
206    function fetch_assoc($res_id=NULL)
207    {
208        $result = $this->_get_result($res_id);
209
210        if (DB::isError($result))
211        {
212            raise_error( array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
213                         'message' => $this->db_link->getMessage()), TRUE, FALSE);
214            return FALSE;
215        }
216                         
217        return $result->fetchRow(DB_FETCHMODE_ASSOC);
218    }
219
220        function quoteIdentifier ( $str )
221        {
222                if (!$this->db_handle)
223                        $this->db_connect('r');
224                       
225                return $this->db_handle->quoteIdentifier($str);
226        }
227       
228        function unixtimestamp($field)
229        {
230                switch($this->db_provider)
231                        {
232                        case 'pgsql':
233                                return "EXTRACT (EPOCH FROM $field)";
234                                break;
235                        default:
236                                return "UNIX_TIMESTAMP($field)";
237                        }
238        }
239       
240    function _add_result($res, $query)
241    {
242        // sql error occured
243        if (DB::isError($res))
244        {
245            raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, 'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $query), 0, 1024)), TRUE, FALSE);
246             return FALSE;
247        }
248        else
249        {
250            $res_id = sizeof($this->a_query_results);
251            $this->a_query_results[$res_id] = $res;
252            $this->last_res_id = $res_id;
253            return $res_id;
254        }
255    }
256
257
258    function _get_result($res_id)
259    {
260        if ($res_id==NULL)
261            $res_id = $this->last_res_id;
262   
263        if ($res_id && isset($this->a_query_results[$res_id]))
264            return $this->a_query_results[$res_id];
265        else
266        return FALSE;
267    }
268
269
270    // create a sqlite database from a file
271    function _sqlite_create_database($dbh, $fileName)
272    {
273        if (empty($fileName) || !is_string($fileName))
274            return ;
275
276        $data = '';
277        if ($fd = fopen($fileName, 'r'))
278          {
279          $data = fread($fd, filesize($fileName));
280          fclose($fd);
281          }
282
283        if (strlen($data))
284          sqlite_exec($dbh->connection, $data);
285    }
286
287    // transform a query so that it is sqlite2 compliant
288    function _sqlite_prepare_query($query)
289    {
290        if (!is_string($query))
291            return ($query);
292
293        $search = array('/NOW\(\)/',
294                        '/`/');
295        $replace = array("datetime('now')",
296                         '"');
297        $query = preg_replace($search, $replace, $query);
298
299        return ($query);
300    }
301   
302}
303
304?>
Note: See TracBrowser for help on using the repository browser.