1: <?php
2: // $Id: mysqldatabase.php,v 1.2 2008/09/20 16:04:40 mumincacao Exp $
3: // ------------------------------------------------------------------------ //
4: // XOOPS - PHP Content Management System //
5: // Copyright (c) 2000 XOOPS.org //
6: // <http://www.xoops.org/> //
7: // ------------------------------------------------------------------------ //
8: // This program is free software; you can redistribute it and/or modify //
9: // it under the terms of the GNU General Public License as published by //
10: // the Free Software Foundation; either version 2 of the License, or //
11: // (at your option) any later version. //
12: // //
13: // You may not change or alter any portion of this comment or credits //
14: // of supporting developers from this source code or any supporting //
15: // source code which is considered copyrighted (c) material of the //
16: // original comment or credit authors. //
17: // //
18: // This program is distributed in the hope that it will be useful, //
19: // but WITHOUT ANY WARRANTY; without even the implied warranty of //
20: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21: // GNU General Public License for more details. //
22: // //
23: // You should have received a copy of the GNU General Public License //
24: // along with this program; if not, write to the Free Software //
25: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //
26: // ------------------------------------------------------------------------ //
27: // Author: Kazumi Ono (AKA onokazu) //
28: // URL: http://www.myweb.ne.jp/, http://www.xoops.org/, http://jp.xoops.org/ //
29: // Project: The XOOPS Project //
30: // ------------------------------------------------------------------------- //
31: /**
32: * @package kernel
33: * @subpackage database
34: *
35: * @author Kazumi Ono <onokazu@xoops.org>
36: * @copyright copyright (c) 2000-2003 XOOPS.org
37: */
38:
39: if (!defined('XOOPS_ROOT_PATH')) exit();
40:
41: /**
42: * base class
43: */
44: include_once XOOPS_ROOT_PATH.'/class/database/database.php';
45:
46: if (!defined('MYSQL_CLIENT_FOUND_ROWS')) {
47: define('MYSQL_CLIENT_FOUND_ROWS', 2);
48: }
49:
50: /**
51: * connection to a mysql database
52: *
53: * @abstract
54: *
55: * @author Kazumi Ono <onokazu@xoops.org>
56: * @copyright copyright (c) 2000-2003 XOOPS.org
57: *
58: * @package kernel
59: * @subpackage database
60: */
61: class XoopsMySQLDatabase extends XoopsDatabase
62: {
63: /**
64: * Database connection
65: * @var resource
66: */
67: var $conn;
68:
69: /**
70: * String for Emulation prepare
71: * @var string
72: */
73: var $mPrepareQuery=null;
74:
75: /**
76: * connect to the database
77: *
78: * @param bool $selectdb select the database now?
79: * @return bool successful?
80: */
81: function connect($selectdb = true)
82: {
83: if (XOOPS_DB_PCONNECT == 1) {
84: $this->conn = @mysql_pconnect(XOOPS_DB_HOST, XOOPS_DB_USER, XOOPS_DB_PASS, false, MYSQL_CLIENT_FOUND_ROWS);
85: } else {
86: $this->conn = @mysql_connect(XOOPS_DB_HOST, XOOPS_DB_USER, XOOPS_DB_PASS, false, MYSQL_CLIENT_FOUND_ROWS);
87: }
88:
89: if (!$this->conn) {
90: $this->logger->addQuery('', $this->error(), $this->errno());
91: return false;
92: }
93:
94: if($selectdb != false){
95: if (!mysql_select_db(XOOPS_DB_NAME)) {
96: $this->logger->addQuery('', $this->error(), $this->errno());
97: return false;
98: }
99: }
100: return true;
101: }
102:
103: /**
104: * generate an ID for a new row
105: *
106: * This is for compatibility only. Will always return 0, because MySQL supports
107: * autoincrement for primary keys.
108: *
109: * @param string $sequence name of the sequence from which to get the next ID
110: * @return int always 0, because mysql has support for autoincrement
111: */
112: function genId($sequence)
113: {
114: return 0; // will use auto_increment
115: }
116:
117: /**
118: * Get a result row as an enumerated array
119: *
120: * @param resource $result
121: * @return array
122: */
123: function fetchRow($result)
124: {
125: return @mysql_fetch_row($result);
126: }
127:
128: /**
129: * Fetch a result row as an associative array
130: *
131: * @return array
132: */
133: function fetchArray($result)
134: {
135: return @mysql_fetch_assoc( $result );
136: }
137:
138: /**
139: * Fetch a result row as an associative array
140: *
141: * @return array
142: */
143: function fetchBoth($result)
144: {
145: return @mysql_fetch_array( $result, MYSQL_BOTH );
146: }
147:
148: /**
149: * Get the ID generated from the previous INSERT operation
150: *
151: * @return int
152: */
153: function getInsertId()
154: {
155: return mysql_insert_id($this->conn);
156: }
157:
158: /**
159: * Get number of rows in result
160: *
161: * @param resource query result
162: * @return int
163: */
164: function getRowsNum($result)
165: {
166: return @mysql_num_rows($result);
167: }
168:
169: /**
170: * Get number of affected rows
171: *
172: * @return int
173: */
174: function getAffectedRows()
175: {
176: return mysql_affected_rows($this->conn);
177: }
178:
179: /**
180: * Close MySQL connection
181: *
182: */
183: function close()
184: {
185: mysql_close($this->conn);
186: }
187:
188: /**
189: * will free all memory associated with the result identifier result.
190: *
191: * @param resource query result
192: * @return bool TRUE on success or FALSE on failure.
193: */
194: function freeRecordSet($result)
195: {
196: return mysql_free_result($result);
197: }
198:
199: /**
200: * Returns the text of the error message from previous MySQL operation
201: *
202: * @return bool Returns the error text from the last MySQL function, or '' (the empty string) if no error occurred.
203: */
204: function error()
205: {
206: return @mysql_error();
207: }
208:
209: /**
210: * Returns the numerical value of the error message from previous MySQL operation
211: *
212: * @return int Returns the error number from the last MySQL function, or 0 (zero) if no error occurred.
213: */
214: function errno()
215: {
216: return @mysql_errno();
217: }
218:
219: /**
220: * Returns escaped string text with single quotes around it to be safely stored in database
221: *
222: * @param string $str unescaped string text
223: * @return string escaped string text with single quotes around
224: */
225: function quoteString($str)
226: {
227: $str = '\''.mysql_real_escape_string($str, $this->conn).'\'';
228: return $str;
229: }
230:
231: /**
232: * perform a query on the database
233: *
234: * @param string $sql a valid MySQL query
235: * @param int $limit number of records to return
236: * @param int $start offset of first record to return
237: * @return resource query result or FALSE if successful
238: * or TRUE if successful and no result
239: */
240: function &queryF($sql, $limit=0, $start=0)
241: {
242: if ( !empty($limit) ) {
243: if (empty($start)) {
244: $sql .= ' LIMIT ' . (int)$limit;
245: }
246: else
247: {
248: $sql = $sql. ' LIMIT '.(int)$start.', '.(int)$limit;
249: }
250: }
251: $result = mysql_query($sql, $this->conn);
252: if ( $result ) {
253: $this->logger->addQuery($sql);
254: return $result;
255: } else {
256: $this->logger->addQuery($sql, $this->error(), $this->errno());
257: $ret = false;
258: return $ret;
259: }
260: }
261:
262: /**
263: * perform a query
264: *
265: * This method is empty and does nothing! It should therefore only be
266: * used if nothing is exactly what you want done! ;-)
267: *
268: * @param string $sql a valid MySQL query
269: * @param int $limit number of records to return
270: * @param int $start offset of first record to return
271: *
272: * @abstract
273: */
274: function &query($sql, $limit=0, $start=0)
275: {
276:
277: }
278:
279: /**
280: * perform queries from SQL dump file in a batch
281: *
282: * @param string $file file path to an SQL dump file
283: *
284: * @return bool FALSE if failed reading SQL file or TRUE if the file has been read and queries executed
285: */
286: function queryFromFile($file){
287: if (false !== ($fp = fopen($file, 'r'))) {
288: include_once XOOPS_ROOT_PATH.'/class/database/sqlutility.php';
289: $sql_queries = trim(fread($fp, filesize($file)));
290: SqlUtility::splitMySqlFile($pieces, $sql_queries);
291: foreach ($pieces as $query) {
292: // [0] contains the prefixed query
293: // [4] contains unprefixed table name
294: $prefixed_query = SqlUtility::prefixQuery(trim($query), $this->prefix());
295: if ($prefixed_query != false) {
296: $this->query($prefixed_query[0]);
297: }
298: }
299: return true;
300: }
301: return false;
302: }
303:
304: /**
305: * Get field name
306: *
307: * @param resource $result query result
308: * @param int numerical field index
309: * @return string
310: */
311: function getFieldName($result, $offset)
312: {
313: return mysql_field_name($result, $offset);
314: }
315:
316: /**
317: * Get field type
318: *
319: * @param resource $result query result
320: * @param int $offset numerical field index
321: * @return string
322: */
323: function getFieldType($result, $offset)
324: {
325: return mysql_field_type($result, $offset);
326: }
327:
328: /**
329: * Get number of fields in result
330: *
331: * @param resource $result query result
332: * @return int
333: */
334: function getFieldsNum($result)
335: {
336: return mysql_num_fields($result);
337: }
338:
339: /**
340: * Emulates prepare(), but this is TEST API.
341: * @remark This is TEST API. This method should be called by only Legacy.
342: */
343: function prepare($query)
344: {
345: $count=0;
346: while(($pos=strpos($query,'?'))!==false) {
347: $pre=substr($query,0,$pos);
348: $after='';
349: if($pos+1<=strlen($query))
350: $after=substr($query,$pos+1);
351:
352: $query=$pre.'{'.$count.'}'.$after;
353: $count++;
354: }
355: $this->mPrepareQuery=$query;
356: }
357:
358: /**
359: * Emulates bind_param(), but this is TEST API.
360: * @remark This is TEST API. This method should be called by only Legacy.
361: */
362: function bind_param()
363: {
364: if(func_num_args()<2)
365: return;
366:
367: $types=func_get_arg(0);
368: $count=strlen($types);
369: if(func_num_args()<$count)
370: return;
371:
372: $searches=array();
373: $replaces=array();
374: for($i=0;$i<$count;$i++) {
375: $searches[$i]='{'.$i.'}';
376: switch(substr($types,$i,1)) {
377: case 'i':
378: $replaces[$i]=(int)func_get_arg($i+1);
379: break;
380:
381: case 's':
382: $replaces[$i]=$this->quoteString(func_get_arg($i+1));
383: break;
384:
385: case 'd':
386: $replaces[$i]=doubleval(func_get_arg($i+1));
387: break;
388:
389: case 'b':
390: // Exception
391: die();
392: }
393: }
394:
395: $this->mPrepareQuery=str_replace($searches,$replaces,$this->mPrepareQuery);
396: }
397:
398: /**
399: * Executes prepared SQL with query(), but this is TEST API.
400: * @remark This is TEST API. This method should be called by only Legacy.
401: */
402: function &execute()
403: {
404: $result=&$this->query($this->mPrepareQuery);
405: $this->mPrepareQuery=null;
406: return $result;
407: }
408:
409: /**
410: * Executes prepared SQL with queryF(), but this is TEST API.
411: * @remark This is TEST API. This method should be called by only Legacy.
412: */
413: function &executeF()
414: {
415: $result=&$this->queryF($this->mPrepareQuery);
416: $this->mPrepareQuery=null;
417: return $result;
418: }
419: }
420:
421: /**
422: * Safe Connection to a MySQL database.
423: *
424: *
425: * @author Kazumi Ono <onokazu@xoops.org>
426: * @copyright copyright (c) 2000-2003 XOOPS.org
427: *
428: * @package kernel
429: * @subpackage database
430: */
431: class XoopsMySQLDatabaseSafe extends XoopsMySQLDatabase
432: {
433:
434: /**
435: * perform a query on the database
436: *
437: * @param string $sql a valid MySQL query
438: * @param int $limit number of records to return
439: * @param int $start offset of first record to return
440: * @return resource query result or FALSE if successful
441: * or TRUE if successful and no result
442: */
443: function &query($sql, $limit=0, $start=0)
444: {
445: $result =& $this->queryF($sql, $limit, $start);
446: return $result;
447: }
448: }
449:
450: /**
451: * Read-Only connection to a MySQL database.
452: *
453: * This class allows only SELECT queries to be performed through its
454: * {@link query()} method for security reasons.
455: *
456: *
457: * @author Kazumi Ono <onokazu@xoops.org>
458: * @copyright copyright (c) 2000-2003 XOOPS.org
459: *
460: * @package kernel
461: * @subpackage database
462: */
463: class XoopsMySQLDatabaseProxy extends XoopsMySQLDatabase
464: {
465:
466: /**
467: * perform a query on the database
468: *
469: * this method allows only SELECT queries for safety.
470: *
471: * @param string $sql a valid MySQL query
472: * @param int $limit number of records to return
473: * @param int $start offset of first record to return
474: * @return resource query result or FALSE if unsuccessful
475: */
476: function &query($sql, $limit=0, $start=0)
477: {
478: $sql = ltrim($sql);
479: if (preg_match('/^SELECT/i', $sql)) {
480: $ret = $this->queryF($sql, $limit, $start);
481: return $ret;
482: }
483: $this->logger->addQuery($sql, 'Database update not allowed during processing of a GET request', 0);
484:
485: $ret = false;
486: return $ret;
487: }
488: }
489: ?>
490: