Automatically define ISSO_DB_LAYER and warn about it
[isso.git] / db.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # app [#]version[#]
5 || # Copyright ©2002-[#]year[#] Iris Studios, Inc.
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Abstract Database Layer
24 * db.php
25 *
26 * @package ISSO
27 */
28
29 /**
30 * Abstract Database Layer
31 *
32 * This class provides an abstract template for all RDBMS layers. All
33 * ISSO abstraction layers should inherit this class. It provides error
34 * reporting, SQL analysis, and general connection functionality.
35 *
36 * Constants:
37 * [required] ISSO_DB_LAYER - The name of the DB layer module used in the application
38 *
39 * @author Iris Studios, Inc.
40 * @copyright Copyright ©2002 - [#]year[#], Iris Studios, Inc.
41 * @version $Revision$
42 * @package ISSO
43 *
44 */
45 class DB_Abstract
46 {
47 /**
48 * Framework registry object
49 * @var object
50 * @access protected
51 */
52 var $registry = null;
53
54 /**
55 * Determines whether or not errors should be shown
56 * @var bool
57 * @access public
58 */
59 var $showerrors = true;
60
61 /**
62 * Current error number
63 * @var integer
64 * @access protected
65 */
66 var $errnum = 0;
67
68 /**
69 * Description of current error
70 * @var string
71 * @access protected
72 */
73 var $errstr = '';
74
75 /**
76 * Currend open MySQL connexion
77 * @var resource
78 * @access protected
79 */
80 var $dblink = null;
81
82 /**
83 * Current query ID
84 * @var integer
85 * @access protected
86 */
87 var $result = null;
88
89 /**
90 * Current query string
91 * @var string
92 * @access protected
93 */
94 var $querystr = '';
95
96 /**
97 * History of all executed queryies
98 * @var array
99 * @access protected
100 */
101 var $history = array();
102
103 /**
104 * Command mapping list
105 * @var array
106 * @access protected
107 */
108 var $commands = array(
109 'pconnect' => '%server %user %password %database',
110 'connect' => '%server %user %password %database',
111 'query' => '%link %query',
112 'error_num' => '%link',
113 'error_str' => '%link',
114 'escape_string' => '%link %string',
115 'fetch_assoc' => '%result',
116 'fetch_object' => '%result',
117 'free_result' => '%result',
118 'insert_id' => '%link',
119 'num_rows' => '%result',
120 'affected_rows' => '%result'
121 );
122
123 // ###################################################################
124 /**
125 * Constructor
126 */
127 function __construct(&$registry)
128 {
129 $this->registry =& $registry;
130
131 // because ivars and call_user_func() are conspiring against us...
132 foreach ($this->commands AS $key => $string)
133 {
134 if (strpos($string, '$this->') !== false)
135 {
136 $this->commands["$key"] = array($this, str_replace('$this->', '', $string));
137 }
138 }
139 }
140
141 // ###################################################################
142 /**
143 * (PHP 4) Constructor
144 */
145 function DB_Abstract(&$registry)
146 {
147 $this->__construct($registry);
148 }
149
150 // ###################################################################
151 /**
152 * Initializes the class and all subclasses under a common package name
153 *
154 * @access protected
155 *
156 * @return string The package name
157 */
158 function init_as_package()
159 {
160 if (!defined('ISSO_DB_LAYER'))
161 {
162 define('ISSO_DB_LAYER', get_class($this));
163 trigger_error('ISSO_DB_LAYER was defined automatically by DB::init_as_package(). Define the constant yourself to remove this warning', E_USER_WARNING);
164 }
165
166 return 'db';
167 }
168
169 // ###################################################################
170 /**
171 * Connect to a the specified database
172 *
173 * @access public
174 *
175 * @param string Server name
176 * @param string User name
177 * @param string Password
178 * @param string Database name
179 * @param bool Use p-connect?
180 *
181 * @return bool Result of connect
182 */
183 function connect($server, $user, $password, $database, $pconnect)
184 {
185 $this->registry->check_isso_fields(get_class($this));
186
187 if ($this->dblink == false)
188 {
189 $this->dblink = call_user_func(($pconnect ? $this->commands['pconnect'] : $this->commands['connect']), $server, $user, $password, $database);
190
191 if ($this->dblink == false)
192 {
193 $this->error('DB-Link == false, cannot connect');
194 return false;
195 }
196
197 return true;
198 }
199 }
200
201 // ###################################################################
202 /**
203 * Send a query to the open database link
204 *
205 * @access public
206 *
207 * @param string Query string
208 *
209 * @return integer Result
210 */
211 function query($string)
212 {
213 $this->querystr = $string;
214 $this->result = call_user_func($this->commands['query'], $this->dblink, $string);
215 $this->history[] = $string;
216
217 if (defined('ISSO_SHOW_QUERIES_LIVE'))
218 {
219 if (constant('ISSO_SHOW_QUERIES_LIVE'))
220 {
221 print($this->querystr . '<hr />');
222 }
223 }
224
225 if (!$this->result)
226 {
227 $this->error('Invalid SQL query');
228 }
229
230 return $this->result;
231 }
232
233 // ###################################################################
234 /**
235 * Escape a string (depending on character set, if supported)
236 *
237 * @access public
238 *
239 * @param string String to be escaped
240 *
241 * @return string Escaped string
242 */
243 function escape_string($string)
244 {
245 return call_user_func($this->commands['escape_string'], $this->dblink, $string);
246 }
247
248 // ###################################################################
249 /**
250 * Fetch the query result as an array
251 *
252 * @access public
253 *
254 * @param integer Result
255 *
256 * @return array A row of the query result
257 */
258 function fetch_array($result)
259 {
260 return call_user_func($this->commands['fetch_assoc'], $result);
261 }
262
263 // ###################################################################
264 /**
265 * Fetch the query result as an object
266 *
267 * @access public
268 *
269 * @param integer Result
270 *
271 * @return object An object with the query result
272 */
273 function fetch_object($result)
274 {
275 return call_user_func($this->commands['fetch_object'], $result);
276 }
277
278 // ###################################################################
279 /**
280 * Send a query and return the first row of the results
281 *
282 * @access public
283 *
284 * @param string Query string
285 * @param string Result return function (in the database layer)
286 *
287 * @return mixed Results in variable formats
288 */
289 function query_first($string, $callback = 'fetch_array')
290 {
291 $resource = $this->query($string);
292 $return = $this->$callback($resource);
293 $this->free_result($resource);
294 return $return;
295 }
296
297 // ###################################################################
298 /**
299 * Free the current query result
300 *
301 * @access public
302 *
303 * @param integer Result
304 */
305 function free_result($result)
306 {
307 call_user_func($this->commands['free_result'], $result);
308 $this->result = null;
309 $this->querystr = '';
310 }
311
312 // ###################################################################
313 /**
314 * Fetch the unique ID of the record just inserted
315 *
316 * @access public
317 *
318 * @return integer Insert-ID
319 */
320 function insert_id()
321 {
322 return call_user_func($this->commands['insert_id'], $this->dblink);
323 }
324
325 // ###################################################################
326 /**
327 * Fetch the number of rows in the result
328 *
329 * @access public
330 *
331 * @param integer Result
332 *
333 * @return integer Number of rows
334 */
335 function num_rows($result)
336 {
337 return call_user_func($this->commands['num_rows'], $result);
338 }
339
340 // ###################################################################
341 /**
342 * Fetch the number of rows affected by the query
343 *
344 * @access public
345 *
346 * @param integer Result
347 *
348 * @return integer Number of affected rows
349 */
350 function affected_rows($result)
351 {
352 return call_user_func($this->commands['affected_rows'], $result);
353 }
354
355 // ###################################################################
356 /**
357 * Error wrapper for ISSO->message()
358 *
359 * @access protected
360 *
361 * @param string User defined error message
362 */
363 function error($message)
364 {
365 if ($this->showerrors)
366 {
367 if ($this->dblink)
368 {
369 $this->errnum = call_user_func($this->commands['error_num'], $this->dblink);
370 $this->errstr = call_user_func($this->commands['error_str'], $this->dblink);
371 }
372
373 $style['code'] = 'font-family: \'Courier New\', Courier, mono; font-size: 11px;';
374
375 $message_prepped = "<blockquote>\n<p>";
376 $message_prepped .= "\n\t&raquo; <strong>Query:</strong>\n<br /> <pre style=\"$style[code]\">" . htmlspecialchars($this->querystr) ."</pre>\n<br />";
377 $message_prepped .= "\n\t&raquo; <strong>Error Number:</strong> <span style=\"$style[code]\">" . $this->errnum . "</span>\n<br />";
378 $message_prepped .= "\n\t&raquo; <strong>Error Message:</strong> <span style=\"$style[code]\">" . $this->errstr . "</span>\n<br />";
379 $message_prepped .= "\n\t&raquo; <strong>Additional Notes:</strong> <span style=\"$style[code]\">" . $message . "</span>\n<br />";
380 $message_prepped .= "\n\t&raquo; <strong>File:</strong> <span style=\"$style[code]\">" . $_SERVER['PHP_SELF'] . "</span>\n";
381 $message_prepped .= "\n</p>\n</blockquote>";
382
383 $this->registry->message('Database Error in `<em>' . $this->registry->application . '</em>`', $message_prepped, 3);
384 exit;
385 }
386 }
387 }
388
389 /*=====================================================================*\
390 || ###################################################################
391 || # $HeadURL$
392 || # $Id$
393 || ###################################################################
394 \*=====================================================================*/
395 ?>