Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Abstract.php
Go to the documentation of this file.
1 <?php
27 #require_once 'Zend/Db.php';
28 
32 #require_once 'Zend/Db/Select.php';
33 
44 {
45 
51  protected $_config = array();
52 
59 
66  protected $_profiler;
67 
73  protected $_defaultStmtClass = 'Zend_Db_Statement';
74 
80  protected $_defaultProfilerClass = 'Zend_Db_Profiler';
81 
87  protected $_connection = null;
88 
99 
109  protected $_autoQuoteIdentifiers = true;
110 
122  protected $_numericDataTypes = array(
126  );
127 
132  protected $_allowSerialization = true;
133 
140  protected $_autoReconnectOnUnserialize = false;
141 
164  public function __construct($config)
165  {
166  /*
167  * Verify that adapter parameters are in an array.
168  */
169  if (!is_array($config)) {
170  /*
171  * Convert Zend_Config argument to a plain array.
172  */
173  if ($config instanceof Zend_Config) {
174  $config = $config->toArray();
175  } else {
179  #require_once 'Zend/Db/Adapter/Exception.php';
180  throw new Zend_Db_Adapter_Exception('Adapter parameters must be in an array or a Zend_Config object');
181  }
182  }
183 
185 
186  $options = array(
187  Zend_Db::CASE_FOLDING => $this->_caseFolding,
188  Zend_Db::AUTO_QUOTE_IDENTIFIERS => $this->_autoQuoteIdentifiers,
189  Zend_Db::FETCH_MODE => $this->_fetchMode,
190  );
191  $driverOptions = array();
192 
193  /*
194  * normalize the config and merge it with the defaults
195  */
196  if (array_key_exists('options', $config)) {
197  // can't use array_merge() because keys might be integers
198  foreach ((array) $config['options'] as $key => $value) {
199  $options[$key] = $value;
200  }
201  }
202  if (array_key_exists('driver_options', $config)) {
203  if (!empty($config['driver_options'])) {
204  // can't use array_merge() because keys might be integers
205  foreach ((array) $config['driver_options'] as $key => $value) {
206  $driverOptions[$key] = $value;
207  }
208  }
209  }
210 
211  if (!isset($config['charset'])) {
212  $config['charset'] = null;
213  }
214 
215  if (!isset($config['persistent'])) {
216  $config['persistent'] = false;
217  }
218 
219  $this->_config = array_merge($this->_config, $config);
220  $this->_config['options'] = $options;
221  $this->_config['driver_options'] = $driverOptions;
222 
223 
224  // obtain the case setting, if there is one
225  if (array_key_exists(Zend_Db::CASE_FOLDING, $options)) {
227  switch ($case) {
228  case Zend_Db::CASE_LOWER:
229  case Zend_Db::CASE_UPPER:
231  $this->_caseFolding = $case;
232  break;
233  default:
235  #require_once 'Zend/Db/Adapter/Exception.php';
236  throw new Zend_Db_Adapter_Exception('Case must be one of the following constants: '
237  . 'Zend_Db::CASE_NATURAL, Zend_Db::CASE_LOWER, Zend_Db::CASE_UPPER');
238  }
239  }
240 
241  if (array_key_exists(Zend_Db::FETCH_MODE, $options)) {
242  if (is_string($options[Zend_Db::FETCH_MODE])) {
243  $constant = 'Zend_Db::FETCH_' . strtoupper($options[Zend_Db::FETCH_MODE]);
244  if(defined($constant)) {
245  $options[Zend_Db::FETCH_MODE] = constant($constant);
246  }
247  }
248  $this->setFetchMode((int) $options[Zend_Db::FETCH_MODE]);
249  }
250 
251  // obtain quoting property if there is one
252  if (array_key_exists(Zend_Db::AUTO_QUOTE_IDENTIFIERS, $options)) {
253  $this->_autoQuoteIdentifiers = (bool) $options[Zend_Db::AUTO_QUOTE_IDENTIFIERS];
254  }
255 
256  // obtain allow serialization property if there is one
257  if (array_key_exists(Zend_Db::ALLOW_SERIALIZATION, $options)) {
258  $this->_allowSerialization = (bool) $options[Zend_Db::ALLOW_SERIALIZATION];
259  }
260 
261  // obtain auto reconnect on unserialize property if there is one
262  if (array_key_exists(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE, $options)) {
263  $this->_autoReconnectOnUnserialize = (bool) $options[Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE];
264  }
265 
266  // create a profiler object
267  $profiler = false;
268  if (array_key_exists(Zend_Db::PROFILER, $this->_config)) {
269  $profiler = $this->_config[Zend_Db::PROFILER];
270  unset($this->_config[Zend_Db::PROFILER]);
271  }
272  $this->setProfiler($profiler);
273  }
274 
282  protected function _checkRequiredOptions(array $config)
283  {
284  // we need at least a dbname
285  if (! array_key_exists('dbname', $config)) {
287  #require_once 'Zend/Db/Adapter/Exception.php';
288  throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");
289  }
290 
291  if (! array_key_exists('password', $config)) {
295  #require_once 'Zend/Db/Adapter/Exception.php';
296  throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials");
297  }
298 
299  if (! array_key_exists('username', $config)) {
303  #require_once 'Zend/Db/Adapter/Exception.php';
304  throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials");
305  }
306  }
307 
314  public function getConnection()
315  {
316  $this->_connect();
317  return $this->_connection;
318  }
319 
325  public function getConfig()
326  {
327  return $this->_config;
328  }
329 
358  public function setProfiler($profiler)
359  {
360  $enabled = null;
361  $profilerClass = $this->_defaultProfilerClass;
362  $profilerInstance = null;
363 
364  if ($profilerIsObject = is_object($profiler)) {
365  if ($profiler instanceof Zend_Db_Profiler) {
366  $profilerInstance = $profiler;
367  } else if ($profiler instanceof Zend_Config) {
368  $profiler = $profiler->toArray();
369  } else {
373  #require_once 'Zend/Db/Profiler/Exception.php';
374  throw new Zend_Db_Profiler_Exception('Profiler argument must be an instance of either Zend_Db_Profiler'
375  . ' or Zend_Config when provided as an object');
376  }
377  }
378 
379  if (is_array($profiler)) {
380  if (isset($profiler['enabled'])) {
381  $enabled = (bool) $profiler['enabled'];
382  }
383  if (isset($profiler['class'])) {
384  $profilerClass = $profiler['class'];
385  }
386  if (isset($profiler['instance'])) {
387  $profilerInstance = $profiler['instance'];
388  }
389  } else if (!$profilerIsObject) {
390  $enabled = (bool) $profiler;
391  }
392 
393  if ($profilerInstance === null) {
394  if (!class_exists($profilerClass)) {
395  #require_once 'Zend/Loader.php';
396  Zend_Loader::loadClass($profilerClass);
397  }
398  $profilerInstance = new $profilerClass();
399  }
400 
401  if (!$profilerInstance instanceof Zend_Db_Profiler) {
403  #require_once 'Zend/Db/Profiler/Exception.php';
404  throw new Zend_Db_Profiler_Exception('Class ' . get_class($profilerInstance) . ' does not extend '
405  . 'Zend_Db_Profiler');
406  }
407 
408  if (null !== $enabled) {
409  $profilerInstance->setEnabled($enabled);
410  }
411 
412  $this->_profiler = $profilerInstance;
413 
414  return $this;
415  }
416 
417 
423  public function getProfiler()
424  {
425  return $this->_profiler;
426  }
427 
433  public function getStatementClass()
434  {
436  }
437 
443  public function setStatementClass($class)
444  {
445  $this->_defaultStmtClass = $class;
446  return $this;
447  }
448 
457  public function query($sql, $bind = array())
458  {
459  // connect to the database if needed
460  $this->_connect();
461 
462  // is the $sql a Zend_Db_Select object?
463  if ($sql instanceof Zend_Db_Select) {
464  if (empty($bind)) {
465  $bind = $sql->getBind();
466  }
467 
468  $sql = $sql->assemble();
469  }
470 
471  // make sure $bind to an array;
472  // don't use (array) typecasting because
473  // because $bind may be a Zend_Db_Expr object
474  if (!is_array($bind)) {
475  $bind = array($bind);
476  }
477 
478  // prepare and execute the statement with profiling
479  $stmt = $this->prepare($sql);
480  $stmt->execute($bind);
481 
482  // return the results embedded in the prepared statement object
483  $stmt->setFetchMode($this->_fetchMode);
484  return $stmt;
485  }
486 
492  public function beginTransaction()
493  {
494  $this->_connect();
495  $q = $this->_profiler->queryStart('begin', Zend_Db_Profiler::TRANSACTION);
496  $this->_beginTransaction();
497  $this->_profiler->queryEnd($q);
498  return $this;
499  }
500 
506  public function commit()
507  {
508  $this->_connect();
509  $q = $this->_profiler->queryStart('commit', Zend_Db_Profiler::TRANSACTION);
510  $this->_commit();
511  $this->_profiler->queryEnd($q);
512  return $this;
513  }
514 
520  public function rollBack()
521  {
522  $this->_connect();
523  $q = $this->_profiler->queryStart('rollback', Zend_Db_Profiler::TRANSACTION);
524  $this->_rollBack();
525  $this->_profiler->queryEnd($q);
526  return $this;
527  }
528 
537  public function insert($table, array $bind)
538  {
539  // extract and quote col names from the array keys
540  $cols = array();
541  $vals = array();
542  $i = 0;
543  foreach ($bind as $col => $val) {
544  $cols[] = $this->quoteIdentifier($col, true);
545  if ($val instanceof Zend_Db_Expr) {
546  $vals[] = $val->__toString();
547  unset($bind[$col]);
548  } else {
549  if ($this->supportsParameters('positional')) {
550  $vals[] = '?';
551  } else {
552  if ($this->supportsParameters('named')) {
553  unset($bind[$col]);
554  $bind[':col'.$i] = $val;
555  $vals[] = ':col'.$i;
556  $i++;
557  } else {
559  #require_once 'Zend/Db/Adapter/Exception.php';
560  throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
561  }
562  }
563  }
564  }
565 
566  // build the statement
567  $sql = "INSERT INTO "
568  . $this->quoteIdentifier($table, true)
569  . ' (' . implode(', ', $cols) . ') '
570  . 'VALUES (' . implode(', ', $vals) . ')';
571 
572  // execute the statement and return the number of affected rows
573  if ($this->supportsParameters('positional')) {
574  $bind = array_values($bind);
575  }
576  $stmt = $this->query($sql, $bind);
577  $result = $stmt->rowCount();
578  return $result;
579  }
580 
590  public function update($table, array $bind, $where = '')
591  {
596  $set = array();
597  $i = 0;
598  foreach ($bind as $col => $val) {
599  if ($val instanceof Zend_Db_Expr) {
600  $val = $val->__toString();
601  unset($bind[$col]);
602  } else {
603  if ($this->supportsParameters('positional')) {
604  $val = '?';
605  } else {
606  if ($this->supportsParameters('named')) {
607  unset($bind[$col]);
608  $bind[':col'.$i] = $val;
609  $val = ':col'.$i;
610  $i++;
611  } else {
613  #require_once 'Zend/Db/Adapter/Exception.php';
614  throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
615  }
616  }
617  }
618  $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val;
619  }
620 
621  $where = $this->_whereExpr($where);
622 
626  $sql = "UPDATE "
627  . $this->quoteIdentifier($table, true)
628  . ' SET ' . implode(', ', $set)
629  . (($where) ? " WHERE $where" : '');
630 
634  if ($this->supportsParameters('positional')) {
635  $stmt = $this->query($sql, array_values($bind));
636  } else {
637  $stmt = $this->query($sql, $bind);
638  }
639  $result = $stmt->rowCount();
640  return $result;
641  }
642 
650  public function delete($table, $where = '')
651  {
652  $where = $this->_whereExpr($where);
653 
657  $sql = "DELETE FROM "
658  . $this->quoteIdentifier($table, true)
659  . (($where) ? " WHERE $where" : '');
660 
664  $stmt = $this->query($sql);
665  $result = $stmt->rowCount();
666  return $result;
667  }
668 
676  protected function _whereExpr($where)
677  {
678  if (empty($where)) {
679  return $where;
680  }
681  if (!is_array($where)) {
682  $where = array($where);
683  }
684  foreach ($where as $cond => &$term) {
685  // is $cond an int? (i.e. Not a condition)
686  if (is_int($cond)) {
687  // $term is the full condition
688  if ($term instanceof Zend_Db_Expr) {
689  $term = $term->__toString();
690  }
691  } else {
692  // $cond is the condition with placeholder,
693  // and $term is quoted into the condition
694  $term = $this->quoteInto($cond, $term);
695  }
696  $term = '(' . $term . ')';
697  }
698 
699  $where = implode(' AND ', $where);
700  return $where;
701  }
702 
708  public function select()
709  {
710  return new Zend_Db_Select($this);
711  }
712 
718  public function getFetchMode()
719  {
720  return $this->_fetchMode;
721  }
722 
732  public function fetchAll($sql, $bind = array(), $fetchMode = null)
733  {
734  if ($fetchMode === null) {
735  $fetchMode = $this->_fetchMode;
736  }
737  $stmt = $this->query($sql, $bind);
738  $result = $stmt->fetchAll($fetchMode);
739  return $result;
740  }
741 
751  public function fetchRow($sql, $bind = array(), $fetchMode = null)
752  {
753  if ($fetchMode === null) {
754  $fetchMode = $this->_fetchMode;
755  }
756  $stmt = $this->query($sql, $bind);
757  $result = $stmt->fetch($fetchMode);
758  return $result;
759  }
760 
774  public function fetchAssoc($sql, $bind = array())
775  {
776  $stmt = $this->query($sql, $bind);
777  $data = array();
778  while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
779  $tmp = array_values(array_slice($row, 0, 1));
780  $data[$tmp[0]] = $row;
781  }
782  return $data;
783  }
784 
792  public function fetchCol($sql, $bind = array())
793  {
794  $stmt = $this->query($sql, $bind);
795  $result = $stmt->fetchAll(Zend_Db::FETCH_COLUMN, 0);
796  return $result;
797  }
798 
809  public function fetchPairs($sql, $bind = array())
810  {
811  $stmt = $this->query($sql, $bind);
812  $data = array();
813  while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) {
814  $data[$row[0]] = $row[1];
815  }
816  return $data;
817  }
818 
826  public function fetchOne($sql, $bind = array())
827  {
828  $stmt = $this->query($sql, $bind);
829  $result = $stmt->fetchColumn(0);
830  return $result;
831  }
832 
839  protected function _quote($value)
840  {
841  if (is_int($value)) {
842  return $value;
843  } elseif (is_float($value)) {
844  return sprintf('%F', $value);
845  }
846  return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
847  }
848 
859  public function quote($value, $type = null)
860  {
861  $this->_connect();
862 
863  if ($value instanceof Zend_Db_Select) {
864  return '(' . $value->assemble() . ')';
865  }
866 
867  if ($value instanceof Zend_Db_Expr) {
868  return $value->__toString();
869  }
870 
871  if (is_array($value)) {
872  foreach ($value as &$val) {
873  $val = $this->quote($val, $type);
874  }
875  return implode(', ', $value);
876  }
877 
878  if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) {
879  $quotedValue = '0';
880  switch ($this->_numericDataTypes[$type]) {
881  case Zend_Db::INT_TYPE: // 32-bit integer
882  $quotedValue = (string) intval($value);
883  break;
884  case Zend_Db::BIGINT_TYPE: // 64-bit integer
885  // ANSI SQL-style hex literals (e.g. x'[\dA-F]+')
886  // are not supported here, because these are string
887  // literals, not numeric literals.
888  if (preg_match('/^(
889  [+-]? # optional sign
890  (?:
891  0[Xx][\da-fA-F]+ # ODBC-style hexadecimal
892  |\d+ # decimal or octal, or MySQL ZEROFILL decimal
893  (?:[eE][+-]?\d+)? # optional exponent on decimals or octals
894  )
895  )/x',
896  (string) $value, $matches)) {
897  $quotedValue = $matches[1];
898  }
899  break;
900  case Zend_Db::FLOAT_TYPE: // float or decimal
901  $quotedValue = sprintf('%F', $value);
902  }
903  return $quotedValue;
904  }
905 
906  return $this->_quote($value);
907  }
908 
928  public function quoteInto($text, $value, $type = null, $count = null)
929  {
930  if ($count === null) {
931  return str_replace('?', $this->quote($value, $type), $text);
932  } else {
933  return implode($this->quote($value, $type), explode('?', $text, $count + 1));
934  }
935  }
936 
959  public function quoteIdentifier($ident, $auto=false)
960  {
961  return $this->_quoteIdentifierAs($ident, null, $auto);
962  }
963 
972  public function quoteColumnAs($ident, $alias, $auto=false)
973  {
974  return $this->_quoteIdentifierAs($ident, $alias, $auto);
975  }
976 
985  public function quoteTableAs($ident, $alias = null, $auto = false)
986  {
987  return $this->_quoteIdentifierAs($ident, $alias, $auto);
988  }
989 
999  protected function _quoteIdentifierAs($ident, $alias = null, $auto = false, $as = ' AS ')
1000  {
1001  if ($ident instanceof Zend_Db_Expr) {
1002  $quoted = $ident->__toString();
1003  } elseif ($ident instanceof Zend_Db_Select) {
1004  $quoted = '(' . $ident->assemble() . ')';
1005  } else {
1006  if (is_string($ident)) {
1007  $ident = explode('.', $ident);
1008  }
1009  if (is_array($ident)) {
1010  $segments = array();
1011  foreach ($ident as $segment) {
1012  if ($segment instanceof Zend_Db_Expr) {
1013  $segments[] = $segment->__toString();
1014  } else {
1015  $segments[] = $this->_quoteIdentifier($segment, $auto);
1016  }
1017  }
1018  if ($alias !== null && end($ident) == $alias) {
1019  $alias = null;
1020  }
1021  $quoted = implode('.', $segments);
1022  } else {
1023  $quoted = $this->_quoteIdentifier($ident, $auto);
1024  }
1025  }
1026  if ($alias !== null) {
1027  $quoted .= $as . $this->_quoteIdentifier($alias, $auto);
1028  }
1029  return $quoted;
1030  }
1031 
1039  protected function _quoteIdentifier($value, $auto=false)
1040  {
1041  if ($auto === false || $this->_autoQuoteIdentifiers === true) {
1042  $q = $this->getQuoteIdentifierSymbol();
1043  return ($q . str_replace("$q", "$q$q", $value) . $q);
1044  }
1045  return $value;
1046  }
1047 
1053  public function getQuoteIdentifierSymbol()
1054  {
1055  return '"';
1056  }
1057 
1066  public function lastSequenceId($sequenceName)
1067  {
1068  return null;
1069  }
1070 
1079  public function nextSequenceId($sequenceName)
1080  {
1081  return null;
1082  }
1083 
1096  public function foldCase($key)
1097  {
1098  switch ($this->_caseFolding) {
1099  case Zend_Db::CASE_LOWER:
1100  $value = strtolower((string) $key);
1101  break;
1102  case Zend_Db::CASE_UPPER:
1103  $value = strtoupper((string) $key);
1104  break;
1105  case Zend_Db::CASE_NATURAL:
1106  default:
1107  $value = (string) $key;
1108  }
1109  return $value;
1110  }
1111 
1119  public function __sleep()
1120  {
1121  if ($this->_allowSerialization == false) {
1123  #require_once 'Zend/Db/Adapter/Exception.php';
1124  throw new Zend_Db_Adapter_Exception(
1125  get_class($this) . ' is not allowed to be serialized'
1126  );
1127  }
1128  $this->_connection = null;
1129 
1130  return array_keys(
1131  array_diff_key(get_object_vars($this), array('_connection' => null))
1132  );
1133  }
1134 
1140  public function __wakeup()
1141  {
1142  if ($this->_autoReconnectOnUnserialize == true) {
1143  $this->getConnection();
1144  }
1145  }
1146 
1156  abstract public function listTables();
1157 
1185  abstract public function describeTable($tableName, $schemaName = null);
1186 
1192  abstract protected function _connect();
1193 
1199  abstract public function isConnected();
1200 
1206  abstract public function closeConnection();
1207 
1214  abstract public function prepare($sql);
1215 
1230  abstract public function lastInsertId($tableName = null, $primaryKey = null);
1231 
1235  abstract protected function _beginTransaction();
1236 
1240  abstract protected function _commit();
1241 
1245  abstract protected function _rollBack();
1246 
1254  abstract public function setFetchMode($mode);
1255 
1264  abstract public function limit($sql, $count, $offset = 0);
1265 
1272  abstract public function supportsParameters($type);
1273 
1279  abstract public function getServerVersion();
1280 }
const PROFILER
Definition: Db.php:38
$tableName
Definition: trigger.php:13
fetchOne($sql, $bind=array())
Definition: Abstract.php:826
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
static loadClass($class, $dirs=null)
Definition: Loader.php:52
fetchCol($sql, $bind=array())
Definition: Abstract.php:792
$config
Definition: fraud_order.php:17
const BIGINT_TYPE
Definition: Db.php:69
quote($value, $type=null)
Definition: Abstract.php:859
const INT_TYPE
Definition: Db.php:68
const AUTO_RECONNECT_ON_UNSERIALIZE
Definition: Db.php:63
$count
Definition: recent.phtml:13
$case
fetchRow($sql, $bind=array(), $fetchMode=null)
Definition: Abstract.php:751
const FETCH_ASSOC
Definition: Db.php:142
lastInsertId($tableName=null, $primaryKey=null)
const FETCH_COLUMN
Definition: Db.php:147
endifif( $block->getLastPageNum()>1)( 'Page') ?></strong >< ul class $text
Definition: pager.phtml:43
fetchAssoc($sql, $bind=array())
Definition: Abstract.php:774
nextSequenceId($sequenceName)
Definition: Abstract.php:1079
lastSequenceId($sequenceName)
Definition: Abstract.php:1066
const FLOAT_TYPE
Definition: Db.php:70
$type
Definition: item.phtml:13
quoteTableAs($ident, $alias=null, $auto=false)
Definition: Abstract.php:985
$_option $_optionId $class
Definition: date.phtml:13
$value
Definition: gender.phtml:16
const FETCH_NUM
Definition: Db.php:153
const FETCH_MODE
Definition: Db.php:48
update($table, array $bind, $where='')
Definition: Abstract.php:590
quoteInto($text, $value, $type=null, $count=null)
Definition: Abstract.php:928
_quoteIdentifierAs($ident, $alias=null, $auto=false, $as=' AS ')
Definition: Abstract.php:999
fetchPairs($sql, $bind=array())
Definition: Abstract.php:809
if($exist=($block->getProductCollection() && $block->getProductCollection() ->getSize())) $mode
Definition: grid.phtml:15
const TRANSACTION
Definition: Profiler.php:69
const AUTO_QUOTE_IDENTIFIERS
Definition: Db.php:53
const CASE_UPPER
Definition: Db.php:125
const CASE_NATURAL
Definition: Db.php:124
query($sql, $bind=array())
Definition: Abstract.php:457
const ALLOW_SERIALIZATION
Definition: Db.php:58
if(!trim($html)) $alias
Definition: details.phtml:20
quoteColumnAs($ident, $alias, $auto=false)
Definition: Abstract.php:972
fetchAll($sql, $bind=array(), $fetchMode=null)
Definition: Abstract.php:732
describeTable($tableName, $schemaName=null)
insert($table, array $bind)
Definition: Abstract.php:537
$table
Definition: trigger.php:14
quoteIdentifier($ident, $auto=false)
Definition: Abstract.php:959
const CASE_FOLDING
Definition: Db.php:43
$i
Definition: gallery.phtml:31
_quoteIdentifier($value, $auto=false)
Definition: Abstract.php:1039
const CASE_LOWER
Definition: Db.php:123
_checkRequiredOptions(array $config)
Definition: Abstract.php:282
limit($sql, $count, $offset=0)