Till Brehm
2014-08-25 4db6b4febf26bfa987ef741b0271ee44e5fb462e
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;
138                 $chars = array(';', '#', '/*', '*/', '--', ' UNION ', '\\\'', '\\"');
139         
140                 $string = str_replace('\\\\', '', $string);
fc0a1c 141                 $string = preg_replace('/(^|[^\\\])([\'"])(.*?[^\\\]?)\\2/is', '$1', $string);
cb1221 142                 $ok = true;
TB 143
144                 if(substr_count($string, "`") % 2 != 0 || substr_count($string, "'") % 2 != 0 || substr_count($string, '"') % 2 != 0) {
145                     $app->log("SQL injection warning (" . $string_orig . ")",2);
146                     $ok = false;
147                 } else {
148                     foreach($chars as $char) {
149                         if(strpos($string, $char) !== false) {
150                             $ok = false;
151                             $app->log("SQL injection warning (" . $string_orig . ")",2);
152                             break;
153                         }
154                     }
155                 }
156                 if($ok == true) {
157                     return true;
158                 } else {
159                     if($ids_config['sql_scan_action'] == 'warn') {
160                         // we return false in warning level.
161                         return false;
162                     } else {
163                         // if sql action = 'block' or anything else then stop here.
164                         $app->error('Possible SQL injection. All actions have been logged.');
165                     }
166                 }
167             }
168         }
169     }
f5b0ca 170
7fe908 171     public function query($queryString) {
MC 172         global $conf;
173         if($this->isConnected == false) return false;
174         $try = 0;
175         do {
176             $try++;
177             $ok = $this->ping();
178             if(!$ok) {
179                 if(!$this->real_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName)) {
180                     if($try > 4) {
181                         $this->updateError('DB::query -> reconnect');
182                         return false;
183                     } else {
184                         sleep(1);
185                     }
186                 } else {
187                     $this->setCharacterEncoding();
188                     $ok = true;
189                 }
190             }
191         } while($ok == false);
cb1221 192         $this->securityScan($queryString);
7fe908 193         $this->queryId = parent::query($queryString);
MC 194         $this->updateError('DB::query('.$queryString.') -> mysqli_query');
195         if($this->errorNumber && $conf['demo_mode'] === false) debug_print_backtrace();
196         if(!$this->queryId) {
197             return false;
198         }
199         $this->currentRow = 0;
200         return $this->queryId;
201     }
f5b0ca 202
7fe908 203     // returns all records in an array
MC 204     public function queryAllRecords($queryString) {
205         if(!$this->query($queryString))
206         {
207             return false;
208         }
209         $ret = array();
210         while($line = $this->nextRecord())
211         {
212             $ret[] = $line;
213         }
214         return $ret;
215     }
f5b0ca 216
7fe908 217     // returns one record in an array
MC 218     public function queryOneRecord($queryString) {
219         if(!$this->query($queryString) || $this->numRows() == 0)
220         {
221             return false;
222         }
223         return $this->nextRecord();
224     }
f5b0ca 225
7fe908 226     // returns the next record in an array
MC 227     public function nextRecord() {
228         $this->record = $this->queryId->fetch_assoc();
229         $this->updateError('DB::nextRecord()-> mysql_fetch_array');
230         if(!$this->record || !is_array($this->record))
231         {
232             return false;
233         }
234         $this->currentRow++;
235         return $this->record;
236     }
237
238     // returns number of rows returned by the last select query
239     public function numRows() {
240         return intval($this->queryId->num_rows);
241     }
242
243     public function affectedRows() {
244         return intval($this->queryId->affected_rows);
245     }
246
247     // returns mySQL insert id
248     public function insertID() {
249         return $this->insert_id;
250     }
251
252
253     //* Function to quote strings
254     public function quote($formfield) {
255         return $this->escape_string($formfield);
256     }
257
258     //* Function to unquotae strings
259     public function unquote($formfield) {
260         return stripslashes($formfield);
261     }
262
263     public function toLower($record) {
264         if(is_array($record)) {
265             foreach($record as $key => $val) {
266                 $key = strtolower($key);
267                 $out[$key] = $val;
268             }
269         }
270         return $out;
271     }
272
273     public function diffrec($record_old, $record_new) {
274         $diffrec_full = array();
275         $diff_num = 0;
276
277         if(is_array($record_old) && count($record_old) > 0) {
278             foreach($record_old as $key => $val) {
279                 // if(!isset($record_new[$key]) || $record_new[$key] != $val) {
280                 if(@$record_new[$key] != $val) {
281                     // Record has changed
282                     $diffrec_full['old'][$key] = $val;
283                     $diffrec_full['new'][$key] = @$record_new[$key];
284                     $diff_num++;
285                 } else {
286                     $diffrec_full['old'][$key] = $val;
287                     $diffrec_full['new'][$key] = $val;
288                 }
289             }
290         } elseif(is_array($record_new)) {
291             foreach($record_new as $key => $val) {
292                 if(isset($record_new[$key]) && @$record_old[$key] != $val) {
293                     // Record has changed
294                     $diffrec_full['new'][$key] = $val;
295                     $diffrec_full['old'][$key] = @$record_old[$key];
296                     $diff_num++;
297                 } else {
298                     $diffrec_full['new'][$key] = $val;
299                     $diffrec_full['old'][$key] = $val;
300                 }
301             }
302         }
303
304         return array('diff_num' => $diff_num, 'diff_rec' => $diffrec_full);
305
306     }
307
308     //** Function to fill the datalog with a full differential record.
309     public function datalogSave($db_table, $action, $primary_field, $primary_id, $record_old, $record_new, $force_update = false) {
310         global $app, $conf;
311
94b44c 312         // Check fields
7272e4 313         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$db_table)) $app->error('Invalid table name '.$db_table);
cd48c7 314         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$primary_field)) $app->error('Invalid primary field '.$primary_field.' in table '.$db_table);
94b44c 315         
TB 316         $primary_field = $this->quote($primary_field);
317         $primary_id = intval($primary_id);
f5b0ca 318
b0eb45 319         if($force_update == true) {
T 320             //* We force a update even if no record has changed
7fe908 321             $diffrec_full = array('new' => $record_new, 'old' => $record_old);
b0eb45 322             $diff_num = count($record_new);
T 323         } else {
324             //* get the difference record between old and new record
325             $tmp = $this->diffrec($record_old, $record_new);
326             $diffrec_full = $tmp['diff_rec'];
327             $diff_num = $tmp['diff_num'];
328             unset($tmp);
329         }
f5b0ca 330
7fe908 331         // Insert the server_id, if the record has a server_id
MC 332         $server_id = (isset($record_old['server_id']) && $record_old['server_id'] > 0)?$record_old['server_id']:0;
333         if(isset($record_new['server_id'])) $server_id = $record_new['server_id'];
e9a57d 334         $server_id = intval($server_id);
f5b0ca 335
7fe908 336         if($diff_num > 0) {
MC 337             //print_r($diff_num);
338             //print_r($diffrec_full);
339             $diffstr = $app->db->quote(serialize($diffrec_full));
340             $username = $app->db->quote($_SESSION['s']['user']['username']);
341             $dbidx = $primary_field.':'.$primary_id;
f5b0ca 342
7fe908 343             if($action == 'INSERT') $action = 'i';
MC 344             if($action == 'UPDATE') $action = 'u';
345             if($action == 'DELETE') $action = 'd';
346             $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$db_table."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
347             $app->db->query($sql);
348         }
f5b0ca 349
7fe908 350         return true;
MC 351     }
f5b0ca 352
7fe908 353     //** Inserts a record and saves the changes into the datalog
MC 354     public function datalogInsert($tablename, $insert_data, $index_field) {
355         global $app;
e9a57d 356         
94b44c 357         // Check fields
7272e4 358         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 359         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 360         
TB 361         if(strpos($tablename, '.') !== false) {
7272e4 362             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 363         } else {
7272e4 364             $tablename_escaped = '`' . $tablename . '`';
94b44c 365         }
TB 366         
e9a57d 367         $index_field = $this->quote($index_field);
7fe908 368
MC 369         if(is_array($insert_data)) {
ee260d 370             $key_str = '';
T 371             $val_str = '';
372             foreach($insert_data as $key => $val) {
373                 $key_str .= "`".$key ."`,";
374                 $val_str .= "'".$this->quote($val)."',";
375             }
7fe908 376             $key_str = substr($key_str, 0, -1);
MC 377             $val_str = substr($val_str, 0, -1);
ee260d 378             $insert_data_str = '('.$key_str.') VALUES ('.$val_str.')';
T 379         } else {
380             $insert_data_str = $insert_data;
381         }
f5b0ca 382
7fe908 383         $old_rec = array();
7272e4 384         $this->query("INSERT INTO $tablename_escaped $insert_data_str");
7fe908 385         $index_value = $this->insertID();
7272e4 386         $new_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 387         $this->datalogSave($tablename, 'INSERT', $index_field, $index_value, $old_rec, $new_rec);
f5b0ca 388
7fe908 389         return $index_value;
MC 390     }
f5b0ca 391
7fe908 392     //** Updates a record and saves the changes into the datalog
MC 393     public function datalogUpdate($tablename, $update_data, $index_field, $index_value, $force_update = false) {
ee260d 394         global $app;
e9a57d 395         
94b44c 396         // Check fields
7272e4 397         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 398         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 399         
TB 400         if(strpos($tablename, '.') !== false) {
7272e4 401             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 402         } else {
7272e4 403             $tablename_escaped = '`' . $tablename . '`';
94b44c 404         }
TB 405         
e9a57d 406         $index_field = $this->quote($index_field);
TB 407         $index_value = $this->quote($index_value);
7fe908 408
7272e4 409         $old_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 410
MC 411         if(is_array($update_data)) {
ee260d 412             $update_data_str = '';
T 413             foreach($update_data as $key => $val) {
414                 $update_data_str .= "`".$key ."` = '".$this->quote($val)."',";
415             }
7fe908 416             $update_data_str = substr($update_data_str, 0, -1);
ee260d 417         } else {
T 418             $update_data_str = $update_data;
419         }
f5b0ca 420
7272e4 421         $this->query("UPDATE $tablename_escaped SET $update_data_str WHERE $index_field = '$index_value'");
TB 422         $new_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 423         $this->datalogSave($tablename, 'UPDATE', $index_field, $index_value, $old_rec, $new_rec, $force_update);
f5b0ca 424
7fe908 425         return true;
MC 426     }
f5b0ca 427
7fe908 428     //** Deletes a record and saves the changes into the datalog
MC 429     public function datalogDelete($tablename, $index_field, $index_value) {
430         global $app;
e9a57d 431         
94b44c 432         // Check fields
7272e4 433         if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename);
cd48c7 434         if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename);
94b44c 435         
TB 436         if(strpos($tablename, '.') !== false) {
7272e4 437             $tablename_escaped = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $tablename);
94b44c 438         } else {
7272e4 439             $tablename_escaped = '`' . $tablename . '`';
94b44c 440         }
TB 441         
e9a57d 442         $index_field = $this->quote($index_field);
TB 443         $index_value = $this->quote($index_value);
f5b0ca 444
7272e4 445         $old_rec = $this->queryOneRecord("SELECT * FROM $tablename_escaped WHERE $index_field = '$index_value'");
TB 446         $this->query("DELETE FROM $tablename_escaped WHERE $index_field = '$index_value'");
7fe908 447         $new_rec = array();
MC 448         $this->datalogSave($tablename, 'DELETE', $index_field, $index_value, $old_rec, $new_rec);
449
450         return true;
451     }
452
453     //* get the current datalog status for the specified login (or currently logged in user)
454     public function datalogStatus($login = '') {
455         global $app;
456
457         $return = array('count' => 0, 'entries' => array());
458         if($_SESSION['s']['user']['typ'] == 'admin') return $return; // these information should not be displayed to admin users
459
460         if($login == '' && isset($_SESSION['s']['user'])) {
461             $login = $_SESSION['s']['user']['username'];
462         }
463
464         $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");
465         foreach($result as $row) {
466             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
467             $return['entries'][] = array('table' => $row['dbtable'], 'action' => $row['action'], 'count' => $row['cnt'], 'text' => $app->lng('datalog_status_' . $row['action'] . '_' . $row['dbtable']));
468             $return['count'] += $row['cnt'];
469         }
470         unset($result);
471
472         return $return;
473     }
f5b0ca 474
N 475
7fe908 476     public function freeResult($query)
MC 477     {
478         if(is_object($query) && (get_class($query) == "mysqli_result")) {
479             $query->free();
480             return true;
481         } else {
482             return false;
483         }
484     }
12fcb2 485
7fe908 486     /* TODO: Does anything use this? */
MC 487     public function delete() {
b5a2f8 488
7fe908 489     }
f5b0ca 490
7fe908 491     /* TODO: Does anything use this? */
MC 492     public function Transaction($action) {
493         //action = begin, commit oder rollback
f5b0ca 494
7fe908 495     }
f5b0ca 496
7fe908 497     /*
f5b0ca 498        $columns = array(action =>   add | alter | drop
N 499        name =>     Spaltenname
500        name_new => neuer Spaltenname, nur bei 'alter' belegt
501        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
502        typeValue => Wert z.B. bei Varchar
503        defaultValue =>  Default Wert
504        notNull =>   true | false
505        autoInc =>   true | false
506        option =>   unique | primary | index)
507
508
509      */
510
7fe908 511     public function createTable($table_name, $columns) {
MC 512         $index = '';
513         $sql = "CREATE TABLE $table_name (";
514         foreach($columns as $col){
515             $sql .= $col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
f5b0ca 516
7fe908 517             if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
MC 518             if($col['notNull'] == true) {
519                 $sql .= 'NOT NULL ';
520             } else {
521                 $sql .= 'NULL ';
522             }
523             if($col['autoInc'] == true) $sql .= 'auto_increment ';
524             $sql.= ',';
525             // key Definitionen
526             if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
527             if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
528             if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
529         }
530         $sql .= $index;
531         $sql = substr($sql, 0, -1);
532         $sql .= ')';
533         $this->query($sql);
534         return true;
f5b0ca 535     }
N 536
7fe908 537     /*
f5b0ca 538        $columns = array(action =>   add | alter | drop
N 539        name =>     Spaltenname
540        name_new => neuer Spaltenname, nur bei 'alter' belegt
541        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
542        typeValue => Wert z.B. bei Varchar
543        defaultValue =>  Default Wert
544        notNull =>   true | false
545        autoInc =>   true | false
546        option =>   unique | primary | index)
547
548
549      */
7fe908 550     public function alterTable($table_name, $columns) {
MC 551         $index = '';
552         $sql = "ALTER TABLE $table_name ";
553         foreach($columns as $col){
554             if($col['action'] == 'add') {
555                 $sql .= 'ADD '.$col['name'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
556             } elseif ($col['action'] == 'alter') {
557                 $sql .= 'CHANGE '.$col['name'].' '.$col['name_new'].' '.$this->mapType($col['type'], $col['typeValue']).' ';
558             } elseif ($col['action'] == 'drop') {
559                 $sql .= 'DROP '.$col['name'].' ';
560             }
561             if($col['action'] != 'drop') {
562                 if($col['defaultValue'] != '') $sql .= "DEFAULT '".$col['defaultValue']."' ";
563                 if($col['notNull'] == true) {
564                     $sql .= 'NOT NULL ';
565                 } else {
566                     $sql .= 'NULL ';
567                 }
568                 if($col['autoInc'] == true) $sql .= 'auto_increment ';
569                 $sql.= ',';
570                 // Index definitions
571                 if($col['option'] == 'primary') $index .= 'PRIMARY KEY ('.$col['name'].'),';
572                 if($col['option'] == 'index') $index .= 'INDEX ('.$col['name'].'),';
573                 if($col['option'] == 'unique') $index .= 'UNIQUE ('.$col['name'].'),';
574             }
575         }
576         $sql .= $index;
577         $sql = substr($sql, 0, -1);
578
579         //die($sql);
580         $this->query($sql);
581         return true;
f5b0ca 582     }
7fe908 583
MC 584     public function dropTable($table_name) {
585         $this->check($table_name);
586         $sql = "DROP TABLE '". $table_name."'";
587         return $this->query($sql);
f5b0ca 588     }
N 589
7fe908 590     // gibt Array mit Tabellennamen zur�ck
MC 591     public function getTables($database_name = '') {
592         if($this->isConnected == false) return false;
593         if($database_name == '') $database_name = $this->dbName;
594         $result = parent::query("SHOW TABLES FROM $database_name");
595         for ($i = 0; $i < $result->num_rows; $i++) {
596             $tb_names[$i] = (($result->data_seek( $i) && (($___mysqli_tmp = $result->fetch_row()) !== NULL)) ? array_shift($___mysqli_tmp) : false);
597         }
598         return $tb_names;
599     }
f5b0ca 600
7fe908 601     // gibt Feldinformationen zur Tabelle zur�ck
MC 602     /*
f5b0ca 603        $columns = array(action =>   add | alter | drop
N 604        name =>     Spaltenname
605        name_new => neuer Spaltenname, nur bei 'alter' belegt
606        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
607        typeValue => Wert z.B. bei Varchar
608        defaultValue =>  Default Wert
609        notNull =>   true | false
610        autoInc =>   true | false
611        option =>   unique | primary | index)
612
613
614      */
615
7fe908 616     function tableInfo($table_name) {
f5b0ca 617
7fe908 618         global $go_api, $go_info, $app;
MC 619         // Tabellenfelder einlesen
f5b0ca 620
7fe908 621         if($rows = $app->db->queryAllRecords('SHOW FIELDS FROM '.$table_name)){
MC 622             foreach($rows as $row) {
623                 /*
f5b0ca 624       $name = $row[0];
N 625       $default = $row[4];
626       $key = $row[3];
627       $extra = $row[5];
628       $isnull = $row[2];
629       $type = $row[1];
bfcdef 630       */
7fe908 631
MC 632                 $name = $row['Field'];
633                 $default = $row['Default'];
634                 $key = $row['Key'];
635                 $extra = $row['Extra'];
636                 $isnull = $row['Null'];
637                 $type = $row['Type'];
f5b0ca 638
N 639
7fe908 640                 $column = array();
f5b0ca 641
7fe908 642                 $column['name'] = $name;
MC 643                 //$column['type'] = $type;
644                 $column['defaultValue'] = $default;
645                 if(stristr($key, 'PRI')) $column['option'] = 'primary';
646                 if(stristr($isnull, 'YES')) {
647                     $column['notNull'] = false;
648                 } else {
649                     $column['notNull'] = true;
650                 }
651                 if($extra == 'auto_increment') $column['autoInc'] = true;
f5b0ca 652
N 653
7fe908 654                 // Type in Metatype umsetzen
f5b0ca 655
7fe908 656                 if(stristr($type, 'int(')) $metaType = 'int32';
MC 657                 if(stristr($type, 'bigint')) $metaType = 'int64';
658                 if(stristr($type, 'char')) {
659                     $metaType = 'char';
660                     $tmp_typeValue = explode('(', $type);
661                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
662                 }
663                 if(stristr($type, 'varchar')) {
664                     $metaType = 'varchar';
665                     $tmp_typeValue = explode('(', $type);
666                     $column['typeValue'] = substr($tmp_typeValue[1], 0, -1);
667                 }
668                 if(stristr($type, 'text')) $metaType = 'text';
669                 if(stristr($type, 'double')) $metaType = 'double';
670                 if(stristr($type, 'blob')) $metaType = 'blob';
f5b0ca 671
N 672
7fe908 673                 $column['type'] = $metaType;
f5b0ca 674
7fe908 675                 $columns[] = $column;
MC 676             }
677             return $columns;
678         } else {
679             return false;
680         }
f5b0ca 681
N 682
7fe908 683         //$this->createTable('tester',$columns);
f5b0ca 684
7fe908 685         /*
f5b0ca 686      $result = mysql_list_fields($go_info["server"]["db_name"],$table_name);
N 687      $fields = mysql_num_fields ($result);
688      $i = 0;
689      $table = mysql_field_table ($result, $i);
690      while ($i < $fields) {
691      $name  = mysql_field_name  ($result, $i);
692      $type  = mysql_field_type  ($result, $i);
693      $len   = mysql_field_len   ($result, $i);
694      $flags = mysql_field_flags ($result, $i);
695      print_r($flags);
696
697      $columns = array(name => $name,
698      type =>     "",
699      defaultValue =>  "",
700      isnull =>   1,
701      option =>   "");
702      $returnvar[] = $columns;
703
704      $i++;
705      }
706        */
707
708
709
7fe908 710     }
f5b0ca 711
7fe908 712     public function mapType($metaType, $typeValue) {
MC 713         global $go_api;
714         $metaType = strtolower($metaType);
715         switch ($metaType) {
716         case 'int16':
717             return 'smallint';
718             break;
719         case 'int32':
720             return 'int';
721             break;
722         case 'int64':
723             return 'bigint';
724             break;
725         case 'double':
726             return 'double';
727             break;
728         case 'char':
729             return 'char';
730             break;
731         case 'varchar':
732             if($typeValue < 1) die('Database failure: Lenght required for these data types.');
733             return 'varchar('.$typeValue.')';
734             break;
735         case 'text':
736             return 'text';
737             break;
738         case 'blob':
739             return 'blob';
740             break;
8748b3 741         case 'date':
TB 742             return 'date';
743             break;
7fe908 744         }
MC 745     }
f5b0ca 746
7fe908 747 }
f5b0ca 748
7fe908 749 ?>