EGOCMS  24.0
EGOTEC Content-Managament-System
Ego_Sql_mysqli.php
gehe zur Dokumentation dieser Datei
1 <?php
5 require_once('base/Ego_Sql_Abstract.php');
6 
16 {
17  private $_dbHandle;
18  private $_queryHandle;
24  function connect($database='', $host='', $user='', $password='')
25  {
26  if (func_num_args()==0)
27  {
29  { // Nur die EGOTEC Standardverbindung wird global gespeichert.
30  $this->_dbHandle = Ego_Sql_mysqli::$_staticMysqliHandle;
31  return;
32  } else {
33  $this->_dbHandle = @mysqli_connect(
34  $GLOBALS['egotec_conf']['db']['host'],
35  $GLOBALS['egotec_conf']['db']['user'],
36  $GLOBALS['egotec_conf']['db']['password'],
37  $GLOBALS['egotec_conf']['db']['database'],
38  $GLOBALS['egotec_conf']['db']['port'],
39  $GLOBALS['egotec_conf']['db']['socket']
40  ) or $this->onError('connect');
41  Ego_Sql_mysqli::$_staticMysqliHandle = $this->_dbHandle; // Nur die EGOTEC Standardverbindung wird global gespeichert.
42  }
43  } else {
44  $this->_dbHandle = @mysqli_connect($host, $user, $password, $database)
45  or $this->onError('connect');
46  }
47  if (!$this->_dbHandle)
48  {
49  // Wenn der DB Handle nicht besteht wird eine Exception geworfen.
50  throw new Ego_Sql_Exception( 'Konnte keine Datenbankverbindung herstellen.', Ego_Sql_Exception::CONNECT_ERROR );
51  }
52  $this->query('SET NAMES utf8');
53  $this->query('SET collation_connection=\'utf8_bin\'');
54  if ($GLOBALS['egotec_conf']['db']['profiling'])
55  {
56  $this->query('SET PROFILING=1');
57  }
58  }
59 
66  function query($query, $appendCurrent = false)
67  {
68  if ($appendCurrent) {
69  $this->currentQuery .= $query;
70  } else {
71  $this->currentQuery = $query;
72  }
73  $this->_queryHandle = mysqli_query($this->_dbHandle, $query);
74  if (!$this->_queryHandle) { // Die Abfrage ist fehlgeschlagen.
75  throw new Ego_Sql_Exception($query."\n".mysqli_error($this->_dbHandle), Ego_Sql_Exception::QUERY_ERROR);
76  }
77  $this->_currentRow = -1;
78  return $this->_queryHandle;
79  }
80 
86  protected function _nextRecord()
87  {
89  return $this->Record = $this->_queryHandle?mysqli_fetch_assoc($this->_queryHandle):false;
90  }
91 
97  protected function _numRecords()
98  {
99  return $this->_queryHandle?mysqli_num_rows($this->_queryHandle):0;
100  }
101 
110  protected function _selectString($query)
111  {
112  if ($query['bitand']) {
113  if (empty($query['where'])) {
114  $query['where'] = '1=1';
115  }
116  foreach ($query['bitand'] as $bit) {
117  $query['where'] .= ' AND '.$bit[0].'&'.$bit[1].'='.$bit[2];
118  }
119  }
120  return 'SELECT '.($query['no_cache']?'SQL_NO_CACHE ':'')
121  .($query['distinct']?'DISTINCT ':'')
122  .($query['fields']?:'*').(isset($query['fields2'])&&!empty($query['fields2'])?','.(is_array($query['fields2'])?implode(',',$query['fields2']):$query['fields2']):'')
123  .' FROM ('.($query['table']?:$query['from'])
124  .($query['table2']?($query['table']?',':'').$query['table2']:'').')'
125  .($query['inner']?' INNER JOIN '.(is_array($query['inner'])?
126  implode(' INNER JOIN ', $query['inner']):$query['inner']):'')
127  .($query['join']?' LEFT JOIN '.(is_array($query['join'])?
128  implode(' LEFT JOIN ', $query['join']):$query['join']):'')
129  .($query['where']?' WHERE '.$query['where']:'')
130  .($query['group']?' GROUP BY '.$query['group']:'')
131  .($query['having']?' HAVING '.$query['having']:'')
132  .($query['order']?' ORDER BY '.$query['order']:'');
133  }
134 
143  protected function _select($query)
144  {
145  if ($query['field_as'])
146  {
147  foreach ($query['field_as'] as $k=>$v)
148  {
149  if ($query['field_as_bitand'][$k]) {
150  foreach ($query['field_as_bitand'][$k] as $bit) {
151  $v .= ' AND '.$bit[0].'&'.$bit[1].'='.$bit[2];
152  }
153  }
154  $query['fields2'][] = '('.$v.') AS '.$k;
155  }
156  unset($query['field_as']);
157  }
158  // proposed Order #78743
159  if ($query['proposed_order'])
160  {
161  $query['order'] = 'FIELD('.$query['proposed_order']['field'].','.implode(',', $query['proposed_order']['values']).')';
162  }
163  if ($query['union'])
164  {
165  $unions = array();
166  foreach ($query['union'] as $union)
167  {
168  $union = array_merge($query, $union);
169  $union['where'] = $query['where']?'('.$query['where'].') AND ('.$union['where'].')':$union['where'];
170  $union['join'] = $query['join']?array_merge_recursive($query['join'], $union['join']):$union['join'];
171  $unions[] = '('.$this->_selectString($union).')';
172  }
173  $s = implode(' UNION ', $unions).($query['order']?' order by'.preg_replace('/([, ])[^, .]+?\./', '$1', ' '.$query['order']):'');
174  } else {
175  $s = $this->_selectString($query);
176  }
177  if ($query['limit'])
178  {
179  $limit = explode(',', $query['limit']);
180  $s.= ' LIMIT '.$limit[0].(sizeof($limit)>1?','.$limit[1]:'');
181  }
182  if ($query['bind'])
183  { // Prepared Statements emulieren.
184  $GLOBALS['prepare_execute_stm'] = array();
185  $q = 'PREPARE STMT FROM "'.preg_replace_callback('#:([a-zA-Z][a-zA-Z0-9_]*)#ims', 'ego_sql_mysqli_prepare_callback', $s).'"';
186  if (!empty($GLOBALS['prepare_execute_stm'])){
187  if (!mysqli_real_query($this->_dbHandle, $q))
188  {
189  throw new Ego_Sql_Exception($s."\n".mysqli_error($this->_dbHandle), Ego_Sql_Exception::QUERY_ERROR );
190  }
191  foreach ($query['bind'] as $k=>$v)
192  {
193  $q = 'SET @'.$k.'=\''.mysqli_real_escape_string($this->_dbHandle, $v).'\'';
194  mysqli_real_query($this->_dbHandle, $q);
195  }
196  $s = 'EXECUTE STMT USING '.implode(',', $GLOBALS['prepare_execute_stm']);
197  }
198  }
199  return $this->query($s);
200  }
201 
202  function delete($query)
203  {
204  assert($query['table']||$query['from']);
205  $s = 'DELETE '
206  .($query['fields']?$query['fields'].' ':'')
207  .'FROM '
208  .($query['table']?$query['table']:$query['from'])
209  .($query['inner']?' INNER JOIN '.(is_array($query['inner'])?
210  implode(' INNER JOIN ', $query['inner']):$query['inner']):'')
211  .($query['join']?' LEFT JOIN '.(is_array($query['join'])?
212  implode(' LEFT JOIN ', $query['join']):$query['join']):'')
213  .($query['where']?' WHERE '.$query['where']:'');
214  if ($query['bind'])
215  { // Prepared Statements emulieren.
216  $GLOBALS['prepare_execute_stm'] = array();
217  $q = 'PREPARE STMT FROM "'.preg_replace_callback('#:([a-zA-Z][a-zA-Z0-9_]*)#ims', 'ego_sql_mysqli_prepare_callback', $s).'"';
218  if (!mysqli_real_query($this->_dbHandle, $q))
219  {
220  throw new Ego_Sql_Exception($s."\n".mysqli_error($this->_dbHandle), Ego_Sql_Exception::QUERY_ERROR );
221  }
222  foreach ($query['bind'] as $k=>$v)
223  {
224  $q = 'SET @'.$k.'=\''.mysqli_real_escape_string($this->_dbHandle, $v).'\'';
225  mysqli_real_query($this->_dbHandle, $q);
226  }
227  $s = 'EXECUTE STMT USING '.implode(',', $GLOBALS['prepare_execute_stm']);
228  }
229  return $this->query($s);
230  }
231 
232  private function _getUpdateField($query)
233  {
234  if (isset($query['key']))
235  {
236  $query['set'] = array_combine($query['key'], $query['val']);
237  }
238  $field = array();
239  if (isset($query['set']))
240  {
241  foreach ($query['set'] as $k => $v)
242  {
243  if ($v === null) {
244  $field[] = '`'.$k.'`=NULL';
245  } else {
246  $field[] = '`'.$k.'`=\''.str_replace(array('\\', '\''), array('\\\\', '\'\''), $v).'\'';
247  }
248  }
249  }
250  return $field;
251  }
252 
259  function update($query)
260  {
261  $field = $this->_getUpdateField($query);
262  if (isset($query['set_f']))
263  {
264  foreach ($query['set_f'] as $k => $v)
265  {
266  $field[] = '`'.$k.'`='.$v;
267  }
268  }
269  $s = 'UPDATE '.($query['ignore']?'IGNORE ':'').// Durch ein Update auftretende doppelte Einträge ignorieren.
270  $query['table'].
271  ' SET '.implode(',', $field).
272  ($query['where']?' WHERE '.$query['where']:'');
273  if ($query['bind'])
274  { // Prepared Statements emulieren.
275  $GLOBALS['prepare_execute_stm'] = array();
276  $q = 'PREPARE STMT FROM "'.preg_replace_callback('#:([a-zA-Z][a-zA-Z0-9_]*)#ims', 'ego_sql_mysqli_prepare_callback', $s).'"';
277  if (!mysqli_real_query($this->_dbHandle, $q))
278  {
279  throw new Ego_Sql_Exception($s."\n".mysqli_error($this->_dbHandle), Ego_Sql_Exception::QUERY_ERROR );
280  }
281  foreach ($query['bind'] as $k=>$v)
282  {
283  $q = 'SET @'.$k.'=\''.mysqli_real_escape_string($this->_dbHandle, $v).'\'';
284  mysqli_real_query($this->_dbHandle, $q);
285  }
286  $s = 'EXECUTE STMT USING '.implode(',', $GLOBALS['prepare_execute_stm']);
287  }
288  return $this->query($s);
289  }
290 
297  function insert($query)
298  {
299  return $this->query(($query['replace']?'REPLACE':'INSERT').' INTO '.$query['table'].' SET '.implode(',', $this->_getUpdateField($query)));
300  }
301 
305  private function _changeType($type)
306  {
307  $type = str_replace('/*bin*/', '', $type, $count);
308 
309  switch ($type)
310  {
311  case 'smalltext':
312  $type = 'TEXT';
313  break;
314  case 'text':
315  $type = 'LONGTEXT';
316  break;
317  case 'tinyint':
318  case 'int':
319  case 'bigint':
320  $type .= ' DEFAULT 0';
321  }
322  if ($count > 0) {
323  $type .= ' character set utf8 collate utf8_bin';
324  }
325  return $type;
326  }
327 
336  function createTable($table, $struct, $drop_flag=true, $notexists_flag=false)
337  {
338  if ($drop_flag)
339  {
340  $this->query('DROP TABLE IF EXISTS '.$table); // Eine evtl. vorhandene Tabelle entfernen.
341  }
342  $query = array();
343  foreach ($struct as $name => $type)
344  {
345  $key = explode(' ', $name);
346  $type = $this->_changeType($type);
347  if (sizeof($key)==1)
348  { // Ein Feld erzeugen.
349  $query[] = $name.' '.$type.' NOT NULL';
350  } else {
351  switch ($key[0])
352  {
353  case 'PRIMARY':
354  $query[] = 'PRIMARY KEY ('.$type.')';
355  break;
356  case 'KEY':
357  $query[] = 'KEY '.$key[1].' ('.$type.')';
358  break;
359  case 'UNIQUE':
360  $query[] = 'UNIQUE KEY '.$key[1].' ('.$type.')';
361  }
362  }
363  }
364  $this->query('CREATE TABLE '.($notexists_flag?'IF NOT EXISTS ':'').$table.' ('.implode(',', $query).
365  ') ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AVG_ROW_LENGTH=1048576 CHECKSUM=0 DELAY_KEY_WRITE=1 MIN_ROWS=1000;');
366  }
367 
368  function alterTable($table, $struct)
369  {
370  $query = array();
371  foreach ($struct as $name => $type)
372  {
373  $key = explode(' ', $name);
374  $type = $this->_changeType($type);
375  if (sizeof($key)==1)
376  { // Ein Feld erzeugen.
377  $query[] = 'ADD '.$name.' '.$type.' NOT NULL';
378  } else {
379  switch ($key[0])
380  {
381  case 'PRIMARY':
382  $query[] = 'ADD PRIMARY KEY ('.$type.')';
383  break;
384  case 'KEY':
385  $query[] = 'ADD KEY '.$key[1].' ('.$type.')';
386  break;
387  case 'UNIQUE':
388  $query[] = 'ADD UNIQUE KEY '.$key[1].' ('.$type.')';
389  break;
390  case 'FULLTEXT':
391  $query[] = 'ADD FULLTEXT '.$key[1].' ('.$type.')';
392  break;
393  case 'CHANGE':
394  $query[] = 'CHANGE '.$key[1].' '.$key[2].' '.$type;
395  }
396  }
397  }
398  return $this->query('ALTER TABLE '.$table.' '.implode(',', $query));
399  }
400 
406  function repair($table)
407  {
408  require_once('base/Ego_System.php');
410  $this->query('repair table '.$table);
412  }
413 
421  function getQueryInfo()
422  {
423  $result_handle = mysqli_query($this->_dbHandle, 'SHOW PROFILE CPU');
424  $result = '';
425  while ($r = mysqli_fetch_assoc($result_handle))
426  {
427  $result.= str_pad($r['Status'], 40)."\t".str_pad($r['Duration'], 8, '0')."\t".$r['CPU_user']."\t".$r['CPU_system']."\n";
428  }
429  return $result;
430  }
431 
444  public function showColumns($table)
445  {
446  if (!$table) return array();
447  $hdl = mysqli_query($this->_dbHandle, "SHOW COLUMNS FROM ".$table);
448  $cols = array();
449  while($record = mysqli_fetch_assoc($hdl))
450  {
451  $cols[] = array(
452  'field' => $record['Field'],
453  'type' => $record['Type']
454  );
455  }
456  return $cols;
457  }
458 
463  public function getVersion()
464  {
465  return mysqli_get_server_info($this->_dbHandle);
466  }
467 
483  public function tableExists($table)
484  {
485  if (!$table)
486  {
487  return false;
488  }
489  $this->query("SHOW TABLES FROM `".$GLOBALS['egotec_conf']['db']['database']."` LIKE '$table'");
490 
491  return (bool)$this->nextRecord();
492  }
493 
500  function getPrimary($table)
501  {
502  $db = clone $this;
503  $db->select(array(
504  'fields' => 'cols.column_name,cols2.data_type',
505  'table' => 'information_schema.table_constraints cons,information_schema.key_column_usage cols,information_schema.columns cols2',
506  'where' => 'cols.table_name=\''.$table.'\' '.
507  'AND cols.table_schema=\''.$GLOBALS['egotec_conf']['db']['database'].'\''.
508  'AND cons.constraint_type=\'PRIMARY KEY\' '.
509  'AND cols.constraint_name=cons.constraint_name AND cols.table_schema=cons.table_schema AND cols.table_name=cons.table_name '.
510  'AND cols2.table_schema=cons.table_schema AND cols2.table_name=cons.table_name AND cols2.column_name=cols.column_name'
511  ));
512  $primary = array();
513  while ($db->nextRecord())
514  {
515  if (strpos($db->Record['data_type'], 'int')!==false)
516  {
517  $type = 'int';
518  } else {
519  $type = 'string';
520  }
521  $primary[$db->Record['column_name']] = $type;
522  }
523  return $primary;
524  }
525 
530  public function optimize($table)
531  {
532  require_once('base/Ego_System.php');
534  $this->query("OPTIMIZE TABLE $table");
536  }
537 
541  protected function _rewind()
542  {
543  $this->_currentRow = -1;
544  mysqli_data_seek($this->_queryHandle, 0);
545  }
546 }
547 
549 {
550  $GLOBALS['prepare_execute_stm'][] = '@'.$matches[1];
551  return '?';
552 }
553 ?>
ego_sql_mysqli_prepare_callback($matches)
alterTable($table, $struct)
createTable($table, $struct, $drop_flag=true, $notexists_flag=false)
query($query, $appendCurrent=false)
connect($database='', $host='', $user='', $password='')
static $_staticMysqliHandle
static eternalCache($active, $clear=true)