Till Brehm
2014-10-16 68b1465cab0805f42facbbc76acf68e51889ccbf
commit | author | age
b5a2f8 1 <?php
T 2 /*
f5b0ca 3    Copyright (c) 2005, Till Brehm, projektfarm Gmbh
N 4    All rights reserved.
b5a2f8 5
f5b0ca 6    Redistribution and use in source and binary forms, with or without modification,
N 7    are permitted provided that the following conditions are met:
b5a2f8 8
f5b0ca 9  * Redistributions of source code must retain the above copyright notice,
N 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.
b5a2f8 17
f5b0ca 18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
N 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  */
b5a2f8 29
f5b0ca 30 class db extends mysqli
N 31 {
7fe908 32     private $dbHost = '';  // hostname of the MySQL server
MC 33     private $dbName = '';  // logical database name on that server
34     private $dbUser = '';  // database authorized user
35     private $dbPass = '';  // user's password
36     private $dbCharset = 'utf8';// Database charset
37     private $dbNewLink = false; // Return a new linkID when connect is called again
38     private $dbClientFlags = 0; // MySQL Client falgs
39     private $linkId = 0;  // last result of mysqli_connect()
40     private $queryId = 0;  // last result of mysqli_query()
41     private $record = array(); // last record fetched
42     private $autoCommit = 1;    // Autocommit Transactions
43     private $currentRow;  // current row number
44     private $errorNumber = 0; // last error number
45     public $errorMessage = ''; // last error message
46     private $errorLocation = '';// last error location
47     public $show_error_messages = false; // false in server, true in interface
48     private $isConnected = false; // needed to know if we have a valid mysqli object from the constructor
b5a2f8 49
7fe908 50     // constructor
MC 51     public function __construct($prefix = '') {
52         global $conf;
53         if($prefix != '') $prefix .= '_';
54         $this->dbHost = $conf[$prefix.'db_host'];
55         $this->dbName = $conf[$prefix.'db_database'];
56         $this->dbUser = $conf[$prefix.'db_user'];
57         $this->dbPass = $conf[$prefix.'db_password'];
58         $this->dbCharset = $conf[$prefix.'db_charset'];
59         $this->dbNewLink = $conf[$prefix.'db_new_link'];
60         $this->dbClientFlags = $conf[$prefix.'db_client_flags'];
61         parent::__construct($conf[$prefix.'db_host'], $conf[$prefix.'db_user'], $conf[$prefix.'db_password'], $conf[$prefix.'db_database']);
62         $try = 0;
63         //while(!is_null($this->connect_error) && $try < 5) {
64         while(mysqli_connect_error() && $try < 5) {
65             if($try > 0) sleep(1);
f5b0ca 66
7fe908 67             $try++;
MC 68             $this->updateError('DB::__construct');
f5b0ca 69
7fe908 70             parent::__construct($conf[$prefix.'db_host'], $conf[$prefix.'db_user'], $conf[$prefix.'db_password'], $conf[$prefix.'db_database']);
MC 71         }
f5b0ca 72
7fe908 73         //if(is_null($this->connect_error)) $this->isConnected = true;
MC 74         //else return false;
75         if(!mysqli_connect_error()) $this->isConnected = true;
76         else return false;
77
78         $this->setCharacterEncoding();
79     }
80
81     public function __destruct() {
82         $this->close(); // helps avoid memory leaks, and persitent connections that don't go away.
83     }
84
85     // error handler
86     public function updateError($location) {
87         global $app, $conf;
88
89         /*
72695f 90     if(!is_null($this->connect_error)) {
f5b0ca 91       $this->errorNumber = $this->connect_errno;
N 92       $this->errorMessage = $this->connect_error;
93     } else {
94       $this->errorNumber = $this->errno;
95       $this->errorMessage = $this->error;
e6c1c4 96     }
cc6568 97     */
7fe908 98         if(mysqli_connect_error()) {
MC 99             $this->errorNumber = mysqli_connect_errno();
100             $this->errorMessage = mysqli_connect_error();
101         } else {
102             $this->errorNumber = mysqli_errno($this);
103             $this->errorMessage = mysqli_error($this);
104         }
cc6568 105
f5b0ca 106
7fe908 107         $this->errorLocation = $location;
MC 108         if($this->errorNumber) {
109             $error_msg = $this->errorLocation .' '. $this->errorMessage;
110             // This right here will allow us to use the same file for server & interface
111             if($this->show_error_messages && $conf['demo_mode'] === false) {
112                 echo $error_msg;
113             } else if(is_object($app) && method_exists($app, 'log')) {
114                     $app->log($error_msg, LOGLEVEL_WARN);
115                 }
116         }
f5b0ca 117     }
7fe908 118
MC 119     private function setCharacterEncoding() {
120         if($this->isConnected == false) return false;
121         parent::query( 'SET NAMES '.$this->dbCharset);
122         parent::query( "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."'");
f5b0ca 123     }
cb1221 124     
TB 125     private function securityScan($string) {
126         global $app, $conf;
127         
128         // get security config
129         if(isset($app)) {
130             $app->uses('getconf');
131             $ids_config = $app->getconf->get_security_config('ids');
132             
133             if($ids_config['sql_scan_enabled'] == 'yes') {
134                 
135                 $string_orig = $string;
136                 
137                 //echo $string;
68b146 138                 $chars = array(';', '#', '/*', '*/', '--', '\\\'', '\\"');
cb1221 139         
TB 140                 $string = str_replace('\\\\', '', $string);
f986a3 141                 $string = preg_replace('/(^|[^\\\])([\'"])\\2/is', '$1', $string);
MC 142                 $string = preg_replace('/(^|[^\\\])([\'"])(.*?[^\\\])\\2/is', '$1', $string);
cb1221 143                 $ok = true;
TB 144
145                 if(substr_count($string, "`") % 2 != 0 || substr_count($string, "'") % 2 != 0 || substr_count($string, '"') % 2 != 0) {
146                     $app->log("SQL injection warning (" . $string_orig . ")",2);
147                     $ok = false;
148                 } else {
149                     foreach($chars as $char) {
150                         if(strpos($string, $char) !== false) {
151                             $ok = false;
152                             $app->log("SQL injection warning (" . $string_orig . ")",2);
153                             break;
154                         }
155                     }
156                 }
157                 if($ok == true) {
158                     return true;
159                 } else {
160                     if($ids_config['sql_scan_action'] == 'warn') {
161                         // we return false in warning level.
162                         return false;
163                     } else {
164                         // if sql action = 'block' or anything else then stop here.
165                         $app->error('Possible SQL injection. All actions have been logged.');
166                     }
167                 }
168             }
169         }
170     }
f5b0ca 171
7fe908 172     public function query($queryString) {
MC 173         global $conf;
174         if($this->isConnected == false) return false;
175         $try = 0;
176         do {
177             $try++;
178             $ok = $this->ping();
179             if(!$ok) {
180                 if(!$this->real_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName)) {
181                     if($try > 4) {
182                         $this->updateError('DB::query -> reconnect');
183                         return false;
184                     } else {
185                         sleep(1);
186                     }
187                 } else {
188                     $this->setCharacterEncoding();
189                     $ok = true;
190                 }
191             }
192         } while($ok == false);
cb1221 193         $this->securityScan($queryString);
7fe908 194         $this->queryId = parent::query($queryString);
MC 195         $this->updateError('DB::query('.$queryString.') -> mysqli_query');
196         if($this->errorNumber && $conf['demo_mode'] === false) debug_print_backtrace();
197         if(!$this->queryId) {
198             return false;
199         }
200         $this->currentRow = 0;
201         return $this->queryId;
202     }
f5b0ca 203
7fe908 204     // returns all records in an array
MC 205     public function queryAllRecords($queryString) {
206         if(!$this->query($queryString))
207         {
208             return false;
209         }
210         $ret = array();
211         while($line = $this->nextRecord())
212         {
213             $ret[] = $line;
214         }
215         return $ret;
216     }
f5b0ca 217
7fe908 218     // returns one record in an array
MC 219     public function queryOneRecord($queryString) {
220         if(!$this->query($queryString) || $this->numRows() == 0)
221         {
222             return false;
223         }
224         return $this->nextRecord();
225     }
f5b0ca 226
7fe908 227     // returns the next record in an array
MC 228     public function nextRecord() {
229         $this->record = $this->queryId->fetch_assoc();
230         $this->updateError('DB::nextRecord()-> mysql_fetch_array');
231         if(!$this->record || !is_array($this->record))
232         {
233             return false;
234         }
235         $this->currentRow++;
236         return $this->record;
237     }
238
239     // returns number of rows returned by the last select query
240     public function numRows() {
241         return intval($this->queryId->num_rows);
242     }
243
244     public function affectedRows() {
245         return intval($this->queryId->affected_rows);
246     }
247
248     // returns mySQL insert id
249     public function insertID() {
250         return $this->insert_id;
251     }
252
253
254     //* Function to quote strings
255     public function quote($formfield) {
256         return $this->escape_string($formfield);
257     }
258
259     //* Function to unquotae strings
260     public function unquote($formfield) {
261         return stripslashes($formfield);
262     }
263
264     public function toLower($record) {
265         if(is_array($record)) {
266             foreach($record as $key => $val) {
267                 $key = strtolower($key);
268                 $out[$key] = $val;
269             }
270         }
271         return $out;
272     }
273
274     public function diffrec($record_old, $record_new) {
275         $diffrec_full = array();
276         $diff_num = 0;
277
278         if(is_array($record_old) && count($record_old) > 0) {
279             foreach($record_old as $key => $val) {
280                 // if(!isset($record_new[$key]) || $record_new[$key] != $val) {
281                 if(@$record_new[$key] != $val) {
282                     // Record has changed
283                     $diffrec_full['old'][$key] = $val;
284                     $diffrec_full['new'][$key] = @$record_new[$key];
285                     $diff_num++;
286                 } else {
287                     $diffrec_full['old'][$key] = $val;
288                     $diffrec_full['new'][$key] = $val;
289                 }
290             }
291         } elseif(is_array($record_new)) {
292             foreach($record_new as $key => $val) {
293                 if(isset($record_new[$key]) && @$record_old[$key] != $val) {
294                     // Record has changed
295                     $diffrec_full['new'][$key] = $val;
296                     $diffrec_full['old'][$key] = @$record_old[$key];
297                     $diff_num++;
298                 } else {
299                     $diffrec_full['new'][$key] = $val;
300                     $diffrec_full['old'][$key] = $val;
301                 }
302             }
303         }
304
305         return array('diff_num' => $diff_num, 'diff_rec' => $diffrec_full);
306
307     }
308
309     //** Function to fill the datalog with a full differential record.
310     public function datalogSave($db_table, $action, $primary_field, $primary_id, $record_old, $record_new, $force_update = false) {
311         global $app, $conf;
312
94b44c 313         // Check fields
7272e4 314         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$db_table)) $app->error('Invalid table name '.$db_table);
cd48c7 315         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$primary_field)) $app->error('Invalid primary field '.$primary_field.' in table '.$db_table);
94b44c 316         
TB 317         $primary_field = $this->quote($primary_field);
318         $primary_id = intval($primary_id);
f5b0ca 319
b0eb45 320         if($force_update == true) {
T 321             //* We force a update even if no record has changed
7fe908 322             $diffrec_full = array('new' => $record_new, 'old' => $record_old);
b0eb45 323             $diff_num = count($record_new);
T 324         } else {
325             //* get the difference record between old and new record
326             $tmp = $this->diffrec($record_old, $record_new);
327             $diffrec_full = $tmp['diff_rec'];
328             $diff_num = $tmp['diff_num'];
329             unset($tmp);
330         }
f5b0ca 331
7fe908 332         // Insert the server_id, if the record has a server_id
MC 333         $server_id = (isset($record_old['server_id']) && $record_old['server_id'] > 0)?$record_old['server_id']:0;
334         if(isset($record_new['server_id'])) $server_id = $record_new['server_id'];
e9a57d 335         $server_id = intval($server_id);
f5b0ca 336
7fe908 337         if($diff_num > 0) {
MC 338             //print_r($diff_num);
339             //print_r($diffrec_full);
340             $diffstr = $app->db->quote(serialize($diffrec_full));
341             $username = $app->db->quote($_SESSION['s']['user']['username']);
342             $dbidx = $primary_field.':'.$primary_id;
f5b0ca 343
7fe908 344             if($action == 'INSERT') $action = 'i';
MC 345             if($action == 'UPDATE') $action = 'u';
346             if($action == 'DELETE') $action = 'd';
347             $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$db_table."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
348             $app->db->query($sql);
349         }
f5b0ca 350
7fe908 351         return true;
MC 352     }
f5b0ca 353
7fe908 354     //** Inserts a record and saves the changes into the datalog
MC 355     public function datalogInsert($tablename, $insert_data, $index_field) {
356         global $app;
e9a57d 357         
94b44c 358         // Check fields
7272e4 359         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 360         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 361         
TB 362         if(strpos($tablename, '.') !== false) {
7272e4 363             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 364         } else {
7272e4 365             $tablename_escaped = '`' . $tablename . '`';
94b44c 366         }
TB 367         
e9a57d 368         $index_field = $this->quote($index_field);
7fe908 369
MC 370         if(is_array($insert_data)) {
ee260d 371             $key_str = '';
T 372             $val_str = '';
373             foreach($insert_data as $key => $val) {
374                 $key_str .= "`".$key ."`,";
375                 $val_str .= "'".$this->quote($val)."',";
376             }
7fe908 377             $key_str = substr($key_str, 0, -1);
MC 378             $val_str = substr($val_str, 0, -1);
ee260d 379             $insert_data_str = '('.$key_str.') VALUES ('.$val_str.')';
T 380         } else {
381             $insert_data_str = $insert_data;
382         }
f5b0ca 383
7fe908 384         $old_rec = array();
7272e4 385         $this->query("INSERT INTO $tablename_escaped $insert_data_str");
7fe908 386         $index_value = $this->insertID();
7272e4 387         $new_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 388         $this->datalogSave($tablename, 'INSERT', $index_field, $index_value, $old_rec, $new_rec);
f5b0ca 389
7fe908 390         return $index_value;
MC 391     }
f5b0ca 392
7fe908 393     //** Updates a record and saves the changes into the datalog
MC 394     public function datalogUpdate($tablename, $update_data, $index_field, $index_value, $force_update = false) {
ee260d 395         global $app;
e9a57d 396         
94b44c 397         // Check fields
7272e4 398         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 399         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 400         
TB 401         if(strpos($tablename, '.') !== false) {
7272e4 402             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 403         } else {
7272e4 404             $tablename_escaped = '`' . $tablename . '`';
94b44c 405         }
TB 406         
e9a57d 407         $index_field = $this->quote($index_field);
TB 408         $index_value = $this->quote($index_value);
7fe908 409
7272e4 410         $old_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 411
MC 412         if(is_array($update_data)) {
ee260d 413             $update_data_str = '';
T 414             foreach($update_data as $key => $val) {
415                 $update_data_str .= "`".$key ."` = '".$this->quote($val)."',";
416             }
7fe908 417             $update_data_str = substr($update_data_str, 0, -1);
ee260d 418         } else {
T 419             $update_data_str = $update_data;
420         }
f5b0ca 421
7272e4 422         $this->query("UPDATE $tablename_escaped SET $update_data_str WHERE $index_field = '$index_value'");
TB 423         $new_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 424         $this->datalogSave($tablename, 'UPDATE', $index_field, $index_value, $old_rec, $new_rec, $force_update);
f5b0ca 425
7fe908 426         return true;
MC 427     }
f5b0ca 428
7fe908 429     //** Deletes a record and saves the changes into the datalog
MC 430     public function datalogDelete($tablename, $index_field, $index_value) {
431         global $app;
e9a57d 432         
94b44c 433         // Check fields
7272e4 434         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 435         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 436         
TB 437         if(strpos($tablename, '.') !== false) {
7272e4 438             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 439         } else {
7272e4 440             $tablename_escaped = '`' . $tablename . '`';
94b44c 441         }
TB 442         
e9a57d 443         $index_field = $this->quote($index_field);
TB 444         $index_value = $this->quote($index_value);
f5b0ca 445
7272e4 446         $old_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
TB 447         $this->query("DELETE FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 448         $new_rec = array();
MC 449         $this->datalogSave($tablename, 'DELETE', $index_field, $index_value, $old_rec, $new_rec);
450
451         return true;
452     }
453
454     //* get the current datalog status for the specified login (or currently logged in user)
455     public function datalogStatus($login = '') {
456         global $app;
457
458         $return = array('count' => 0, 'entries' => array());
459         if($_SESSION['s']['user']['typ'] == 'admin') return $return; // these information should not be displayed to admin users
460
461         if($login == '' && isset($_SESSION['s']['user'])) {
462             $login = $_SESSION['s']['user']['username'];
463         }
464
465         $result = $this->queryAllRecords("SELECT COUNT( * ) AS cnt, sys_datalog.action, sys_datalog.dbtable FROM sys_datalog, server WHERE server.server_id = sys_datalog.server_id AND sys_datalog.user = '" . $this->quote($login) . "' AND sys_datalog.datalog_id > server.updated GROUP BY sys_datalog.dbtable, sys_datalog.action");
466         foreach($result as $row) {
467             if(!$row['dbtable'] || in_array($row['dbtable'], array('aps_instances', 'aps_instances_settings', 'mail_access', 'mail_content_filter'))) continue; // ignore some entries, maybe more to come
468             $return['entries'][] = array('table' => $row['dbtable'], 'action' => $row['action'], 'count' => $row['cnt'], 'text' => $app->lng('datalog_status_' . $row['action'] . '_' . $row['dbtable']));
469             $return['count'] += $row['cnt'];
470         }
471         unset($result);
472
473         return $return;
474     }
f5b0ca 475
N 476
7fe908 477     public function freeResult($query)
MC 478     {
479         if(is_object($query) && (get_class($query) == "mysqli_result")) {
480             $query->free();
481             return true;
482         } else {
483             return false;
484         }
485     }
12fcb2 486
7fe908 487     /* TODO: Does anything use this? */
MC 488     public function delete() {
b5a2f8 489
7fe908 490     }
f5b0ca 491
7fe908 492     /* TODO: Does anything use this? */
MC 493     public function Transaction($action) {
494         //action = begin, commit oder rollback
f5b0ca 495
7fe908 496     }
f5b0ca 497
7fe908 498     /*
f5b0ca 499        $columns = array(action =>   add | alter | drop
N 500        name =>     Spaltenname
501        name_new => neuer Spaltenname, nur bei 'alter' belegt
502        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
503        typeValue => Wert z.B. bei Varchar
504        defaultValue =>  Default Wert
505        notNull =>   true | false
506        autoInc =>   true | false
507        option =>   unique | primary | index)
508
509
510      */
511
7fe908 512     public function createTable($table_name, $columns) {
MC 513         $index = '';
514         $sql = "CREATE TABLE $table_name (";
515         foreach($columns as $col){
516             $sql .= $col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
f5b0ca 517
7fe908 518             if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
MC 519             if($col['notNull'] == true) {
520                 $sql .= 'NOT NULL ';
521             } else {
522                 $sql .= 'NULL ';
523             }
524             if($col['autoInc'] == true) $sql .= 'auto_increment ';
525             $sql.= ',';
526             // key Definitionen
527             if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
528             if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
529             if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
530         }
531         $sql .= $index;
532         $sql = substr($sql, 0, -1);
533         $sql .= ')';
534         $this->query($sql);
535         return true;
f5b0ca 536     }
N 537
7fe908 538     /*
f5b0ca 539        $columns = array(action =>   add | alter | drop
N 540        name =>     Spaltenname
541        name_new => neuer Spaltenname, nur bei 'alter' belegt
542        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
543        typeValue => Wert z.B. bei Varchar
544        defaultValue =>  Default Wert
545        notNull =>   true | false
546        autoInc =>   true | false
547        option =>   unique | primary | index)
548
549
550      */
7fe908 551     public function alterTable($table_name, $columns) {
MC 552         $index = '';
553         $sql = "ALTER TABLE $table_name ";
554         foreach($columns as $col){
555             if($col['action'] == 'add') {
556                 $sql .= 'ADD '.$col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
557             } elseif ($col['action'] == 'alter') {
558                 $sql .= 'CHANGE '.$col['name'].' '.$col['name_new'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
559             } elseif ($col['action'] == 'drop') {
560                 $sql .= 'DROP '.$col['name'].' ';
561             }
562             if($col['action'] != 'drop') {
563                 if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
564                 if($col['notNull'] == true) {
565                     $sql .= 'NOT NULL ';
566                 } else {
567                     $sql .= 'NULL ';
568                 }
569                 if($col['autoInc'] == true) $sql .= 'auto_increment ';
570                 $sql.= ',';
571                 // Index definitions
572                 if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
573                 if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
574                 if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
575             }
576         }
577         $sql .= $index;
578         $sql = substr($sql, 0, -1);
579
580         //die($sql);
581         $this->query($sql);
582         return true;
f5b0ca 583     }
7fe908 584
MC 585     public function dropTable($table_name) {
586         $this->check($table_name);
587         $sql = "DROP TABLE '". $table_name."'";
588         return $this->query($sql);
f5b0ca 589     }
N 590
7fe908 591     // gibt Array mit Tabellennamen zur�ck
MC 592     public function getTables($database_name = '') {
593         if($this->isConnected == false) return false;
594         if($database_name == '') $database_name = $this->dbName;
595         $result = parent::query("SHOW TABLES FROM $database_name");
596         for ($i = 0; $i < $result->num_rows; $i++) {
597             $tb_names[$i] = (($result->data_seek( $i) && (($___mysqli_tmp = $result->fetch_row()) !== NULL)) ? array_shift($___mysqli_tmp) : false);
598         }
599         return $tb_names;
600     }
f5b0ca 601
7fe908 602     // gibt Feldinformationen zur Tabelle zur�ck
MC 603     /*
f5b0ca 604        $columns = array(action =>   add | alter | drop
N 605        name =>     Spaltenname
606        name_new => neuer Spaltenname, nur bei 'alter' belegt
607        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
608        typeValue => Wert z.B. bei Varchar
609        defaultValue =>  Default Wert
610        notNull =>   true | false
611        autoInc =>   true | false
612        option =>   unique | primary | index)
613
614
615      */
616
7fe908 617     function tableInfo($table_name) {
f5b0ca 618
7fe908 619         global $go_api, $go_info, $app;
MC 620         // Tabellenfelder einlesen
f5b0ca 621
7fe908 622         if($rows = $app->db->queryAllRecords('SHOW FIELDS FROM '.$table_name)){
MC 623             foreach($rows as $row) {
624                 /*
f5b0ca 625       $name = $row[0];
N 626       $default = $row[4];
627       $key = $row[3];
628       $extra = $row[5];
629       $isnull = $row[2];
630       $type = $row[1];
bfcdef 631       */
7fe908 632
MC 633                 $name = $row['Field'];
634                 $default = $row['Default'];
635                 $key = $row['Key'];
636                 $extra = $row['Extra'];
637                 $isnull = $row['Null'];
638                 $type = $row['Type'];
f5b0ca 639
N 640
7fe908 641                 $column = array();
f5b0ca 642
7fe908 643                 $column['name'] = $name;
MC 644                 //$column['type'] = $type;
645                 $column['defaultValue'] = $default;
646                 if(stristr($key, 'PRI')) $column['option'] = 'primary';
647                 if(stristr($isnull, 'YES')) {
648                     $column['notNull'] = false;
649                 } else {
650                     $column['notNull'] = true;
651                 }
652                 if($extra == 'auto_increment') $column['autoInc'] = true;
f5b0ca 653
N 654
7fe908 655                 // Type in Metatype umsetzen
f5b0ca 656
7fe908 657                 if(stristr($type, 'int(')) $metaType = 'int32';
MC 658                 if(stristr($type, 'bigint')) $metaType = 'int64';
659                 if(stristr($type, 'char')) {
660                     $metaType = 'char';
661                     $tmp_typeValue = explode('(', $type);
662                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
663                 }
664                 if(stristr($type, 'varchar')) {
665                     $metaType = 'varchar';
666                     $tmp_typeValue = explode('(', $type);
667                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
668                 }
669                 if(stristr($type, 'text')) $metaType = 'text';
670                 if(stristr($type, 'double')) $metaType = 'double';
671                 if(stristr($type, 'blob')) $metaType = 'blob';
f5b0ca 672
N 673
7fe908 674                 $column['type'] = $metaType;
f5b0ca 675
7fe908 676                 $columns[] = $column;
MC 677             }
678             return $columns;
679         } else {
680             return false;
681         }
f5b0ca 682
N 683
7fe908 684         //$this->createTable('tester',$columns);
f5b0ca 685
7fe908 686         /*
f5b0ca 687      $result = mysql_list_fields($go_info["server"]["db_name"],$table_name);
N 688      $fields = mysql_num_fields ($result);
689      $i = 0;
690      $table = mysql_field_table ($result, $i);
691      while ($i < $fields) {
692      $name  = mysql_field_name  ($result, $i);
693      $type  = mysql_field_type  ($result, $i);
694      $len   = mysql_field_len   ($result, $i);
695      $flags = mysql_field_flags ($result, $i);
696      print_r($flags);
697
698      $columns = array(name => $name,
699      type =>     "",
700      defaultValue =>  "",
701      isnull =>   1,
702      option =>   "");
703      $returnvar[] = $columns;
704
705      $i++;
706      }
707        */
708
709
710
7fe908 711     }
f5b0ca 712
7fe908 713     public function mapType($metaType, $typeValue) {
MC 714         global $go_api;
715         $metaType = strtolower($metaType);
716         switch ($metaType) {
717         case 'int16':
718             return 'smallint';
719             break;
720         case 'int32':
721             return 'int';
722             break;
723         case 'int64':
724             return 'bigint';
725             break;
726         case 'double':
727             return 'double';
728             break;
729         case 'char':
730             return 'char';
731             break;
732         case 'varchar':
733             if($typeValue < 1) die('Database failure: Lenght required for these data types.');
734             return 'varchar('.$typeValue.')';
735             break;
736         case 'text':
737             return 'text';
738             break;
739         case 'blob':
740             return 'blob';
741             break;
8748b3 742         case 'date':
TB 743             return 'date';
744             break;
7fe908 745         }
MC 746     }
f5b0ca 747
7fe908 748 }
f5b0ca 749
7fe908 750 ?>