source: github/program/include/rcube_mdb2.inc @ 53560c5

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

added DB LIMIT abstraction

  • Property mode set to 100755
File size: 7.0 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('MDB2.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 = MDB2::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 = MDB2::factory($dsn, array('persistent' => $true));
59       
60        if (PEAR::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 = MDB2::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 (read operations)
105   
106    function query($query, $offset=0, $numrows=0)
107    {
108        // Read or write ?
109        if (strtolower(trim(substr($query,0,6)))=='select')
110            $mode='r';
111        else
112            $mode='w';
113       
114        $this->db_connect($mode);
115
116        if ($this->db_provider == 'sqlite')
117            $query = $this->_sqlite_prepare_query($query);
118           
119        $this->db_handle->row_offset = $offset;
120                $this->db_handle->row_limit = $numrows;
121               
122        $result = $this->db_handle->query($query);
123       
124        if (PEAR::isError($result))
125            raise_error(array('code' => 500,
126                              'type' => 'db',
127                              'line' => __LINE__,
128                              'file' => __FILE__,
129                              'message' => $result->getMessage()), TRUE, FALSE);
130       
131        return $this->_add_result($result, $query);
132    }
133
134    function num_rows($res_id=NULL)
135    {
136        if (!$this->db_handle)
137            return FALSE;
138
139        $result = $this->_get_result($res_id);
140   
141        if ($result)   
142              return $result->numRows();
143        else
144              return FALSE;
145    }
146
147    function affected_rows($res_id=NULL)
148    {
149        if (!$this->db_handle)
150            return FALSE;
151   
152        return $this->db_handle->affectedRows();
153    }
154
155    function insert_id($sequence = '')
156    {
157        if (!$this->db_handle || $this->db_mode=='r')
158            return FALSE;
159
160        return $this->db_handle->lastInsertID();
161    }
162
163
164    function fetch_assoc($res_id=NULL)
165    {
166        $result = $this->_get_result($res_id);
167
168        if (PEAR::isError($result))
169        {
170            raise_error( array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
171                         'message' => $this->db_link->getMessage()), TRUE, FALSE);
172            return FALSE;
173        }
174                         
175        return $result->fetchRow(MDB2_FETCHMODE_ASSOC);
176    }
177
178    function _add_result($res, $query)
179    {
180        // sql error occured
181        if (PEAR::isError($res))
182        {
183            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);
184             return FALSE;
185        }
186        else
187        {
188            $res_id = sizeof($this->a_query_results);
189            $this->a_query_results[$res_id] = $res;
190            $this->last_res_id = $res_id;
191            return $res_id;
192        }
193    }
194
195
196    function _get_result($res_id)
197    {
198        if ($res_id==NULL)
199            $res_id = $this->last_res_id;
200   
201        if ($res_id && isset($this->a_query_results[$res_id]))
202            return $this->a_query_results[$res_id];
203        else
204        return FALSE;
205    }
206
207
208    // create a sqlite database from a file
209    function _sqlite_create_database($dbh, $fileName)
210    {
211        if (empty($fileName) || !is_string($fileName))
212            return ;
213
214        $data = '';
215        if ($fd = fopen($fileName, 'r'))
216          {
217          $data = fread($fd, filesize($fileName));
218          fclose($fd);
219          }
220
221        if (strlen($data))
222          sqlite_exec($dbh->connection, $data);
223    }
224
225    // transform a query so that it is sqlite2 compliant
226    function _sqlite_prepare_query($query)
227    {
228        if (!is_string($query))
229            return ($query);
230
231        $search = array('/NOW\(\)/',
232                        '/`/');
233        $replace = array("datetime('now')",
234                         '"');
235        $query = preg_replace($search, $replace, $query);
236
237        return ($query);
238    }
239   
240}
241
242?>
Note: See TracBrowser for help on using the repository browser.