Marius Cramer
2015-08-06 37b29231e47a0c4458dc1c15d98588f16f07e1e2
commit | author | age
9200ad 1 <?php
T 2 /*
2af58c 3    Copyright (c) 2005, Till Brehm, projektfarm Gmbh
MC 4    All rights reserved.
9200ad 5
2af58c 6    Redistribution and use in source and binary forms, with or without modification,
MC 7    are permitted provided that the following conditions are met:
9200ad 8
2af58c 9  * Redistributions of source code must retain the above copyright notice,
MC 10  this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright notice,
12  this list of conditions and the following disclaimer in the documentation
13  and/or other materials provided with the distribution.
14  * Neither the name of ISPConfig nor the names of its contributors
15  may be used to endorse or promote products derived from this software without
16  specific prior written permission.
9200ad 17
2af58c 18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
MC 19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
9200ad 29
2af58c 30 class db extends mysqli
436ed8 31 {
2af58c 32     /**#@+
MC 33      * @access private
34      */
35     private $_iQueryId;
36     private $_iConnId;
37
38     private $dbHost = '';  // hostname of the MySQL server
39     private $dbName = '';  // logical database name on that server
40     private $dbUser = '';  // database authorized user
41     private $dbPass = '';  // user's password
42     private $dbCharset = 'utf8';// Database charset
43     private $dbNewLink = false; // Return a new linkID when connect is called again
44     private $dbClientFlags = 0; // MySQL Client falgs
45     /**#@-*/
46
47     public $show_error_messages = false; // false in server, true in interface
48
49
50     /* old things - unused now ////
51     private $linkId = 0;  // last result of mysqli_connect()
52     private $queryId = 0;  // last result of mysqli_query()
53     private $record = array(); // last record fetched
54     private $autoCommit = 1;    // Autocommit Transactions
55     private $currentRow;  // current row number
56     public $errorNumber = 0; // last error number
57     public $errorMessage = ''; // last error message
58     private $errorLocation = '';// last error location
59     private $isConnected = false; // needed to know if we have a valid mysqli object from the constructor
60     ////
61     */
436ed8 62
5eafbc 63     public function __destruct() {
MC 64         if($this->_iConnId) mysqli_close($this->_iConnId);
65     }
66     
67     private function do_connect() {
436ed8 68         global $conf;
5eafbc 69         
MC 70         if($this->_iConnId) return true;
436ed8 71         $this->dbHost = $conf["mysql"]["host"];
305dda 72         $this->dbName = false;//$conf["mysql"]["database"];
436ed8 73         $this->dbUser = $conf["mysql"]["admin_user"];
R 74         $this->dbPass = $conf["mysql"]["admin_password"];
75         $this->dbCharset = $conf["mysql"]["charset"];
2af58c 76         $this->dbNewLink = false;
MC 77         $this->dbClientFlags = null;
40c6e8 78         
2af58c 79         $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass);
MC 80         $try = 0;
81         while((!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5) {
82             if($try > 0) sleep(1);
83
84             $try++;
85             $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass);
436ed8 86         }
2af58c 87
MC 88         if(!is_object($this->_iConnId) || mysqli_connect_error()) {
89             $this->_iConnId = null;
90             $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!');
91             return false;
92         }
305dda 93         
MC 94         if($this->dbName) $this->setDBName($this->dbName);
95
96         $this->_setCharset();
97     }
98     
99     public function setDBData($host, $user, $password) {
100         $this->dbHost = $host;
101         $this->dbUser = $user;
102         $this->dbPass = $password;
103     }
104     
105     public function setDBName($name) {
106         $this->dbName = $name;
2af58c 107         if(!((bool)mysqli_query( $this->_iConnId, 'USE `' . $this->dbName . '`'))) {
MC 108             $this->close();
109             $this->_sqlerror('Datenbank nicht gefunden / Database not found');
110             return false;
111         }
436ed8 112     }
40c6e8 113     
2af58c 114     public function close() {
MC 115         if($this->_iConnId) mysqli_close($this->_iConnId);
116         $this->_iConnId = null;
117     }
118
119     /* This allows our private variables to be "read" out side of the class */
120     public function __get($var) {
121         return isset($this->$var) ? $this->$var : NULL;
122     }
123
124     public function _build_query_string($sQuery = '') {
125         $iArgs = func_num_args();
126         if($iArgs > 1) {
127             $aArgs = func_get_args();
128
129             if($iArgs == 3 && $aArgs[1] === true && is_array($aArgs[2])) {
130                 $aArgs = $aArgs[2];
131                 $iArgs = count($aArgs);
132             } else {
133                 array_shift($aArgs); // delete the query string that is the first arg!
436ed8 134             }
2af58c 135
MC 136             $iPos = 0;
137             $iPos2 = 0;
138             foreach($aArgs as $sKey => $sValue) {
139                 $iPos2 = strpos($sQuery, '??', $iPos2);
140                 $iPos = strpos($sQuery, '?', $iPos);
141
142                 if($iPos === false && $iPos2 === false) break;
143
144                 if($iPos2 !== false && ($iPos === false || $iPos2 <= $iPos)) {
145                     $sTxt = $this->escape($sValue);
146
cf84b3 147                     if(strpos($sTxt, '.') !== false) {
MC 148                         $sTxt = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $sTxt);
149                         $sTxt = str_replace('.`*`', '.*', $sTxt);
150                     } else $sTxt = '`' . $sTxt . '`';
2af58c 151
MC 152                     $sQuery = substr_replace($sQuery, $sTxt, $iPos2, 2);
153                     $iPos2 += strlen($sTxt);
154                     $iPos = $iPos2;
155                 } else {
156                     if(is_int($sValue) || is_float($sValue)) {
157                         $sTxt = $sValue;
158                     } elseif(is_string($sValue) && (strcmp($sValue, '#NULL#') == 0)) {
159                         $sTxt = 'NULL';
160                     } elseif(is_array($sValue)) {
161                         $sTxt = '';
162                         foreach($sValue as $sVal) $sTxt .= ',\'' . $this->escape($sVal) . '\'';
163                         $sTxt = '(' . substr($sTxt, 1) . ')';
164                         if($sTxt == '()') $sTxt = '(0)';
165                     } else {
166                         $sTxt = '\'' . $this->escape($sValue) . '\'';
167                     }
168
169                     $sQuery = substr_replace($sQuery, $sTxt, $iPos, 1);
170                     $iPos += strlen($sTxt);
171                     $iPos2 = $iPos;
172                 }
173             }
174         }
175
176         return $sQuery;
177     }
178
179     /**#@-*/
180
181
182     /**#@+
183      * @access private
184      */
185     private function _setCharset() {
186         mysqli_query($this->_iConnId, 'SET NAMES '.$this->dbCharset);
187         mysqli_query($this->_iConnId, "SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'");
188     }
189
190     private function _query($sQuery = '') {
d7ad8f 191         $this->do_connect();
40c6e8 192
2af58c 193         if ($sQuery == '') {
MC 194             $this->_sqlerror('Keine Anfrage angegeben / No query given');
195             return false;
196         }
197
198         $try = 0;
199         do {
200             $try++;
201             $ok = mysqli_ping($this->_iConnId);
202             if(!$ok) {
203                 if(!mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName)) {
204                     if($this->errorNumber == '111') {
205                         // server is not available
206                         if($try > 9) {
c6d4e8 207                             $this->_sqlerror('DB::query -> error connecting');
MC 208                             exit;
2af58c 209                         }
MC 210                         sleep(30); // additional seconds, please!
211                     }
212
213                     if($try > 9) {
214                         $this->_sqlerror('DB::query -> reconnect');
215                         return false;
216                     } else {
217                         sleep(($try > 7 ? 5 : 1));
218                     }
219                 } else {
220                     $this->_setCharset();
221                     $ok = true;
222                 }
223             }
224         } while($ok == false);
225
226         $aArgs = func_get_args();
227         $sQuery = call_user_func_array(array(&$this, '_build_query_string'), $aArgs);
228
229         $this->_iQueryId = mysqli_query($this->_iConnId, $sQuery);
230         if (!$this->_iQueryId) {
231             $this->_sqlerror('Falsche Anfrage / Wrong Query', false, 'SQL-Query = ' . $sQuery);
232             return false;
233         }
234
235         return is_bool($this->_iQueryId) ? $this->_iQueryId : new db_result($this->_iQueryId, $this->_iConnId);
236     }
237
238     /**#@-*/
239
240
241
242
243
244     /**
245      * Executes a query
246      *
247      * Executes a given query string, has a variable amount of parameters:
248      * - 1 parameter
249      *   executes the given query
250      * - 2 parameters
251      *   executes the given query, replaces the first ? in the query with the second parameter
252      * - 3 parameters
253      *   if the 2nd parameter is a boolean true, the 3rd parameter has to be an array containing all the replacements for every occuring ? in the query, otherwise the second parameter replaces the first ?, the third parameter replaces the second ? in the query
254      * - 4 or more parameters
255      *   all ? in the query are replaced from left to right by the parameters 2 to x
256      *
257      * @access public
258      * @param string  $sQuery query string
259      * @param mixed   ... one or more parameters
260      * @return db_result the result object of the query
261      */
262
263
264     public function query($sQuery = '') {
265         $aArgs = func_get_args();
266         return call_user_func_array(array(&$this, '_query'), $aArgs);
267     }
268
269     /**
270      * Execute a query and get first result array
271      *
272      * Executes a query and returns the first result row as an array
273      * This is like calling $result = $db->query(),  $result->get(), $result->free()
274      * Use of this function @see query
275      *
276      * @access public
277      * @param string  $sQuery query to execute
278      * @param ...     further params (see query())
279      * @return array result row or NULL if none found
280      */
281     public function queryOneRecord($sQuery = '') {
282         if(!preg_match('/limit \d+\s*,\s*\d+$/i', $sQuery)) $sQuery .= ' LIMIT 0,1';
283
284         $aArgs = func_get_args();
285         $oResult = call_user_func_array(array(&$this, 'query'), $aArgs);
286         if(!$oResult) return null;
287
288         $aReturn = $oResult->get();
289         $oResult->free();
290
291         return $aReturn;
292     }
293
294     public function queryOne($sQuery = '') {
295         return call_user_func_array(array(&$this, 'queryOneRecord'), func_get_args());
296     }
297
298     public function query_one($sQuery = '') {
299         return call_user_func_array(array(&$this, 'queryOneRecord'), func_get_args());
300     }
301
302     /**
303      * Execute a query and return all rows
304      *
305      * Executes a query and returns all result rows in an array
306      * <strong>Use this with extreme care!!!</strong> Uses lots of memory on big result sets.
307      *
308      * @access public
309      * @param string  $sQuery query to execute
310      * @param ...     further params (see query())
311      * @return array all the rows in the result set
312      */
313     public function queryAllRecords($sQuery = '') {
314         $aArgs = func_get_args();
315         $oResult = call_user_func_array(array(&$this, 'query'), $aArgs);
316         if(!$oResult) return array();
317
318         $aResults = array();
319         while($aRow = $oResult->get()) {
320             $aResults[] = $aRow;
321         }
322         $oResult->free();
323
324         return $aResults;
325     }
326
327     public function queryAll($sQuery = '') {
328         return call_user_func_array(array(&$this, 'queryAllRecords'), func_get_args());
329     }
330
331     public function query_all($sQuery = '') {
332         return call_user_func_array(array(&$this, 'queryAllRecords'), func_get_args());
333     }
334
335     /**
336      * Execute a query and return all rows as simple array
337      *
338      * Executes a query and returns all result rows in an array with elements
339      * <strong>Only first column is returned</strong> Uses lots of memory on big result sets.
340      *
341      * @access public
342      * @param string  $sQuery query to execute
343      * @param ...     further params (see query())
344      * @return array all the rows in the result set
345      */
346     public function queryAllArray($sQuery = '') {
347         $aArgs = func_get_args();
348         $oResult = call_user_func_array(array(&$this, 'query'), $aArgs);
349         if(!$oResult) return array();
350
351         $aResults = array();
352         while($aRow = $oResult->get()) {
353             $aResults[] = reset($aRow);
354         }
355         $oResult->free();
356
357         return $aResults;
358     }
359
360     public function query_all_array($sQuery = '') {
361         return call_user_func_array(array(&$this, 'queryAllArray'), func_get_args());
362     }
363
364
365
366     /**
367      * Get id of last inserted row
368      *
369      * Gives you the id of the last inserted row in a table with an auto-increment primary key
370      *
371      * @access public
372      * @return int id of last inserted row or 0 if none
373      */
374     public function insert_id() {
375         $iRes = mysqli_query($this->_iConnId, 'SELECT LAST_INSERT_ID() as `newid`');
376         if(!is_object($iRes)) return false;
377
378         $aReturn = mysqli_fetch_assoc($iRes);
379         mysqli_free_result($iRes);
380
381         return $aReturn['newid'];
382     }
383
384
385
386     /**
387      * get affected row count
388      *
389      * Gets the amount of rows affected by the previous query
390      *
391      * @access public
392      * @return int affected rows
393      */
394     public function affected() {
395         if(!is_object($this->_iConnId)) return 0;
396         $iRows = mysqli_affected_rows($this->_iConnId);
397         if(!$iRows) $iRows = 0;
398         return $iRows;
399     }
400
401
402
403     /**
404      * check if a utf8 string is valid
405      *
406      * @access public
407      * @param string  $string the string to check
408      * @return bool true if it is valid utf8, false otherwise
409      */
410     private function check_utf8($str) {
411         $len = strlen($str);
412         for($i = 0; $i < $len; $i++){
413             $c = ord($str[$i]);
414             if ($c > 128) {
415                 if (($c > 247)) return false;
416                 elseif ($c > 239) $bytes = 4;
417                 elseif ($c > 223) $bytes = 3;
418                 elseif ($c > 191) $bytes = 2;
419                 else return false;
420                 if (($i + $bytes) > $len) return false;
421                 while ($bytes > 1) {
422                     $i++;
423                     $b = ord($str[$i]);
424                     if ($b < 128 || $b > 191) return false;
425                     $bytes--;
426                 }
427             }
436ed8 428         }
R 429         return true;
2af58c 430     } // end of check_utf8
436ed8 431
2af58c 432     /**
MC 433      * Escape a string for usage in a query
434      *
435      * @access public
436      * @param string  $sString query string to escape
437      * @return string escaped string
438      */
439     public function escape($sString) {
440         if(!is_string($sString) && !is_numeric($sString)) {
441             $sString = '';
436ed8 442         }
2af58c 443
MC 444         $cur_encoding = mb_detect_encoding($sString);
445         if($cur_encoding != "UTF-8") {
446             if($cur_encoding != 'ASCII') {
447                 if($cur_encoding) $sString = mb_convert_encoding($sString, 'UTF-8', $cur_encoding);
448                 else $sString = mb_convert_encoding($sString, 'UTF-8');
436ed8 449             }
2af58c 450         } elseif(!$this->check_utf8($sString)) {
MC 451             $sString = utf8_encode($sString);
436ed8 452         }
2af58c 453
MC 454         if($this->_iConnId) return mysqli_real_escape_string($this->_iConnId, $sString);
455         else return addslashes($sString);
436ed8 456     }
R 457
2af58c 458     /**
MC 459      *
460      *
461      * @access private
462      */
463     private function _sqlerror($sErrormsg = 'Unbekannter Fehler', $sAddMsg = '') {
c6d4e8 464         global $conf;
2af58c 465
MC 466         $mysql_error = (is_object($this->_iConnId) ? mysqli_error($this->_iConnId) : mysqli_connect_error());
467         $mysql_errno = (is_object($this->_iConnId) ? mysqli_errno($this->_iConnId) : mysqli_connect_errno());
468
469         //$sAddMsg .= getDebugBacktrace();
470
471         if($this->show_error_messages && $conf['demo_mode'] === false) {
472             echo $sErrormsg . $sAddMsg;
c6d4e8 473         }
436ed8 474     }
R 475
2af58c 476     public function affectedRows() {
MC 477         return $this->affected();
436ed8 478     }
b1a6a5 479
436ed8 480     // returns mySQL insert id
2af58c 481     public function insertID() {
MC 482         return $this->insert_id();
436ed8 483     }
b1a6a5 484
2af58c 485
MC 486     //* Function to quote strings
487     public function quote($formfield) {
488         return $this->escape($formfield);
b1a6a5 489     }
MC 490
2af58c 491     //* Function to unquotae strings
MC 492     public function unquote($formfield) {
b1a6a5 493         return stripslashes($formfield);
MC 494     }
495
2af58c 496     public function toLower($record) {
436ed8 497         if(is_array($record)) {
R 498             foreach($record as $key => $val) {
499                 $key = strtolower($key);
500                 $out[$key] = $val;
501             }
502         }
b1a6a5 503         return $out;
436ed8 504     }
b1a6a5 505
2af58c 506     /* TODO: rewrite SQL */
b1a6a5 507     function insert($tablename, $form, $debug = 0)
MC 508     {
509         if(is_array($form)){
510             foreach($form as $key => $value)
511             {
512                 $sql_key .= "$key, ";
513                 $sql_value .= "'".$this->check($value)."', ";
436ed8 514             }
b1a6a5 515             $sql_key = substr($sql_key, 0, strlen($sql_key) - 2);
MC 516             $sql_value = substr($sql_value, 0, strlen($sql_value) - 2);
517
518             $sql = "INSERT INTO $tablename (" . $sql_key . ") VALUES (" . $sql_value .")";
519
520             if($debug == 1) echo "SQL-Statement: ".$sql."<br><br>";
521             $this->query($sql);
522             if($debug == 1) echo "mySQL Error Message: ".$this->errorMessage;
436ed8 523         }
b1a6a5 524     }
2af58c 525     
MC 526     /* TODO: rewrite SQL */
b1a6a5 527     function update($tablename, $form, $bedingung, $debug = 0)
MC 528     {
529
530         if(is_array($form)){
531             foreach($form as $key => $value)
532             {
533                 $insql .= "$key = '".$this->check($value)."', ";
534             }
535             $insql = substr($insql, 0, strlen($insql) - 2);
536             $sql = "UPDATE $tablename SET " . $insql . " WHERE $bedingung";
537             if($debug == 1) echo "SQL-Statement: ".$sql."<br><br>";
538             $this->query($sql);
539             if($debug == 1) echo "mySQL Error Message: ".$this->errorMessage;
436ed8 540         }
b1a6a5 541     }
MC 542
543
544     /*
2af58c 545        $columns = array(action =>   add | alter | drop
MC 546        name =>     Spaltenname
547        name_new => neuer Spaltenname, nur bei 'alter' belegt
548        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
549        typeValue => Wert z.B. bei Varchar
550        defaultValue =>  Default Wert
551        notNull =>   true | false
552        autoInc =>   true | false
553        option =>   unique | primary | index)
b1a6a5 554
MC 555
2af58c 556      */
MC 557     /* TODO: rewrite SQL */
558     public function createTable($table_name, $columns) {
559         $index = '';
560         $sql = "CREATE TABLE ?? (";
b1a6a5 561         foreach($columns as $col){
2af58c 562             $sql .= $col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
b1a6a5 563
2af58c 564             if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
MC 565             if($col['notNull'] == true) {
566                 $sql .= 'NOT NULL ';
567             } else {
568                 $sql .= 'NULL ';
b1a6a5 569             }
2af58c 570             if($col['autoInc'] == true) $sql .= 'auto_increment ';
MC 571             $sql.= ',';
b1a6a5 572             // key Definitionen
2af58c 573             if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
MC 574             if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
575             if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
b1a6a5 576         }
MC 577         $sql .= $index;
578         $sql = substr($sql, 0, -1);
2af58c 579         $sql .= ')';
MC 580         /* TODO: secure parameters */
581         $this->query($sql, $table_name);
b1a6a5 582         return true;
MC 583     }
584
585     /*
2af58c 586        $columns = array(action =>   add | alter | drop
MC 587        name =>     Spaltenname
588        name_new => neuer Spaltenname, nur bei 'alter' belegt
589        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
590        typeValue => Wert z.B. bei Varchar
591        defaultValue =>  Default Wert
592        notNull =>   true | false
593        autoInc =>   true | false
594        option =>   unique | primary | index)
b1a6a5 595
MC 596
2af58c 597      */
MC 598     /* TODO: rewrite SQL */
599     public function alterTable($table_name, $columns) {
600         $index = '';
601         $sql = "ALTER TABLE ?? ";
b1a6a5 602         foreach($columns as $col){
2af58c 603             if($col['action'] == 'add') {
MC 604                 $sql .= 'ADD '.$col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
605             } elseif ($col['action'] == 'alter') {
606                 $sql .= 'CHANGE '.$col['name'].' '.$col['name_new'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
607             } elseif ($col['action'] == 'drop') {
608                 $sql .= 'DROP '.$col['name'].' ';
b1a6a5 609             }
2af58c 610             if($col['action'] != 'drop') {
MC 611                 if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
612                 if($col['notNull'] == true) {
613                     $sql .= 'NOT NULL ';
b1a6a5 614                 } else {
2af58c 615                     $sql .= 'NULL ';
b1a6a5 616                 }
2af58c 617                 if($col['autoInc'] == true) $sql .= 'auto_increment ';
MC 618                 $sql.= ',';
619                 // Index definitions
620                 if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
621                 if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
622                 if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
b1a6a5 623             }
MC 624         }
625         $sql .= $index;
626         $sql = substr($sql, 0, -1);
2af58c 627         /* TODO: secure parameters */
b1a6a5 628         //die($sql);
2af58c 629         $this->query($sql, $table_name);
b1a6a5 630         return true;
MC 631     }
632
2af58c 633     public function dropTable($table_name) {
b1a6a5 634         $this->check($table_name);
2af58c 635         $sql = "DROP TABLE ??";
MC 636         return $this->query($sql, $table_name);
b1a6a5 637     }
MC 638
639     // gibt Array mit Tabellennamen zur�ck
2af58c 640     public function getTables($database_name = '') {
MC 641         if(!is_object($this->_iConnId)) return false;
642         if($database_name == '') $database_name = $this->dbName;
643         $tb_names = $this->queryAllArray("SHOW TABLES FROM ??", $database_name);
b1a6a5 644         return $tb_names;
MC 645     }
646
647     // gibt Feldinformationen zur Tabelle zur�ck
648     /*
2af58c 649        $columns = array(action =>   add | alter | drop
MC 650        name =>     Spaltenname
651        name_new => neuer Spaltenname, nur bei 'alter' belegt
652        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
653        typeValue => Wert z.B. bei Varchar
654        defaultValue =>  Default Wert
655        notNull =>   true | false
656        autoInc =>   true | false
657        option =>   unique | primary | index)
7b47c0 658
b1a6a5 659
2af58c 660      */
MC 661     /* TODO: rewrite SQL */
b1a6a5 662     function tableInfo($table_name) {
MC 663
664         global $go_api, $go_info;
665         // Tabellenfelder einlesen
666
2af58c 667         if($rows = $go_api->db->queryAllRecords('SHOW FIELDS FROM ??', $table_name)){
b1a6a5 668             foreach($rows as $row) {
2af58c 669                 $name = $row['Field'];
MC 670                 $default = $row['Default'];
671                 $key = $row['Key'];
672                 $extra = $row['Extra'];
673                 $isnull = $row['Null'];
674                 $type = $row['Type'];
b1a6a5 675
MC 676
677                 $column = array();
678
2af58c 679                 $column['name'] = $name;
MC 680                 //$column['type'] = $type;
681                 $column['defaultValue'] = $default;
682                 if(stristr($key, 'PRI')) $column['option'] = 'primary';
683                 if(stristr($isnull, 'YES')) {
684                     $column['notNull'] = false;
b1a6a5 685                 } else {
2af58c 686                     $column['notNull'] = true;
b1a6a5 687                 }
2af58c 688                 if($extra == 'auto_increment') $column['autoInc'] = true;
b1a6a5 689
MC 690
691                 // Type in Metatype umsetzen
692
2af58c 693                 if(stristr($type, 'int(')) $metaType = 'int32';
MC 694                 if(stristr($type, 'bigint')) $metaType = 'int64';
695                 if(stristr($type, 'char')) {
b1a6a5 696                     $metaType = 'char';
MC 697                     $tmp_typeValue = explode('(', $type);
2af58c 698                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
b1a6a5 699                 }
2af58c 700                 if(stristr($type, 'varchar')) {
b1a6a5 701                     $metaType = 'varchar';
MC 702                     $tmp_typeValue = explode('(', $type);
2af58c 703                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
b1a6a5 704                 }
2af58c 705                 if(stristr($type, 'text')) $metaType = 'text';
MC 706                 if(stristr($type, 'double')) $metaType = 'double';
707                 if(stristr($type, 'blob')) $metaType = 'blob';
b1a6a5 708
MC 709
2af58c 710                 $column['type'] = $metaType;
b1a6a5 711
MC 712                 $columns[] = $column;
713             }
714             return $columns;
715         } else {
716             return false;
717         }
718
719     }
720
2af58c 721     public function mapType($metaType, $typeValue) {
b1a6a5 722         global $go_api;
MC 723         $metaType = strtolower($metaType);
724         switch ($metaType) {
725         case 'int16':
726             return 'smallint';
727             break;
728         case 'int32':
729             return 'int';
730             break;
731         case 'int64':
732             return 'bigint';
733             break;
734         case 'double':
735             return 'double';
736             break;
737         case 'char':
738             return 'char';
739             break;
740         case 'varchar':
2af58c 741             if($typeValue < 1) die('Database failure: Lenght required for these data types.');
b1a6a5 742             return 'varchar('.$typeValue.')';
MC 743             break;
744         case 'text':
745             return 'text';
746             break;
747         case 'blob':
748             return 'blob';
749             break;
750         }
751     }
752
436ed8 753 }
R 754
2af58c 755 /**
MC 756  * database query result class
757  *
758  * @package pxFramework
759  *
760  */
761 class db_result {
762
763     /**
764      *
765      *
766      * @access private
767      */
768     private $_iResId = null;
769     private $_iConnection = null;
770
771
772
773     /**
774      *
775      *
776      * @access private
777      */
778     public function db_result($iResId, $iConnection) {
779         $this->_iResId = $iResId;
780         $this->_iConnection = $iConnection;
781     }
782
783
784
785     /**
786      * get count of result rows
787      *
788      * Returns the amount of rows in the result set
789      *
790      * @access public
791      * @return int amount of rows
792      */
793     public function rows() {
794         if(!is_object($this->_iResId)) return 0;
795         $iRows = mysqli_num_rows($this->_iResId);
796         if(!$iRows) $iRows = 0;
797         return $iRows;
798     }
799
800
801
802     /**
803      * Get number of affected rows
804      *
805      * Returns the amount of rows affected by the previous query
806      *
807      * @access public
808      * @return int amount of affected rows
809      */
810     public function affected() {
811         if(!is_object($this->_iConnection)) return 0;
812         $iRows = mysqli_affected_rows($this->_iConnection);
813         if(!$iRows) $iRows = 0;
814         return $iRows;
815     }
816
817
818
819     /**
820      * Frees the result set
821      *
822      * @access public
823      */
824     public function free() {
825         if(!is_object($this->_iResId)) return;
826
827         mysqli_free_result($this->_iResId);
828         return;
829     }
830
831
832
833     /**
834      * Get a result row (associative)
835      *
836      * Returns the next row in the result set. To be used in a while loop like while($currow = $result->get()) { do something ... }
837      *
838      * @access public
839      * @return array result row
840      */
841     public function get() {
842         $aItem = null;
843
844         if(is_object($this->_iResId)) {
845             $aItem = mysqli_fetch_assoc($this->_iResId);
846             if(!$aItem) $aItem = null;
847         }
848         return $aItem;
849     }
850
851
852
853     /**
854      * Get a result row (array with numeric index)
855      *
856      * @access public
857      * @return array result row
858      */
859     public function getAsRow() {
860         $aItem = null;
861
862         if(is_object($this->_iResId)) {
863             $aItem = mysqli_fetch_row($this->_iResId);
864             if(!$aItem) $aItem = null;
865         }
866         return $aItem;
867     }
868
869 }
870
871 /**
872  * database query result class
873  *
874  * emulates a db result set out of an array so you can use array results and db results the same way
875  *
876  * @package pxFramework
877  * @see db_result
878  *
879  *
880  */
881 class fakedb_result {
882
883     /**
884      *
885      *
886      * @access private
887      */
888     private $aResultData = array();
889
890     /**
891      *
892      *
893      * @access private
894      */
895     private $aLimitedData = array();
896
897
898
899     /**
900      *
901      *
902      * @access private
903      */
904     public function fakedb_result($aData) {
905         $this->aResultData = $aData;
906         $this->aLimitedData = $aData;
907         reset($this->aLimitedData);
908     }
909
910
911
912     /**
913      * get count of result rows
914      *
915      * Returns the amount of rows in the result set
916      *
917      * @access public
918      * @return int amount of rows
919      */
920     // Gibt die Anzahl Zeilen zurück
921     public function rows() {
922         return count($this->aLimitedData);
923     }
924
925
926
927     /**
928      * Frees the result set
929      *
930      * @access public
931      */
932     // Gibt ein Ergebnisset frei
933     public function free() {
934         $this->aResultData = array();
935         $this->aLimitedData = array();
936         return;
937     }
938
939
940
941     /**
942      * Get a result row (associative)
943      *
944      * Returns the next row in the result set. To be used in a while loop like while($currow = $result->get()) { do something ... }
945      *
946      * @access public
947      * @return array result row
948      */
949     // Gibt eine Ergebniszeile zurück
950     public function get() {
951         $aItem = null;
952
953         if(!is_array($this->aLimitedData)) return $aItem;
954
955         if(list($vKey, $aItem) = each($this->aLimitedData)) {
956             if(!$aItem) $aItem = null;
957         }
958         return $aItem;
959     }
960
961
962
963     /**
964      * Get a result row (array with numeric index)
965      *
966      * @access public
967      * @return array result row
968      */
969     public function getAsRow() {
970         return $this->get();
971     }
972
973
974
975     /**
976      * Limit the result (like a LIMIT x,y in a SQL query)
977      *
978      * @access public
979      * @param int     $iStart offset to start read
980      * @param int     iLength amount of datasets to read
981      */
982     public function limit_result($iStart, $iLength) {
983         $this->aLimitedData = array_slice($this->aResultData, $iStart, $iLength, true);
984     }
985
986 }
987
988
20218c 989 ?>