EGOCMS  18.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']?$query['fields']:'*').($query['fields2']?','.$query['fields2']:'')
123  .' FROM ('.($query['table']?$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'] = ($query['fields2']?$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  switch ($type)
308  {
309  case 'smalltext':
310  $type = 'TEXT';
311  break;
312  case 'text':
313  $type = 'LONGTEXT';
314  break;
315  case 'tinyint':
316  case 'int':
317  case 'bigint':
318  $type.= ' DEFAULT 0';
319  break;
320  }
321  $type.= ' NOT NULL';
322  return $type;
323  }
324 
333  function createTable($table, $struct, $drop_flag=true, $notexists_flag=false)
334  {
335  if ($drop_flag)
336  {
337  $this->query('DROP TABLE IF EXISTS '.$table); // Eine evtl. vorhandene Tabelle entfernen.
338  }
339  $query = array();
340  foreach ($struct as $name => $type)
341  {
342  $key = explode(' ', $name);
343  if (sizeof($key)==1)
344  { // Ein Feld erzeugen.
345  $query[] = $name.' '.$this->_changeType($type);
346  } else {
347  switch ($key[0])
348  {
349  case 'PRIMARY':
350  $query[] = 'PRIMARY KEY ('.$type.')';
351  break;
352  case 'KEY':
353  $query[] = 'KEY '.$key[1].' ('.$type.')';
354  break;
355  case 'UNIQUE':
356  $query[] = 'UNIQUE KEY '.$key[1].' ('.$type.')';
357  break;
358  }
359  }
360  }
361  $query_string = 'CREATE TABLE '.($notexists_flag?'IF NOT EXISTS ':'').$table.' ('.implode(',', $query).
362  ') ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AVG_ROW_LENGTH=1048576 CHECKSUM=0 DELAY_KEY_WRITE=1 MIN_ROWS=1000;';
363  $query_string = str_replace('/*bin*/', ' character set utf8 collate utf8_bin ', $query_string);
364  $this->query($query_string);
365  }
366 
367  function alterTable($table, $struct)
368  {
369  $query = array();
370  foreach ($struct as $name => $type)
371  {
372  $key = explode(' ', $name);
373  if (sizeof($key)==1)
374  { // Ein Feld erzeugen.
375  $query[] = 'ADD '.$name.' '.$this->_changeType($type);
376  } else {
377  switch ($key[0])
378  {
379  case 'PRIMARY':
380  $query[] = 'ADD PRIMARY KEY ('.$type.')';
381  break;
382  case 'KEY':
383  $query[] = 'ADD KEY '.$key[1].' ('.$type.')';
384  break;
385  case 'UNIQUE':
386  $query[] = 'ADD UNIQUE KEY '.$key[1].' ('.$type.')';
387  break;
388  case 'FULLTEXT':
389  $query[] = 'ADD FULLTEXT '.$key[1].' ('.$type.')';
390  break;
391  case 'CHANGE':
392  $query[] = 'CHANGE '.$key[1].' '.$key[2].' '.$type;
393  break;
394  }
395  }
396  }
397  return $this->query('ALTER TABLE '.$table.' '.implode(',', $query));
398  }
399 
405  function repair($table)
406  {
407  require_once('base/Ego_System.php');
409  $this->query('repair table '.$table);
411  }
412 
420  function getQueryInfo()
421  {
422  $result_handle = mysqli_query($this->_dbHandle, 'SHOW PROFILE CPU');
423  $result = '';
424  while ($r = mysqli_fetch_assoc($result_handle))
425  {
426  $result.= str_pad($r['Status'], 40)."\t".str_pad($r['Duration'], 8, '0')."\t".$r['CPU_user']."\t".$r['CPU_system']."\n";
427  }
428  return $result;
429  }
430 
443  public function showColumns($table)
444  {
445  if (!$table) return array();
446  $hdl = mysqli_query($this->_dbHandle, "SHOW COLUMNS FROM ".$table);
447  $cols = array();
448  while($record = mysqli_fetch_assoc($hdl))
449  {
450  $cols[] = array(
451  'field' => $record['Field'],
452  'type' => $record['Type']
453  );
454  }
455  return $cols;
456  }
457 
462  public function getVersion()
463  {
464  return mysqli_get_server_info($this->_dbHandle);
465  }
466 
482  public function tableExists($table)
483  {
484  if (!$table)
485  {
486  return false;
487  }
488  $this->query("SHOW TABLES FROM `".$GLOBALS['egotec_conf']['db']['database']."` LIKE '$table'");
489 
490  return (bool)$this->nextRecord();
491  }
492 
499  function getPrimary($table)
500  {
501  $db = clone $this;
502  $db->select(array(
503  'fields' => 'cols.column_name,cols2.data_type',
504  'table' => 'information_schema.table_constraints cons,information_schema.key_column_usage cols,information_schema.columns cols2',
505  'where' => 'cols.table_name=\''.$table.'\' '.
506  'AND cols.table_schema=\''.$GLOBALS['egotec_conf']['db']['database'].'\''.
507  'AND cons.constraint_type=\'PRIMARY KEY\' '.
508  'AND cols.constraint_name=cons.constraint_name AND cols.table_schema=cons.table_schema AND cols.table_name=cons.table_name '.
509  'AND cols2.table_schema=cons.table_schema AND cols2.table_name=cons.table_name AND cols2.column_name=cols.column_name'
510  ));
511  $primary = array();
512  while ($db->nextRecord())
513  {
514  if (strpos($db->Record['data_type'], 'int')!==false)
515  {
516  $type = 'int';
517  } else {
518  $type = 'string';
519  }
520  $primary[$db->Record['column_name']] = $type;
521  }
522  return $primary;
523  }
524 
529  public function optimize($table)
530  {
531  require_once('base/Ego_System.php');
533  $this->query("OPTIMIZE TABLE $table");
535  }
536 
540  protected function _rewind()
541  {
542  $this->_currentRow = -1;
543  mysqli_data_seek($this->_queryHandle, 0);
544  }
545 }
546 
548 {
549  $GLOBALS['prepare_execute_stm'][] = '@'.$matches[1];
550  return '?';
551 }
552 ?>
connect($database='', $host='', $user='', $password='')
static eternalCache($active)
alterTable($table, $struct)
static $_staticMysqliHandle
ego_sql_mysqli_prepare_callback($matches)
createTable($table, $struct, $drop_flag=true, $notexists_flag=false)
query($query, $appendCurrent=false)