Cheetah
ChWsbDb.php
Go to the documentation of this file.
1 <?php
2 
8 define('CH_WSB_TABLE_PROFILES', '`Profiles`');
9 
10 require_once(CH_DIRECTORY_PATH_CLASSES . 'ChWsbParams.php');
11 
12 class ChWsbDb
13 {
15 
19  protected $link;
20 
24  protected static $instance;
25 
29  protected $oCurrentStmt;
30 
35 
39  public $oParams = null;
40 
46  public $oDbCacheObject = null;
47 
48  /*
49  * set database parameters and connect to it
50  * don't want anyone to initate this class
51  */
52  protected function __construct()
53  {
54  $this->host = DATABASE_HOST;
55  $this->port = DATABASE_PORT;
56  $this->socket = DATABASE_SOCK;
57  $this->dbname = DATABASE_NAME;
58  $this->user = DATABASE_USER;
59  $this->password = DATABASE_PASS;
60  $this->iCurrentFetchStyle = PDO::FETCH_ASSOC;
61 
62  // connect to db automatically
63  if (!$this->link) {
64  $this->connect();
65  }
66 
67  $GLOBALS['gl_db_cache'] = [];
68  $GLOBALS['ch_db_param'] = [];
69 
70  if (empty($GLOBALS['ch_db_param'])) {
71  $GLOBALS['ch_db_param'] = new ChWsbParams($this);
72  }
73 
74  $this->oParams = $GLOBALS['ch_db_param'];
75  }
76 
82  public static function getInstance()
83  {
84  if (!isset(self::$instance)) {
85  self::$instance = new static();
86  }
87 
88  return self::$instance;
89  }
90 
94  protected function connect()
95  {
96  $sSocketOrHost = ($this->socket) ? "unix_socket={$this->socket}" : "host={$this->host};port={$this->port}";
97 
98  try {
99  $this->link = new PDO(
100  "mysql:{$sSocketOrHost};dbname={$this->dbname};charset=utf8",
101  $this->user,
102  $this->password,
103  [
104  PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode=""',
105  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
106  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
107  PDO::ATTR_EMULATE_PREPARES => false,
108  PDO::ATTR_PERSISTENT => defined('DATABASE_PERSISTENT') && DATABASE_PERSISTENT ? true : false,
109  ]
110  );
111  }
112  catch (PDOException $o) {
113  throw new Exception ("DB connect failed: " . $o->getMessage());
114  }
115  }
116 
120  protected function disconnect()
121  {
122  $this->link = null;
123  }
124 
130  public function setTimezone($sTimezone)
131  {
132  $oTimeZone = new DateTimeZone($sTimezone);
133  $oDate = new DateTime('now', $oTimeZone);
134  $this->link->query('SET time_zone = "' . $oDate->format('P') . '"');
135  }
136 
137  public function getLink()
138  {
139  return $this->link;
140  }
141 
150  public function res($sQuery, $aBindings = [], $bReplaying = false)
151  {
152  if (strlen(trim($sQuery)) < 1) {
153  throw new InvalidArgumentException('Please provide a valid sql query');
154  }
155 
156  if ($this->link === null) {
157  $this->connect();
158  }
159 
160  if (isset($GLOBALS['ch_profiler'])) {
161  $GLOBALS['ch_profiler']->beginQuery($sQuery);
162  }
163 
164  try {
165  if ($aBindings) {
166  $oStmt = $this->link->prepare($sQuery);
167  $oStmt->execute($aBindings);
168  } else {
169  $oStmt = $this->link->query($sQuery);
170  }
171  } catch (PDOException $e) {
172  // check if this is not a replay call already, if it is, than we will skip this block
173  // and also check if the error is about mysql server going away/disconnecting
174  if (!$bReplaying && (stripos($e->getMessage(), 'gone away') !== false)) {
175  // reconnect to db
176  $this->disconnect();
177  $this->connect();
178 
179  // lets retry after reconnecting by replaying
180  // the call with the replay arg set to true
181  return $this->res($sQuery, $aBindings, true);
182  }
183 
184  // this was a replay call and it failed again OR
185  // the error was not about mysql disconnecting.
186  // We will throw the exception and let
187  // the system handle it like a boss
188  throw $e;
189  }
190 
191  if (isset($GLOBALS['ch_profiler'])) {
192  $GLOBALS['ch_profiler']->endQuery($oStmt);
193  }
194 
195  return $oStmt;
196  }
197 
206  public function getAll($sQuery, $aBindings = [], $iFetchType = PDO::FETCH_ASSOC)
207  {
208  if ($iFetchType != PDO::FETCH_ASSOC && $iFetchType != PDO::FETCH_NUM && $iFetchType != PDO::FETCH_BOTH) {
209  $iFetchType = PDO::FETCH_ASSOC;
210  }
211 
212  $oStmt = $this->res($sQuery, $aBindings);
213 
214  return $oStmt->fetchAll($iFetchType);
215  }
216 
225  public function getRow($sQuery, $aBindings = [], $iFetchStyle = PDO::FETCH_ASSOC)
226  {
227  if ($iFetchStyle != PDO::FETCH_ASSOC && $iFetchStyle != PDO::FETCH_NUM && $iFetchStyle != PDO::FETCH_BOTH) {
228  $iFetchStyle = PDO::FETCH_ASSOC;
229  }
230 
231  $oStmt = $this->res($sQuery, $aBindings);
232 
233  return $oStmt->fetch($iFetchStyle);
234  }
235 
243  public function getColumn($sQuery, $aBindings = [])
244  {
245  $oStmt = $this->res($sQuery, $aBindings);
246 
247  $aResultRows = [];
248  while ($row = $oStmt->fetchColumn()) {
249  $aResultRows[] = $row;
250  }
251 
252  return $aResultRows;
253  }
254 
263  public function getOne($sQuery, $aBindings = [], $iIndex = 0)
264  {
265  $oStmt = $this->res($sQuery, $aBindings);
266 
267  $result = $oStmt->fetch(PDO::FETCH_BOTH);
268  if ($result) {
269  return $result[$iIndex];
270  }
271 
272  return null;
273  }
274 
284  public function getFirstRow($sQuery, $aBindings = [], $iFetchStyle = PDO::FETCH_ASSOC)
285  {
286  if ($iFetchStyle != PDO::FETCH_ASSOC && $iFetchStyle != PDO::FETCH_NUM) {
287  $this->iCurrentFetchStyle = PDO::FETCH_ASSOC;
288  } else {
289  $this->iCurrentFetchStyle = $iFetchStyle;
290  }
291 
292  $oStmt = $this->res($sQuery, $aBindings);
293 
294  $this->oCurrentStmt = $oStmt;
295 
296  $result = $this->oCurrentStmt->fetch($this->iCurrentFetchStyle);
297  if ($result) {
298  return $result;
299  }
300 
301  return [];
302  }
303 
309  public function getNextRow()
310  {
311  $aResult = [];
312 
313  if (!$this->oCurrentStmt) {
314  return $aResult;
315  }
316 
317  $aResult = $this->oCurrentStmt->fetch($this->iCurrentFetchStyle);
318 
319  if ($aResult === false) {
320  $this->oCurrentStmt = null;
321  $this->iCurrentFetchStyle = PDO::FETCH_ASSOC;
322 
323  return [];
324  }
325 
326  return $aResult;
327  }
328 
338  public function getAllWithKey($sQuery, $sFieldKey, $aBindings = [], $iFetchType = PDO::FETCH_ASSOC)
339  {
340  $oStmt = $this->res($sQuery, $aBindings);
341 
342  $aResult = [];
343  if ($oStmt) {
344  while ($row = $oStmt->fetch($iFetchType)) {
345  $aResult[$row[$sFieldKey]] = $row;
346  }
347 
348  $oStmt = null;
349  }
350 
351  return $aResult;
352  }
353 
363  public function getPairs($sQuery, $sFieldKey, $sFieldValue, $aBindings = [])
364  {
365  $oStmt = $this->res($sQuery, $aBindings);
366 
367  $aResult = [];
368  if ($oStmt) {
369  while ($row = $oStmt->fetch()) {
370  $aResult[$row[$sFieldKey]] = $row[$sFieldValue];
371  }
372 
373  $oStmt = null;
374  }
375 
376  return $aResult;
377  }
378 
386  public function query($sQuery, $aBindings = [])
387  {
388  return $this->res($sQuery, $aBindings)->rowCount();
389  }
390 
398  public function getNumRows($oStmt = null)
399  {
400  return $this->getAffectedRows($oStmt);
401  }
402 
409  public function getAffectedRows($oStmt = null)
410  {
411  if ($oStmt) {
412  return $oStmt->rowCount();
413  }
414 
415  if ($this->oCurrentStmt) {
416  return $this->oCurrentStmt->rowCount();
417  }
418 
419  return 0;
420  }
421 
430  public function fillArray($oStmt, $iFetchType = PDO::FETCH_ASSOC)
431  {
432  if ($iFetchType != PDO::FETCH_ASSOC && $iFetchType != PDO::FETCH_NUM && $iFetchType != PDO::FETCH_BOTH) {
433  $iFetchType = PDO::FETCH_ASSOC;
434  }
435 
436  $aResult = [];
437  while ($row = $oStmt->fetch($iFetchType)) {
438  $aResult[] = $row;
439  }
440 
441  return $aResult;
442  }
443 
449  public function lastId()
450  {
451  return $this->link->lastInsertId();
452  }
453 
454  public function getParam($sName, $bCache = true)
455  {
456  return $this->oParams->get($sName, $bCache);
457  }
458 
459  public function setParam($sName, $sValue)
460  {
461  $this->oParams->set($sName, $sValue);
462 
463  return true;
464  }
465 
471  public function listTables()
472  {
473  $aResult = [];
474 
475  $oStmt = $this->link->query("SHOW TABLES FROM `{$this->dbname}`");
476  while ($row = $oStmt->fetch(PDO::FETCH_NUM)) {
477  $aResult[] = $row[0];
478  }
479 
480  return $aResult;
481  }
482 
483  public function getFields($sTable)
484  {
485  $oFieldsStmt = $this->link->query("SHOW COLUMNS FROM `{$sTable}`");
486 
487  $aResult = ['original' => [], 'uppercase' => []];
488  while ($row = $oFieldsStmt->fetch()) {
489  $sName = $row['Field'];
490  $aResult['original'][] = $sName;
491  $aResult['uppercase'][] = strtoupper($sName);
492  }
493 
494  return $aResult;
495  }
496 
497  public function isFieldExists($sTable, $sFieldName)
498  {
499  $aFields = $this->getFields($sTable);
500 
501  return in_array(strtoupper($sFieldName), $aFields['uppercase']);
502  }
503 
504  public function fetchField($mixedQuery, $iField, $aBindings = [])
505  {
506  if(is_string($mixedQuery))
507  $mixedQuery = $this->res($mixedQuery, $aBindings);
508 
509  return $mixedQuery->getColumnMeta($iField);
510  }
511 
512  public function getDbCacheObject()
513  {
514  if ($this->oDbCacheObject != null) {
515  return $this->oDbCacheObject;
516  } else {
517  $sEngine = getParam('sys_db_cache_engine');
518  $this->oDbCacheObject = ch_instance('ChWsbCache' . $sEngine);
519  if (!$this->oDbCacheObject->isAvailable()) {
520  $this->oDbCacheObject = ch_instance('ChWsbCacheFile');
521  }
522 
523  return $this->oDbCacheObject;
524  }
525  }
526 
527  public function genDbCacheKey($sName)
528  {
529  global $site;
530 
531  return 'db_' . $sName . '_' . md5($site['ver'] . $site['build'] . $site['url']) . '.php';
532  }
533 
534  public function fromCache($sName, $sFunc)
535  {
536  $aArgs = func_get_args();
537  array_shift($aArgs); // shift $sName
538  array_shift($aArgs); // shift $sFunc
539 
540  if (!getParam('sys_db_cache_enable')) {
541  return call_user_func_array(array($this, $sFunc), $aArgs);
542  } // pass other function parameters as database function parameters
543 
544  $oCache = $this->getDbCacheObject();
545 
546  $sKey = $this->genDbCacheKey($sName);
547 
548  $mixedRet = $oCache->getData($sKey);
549 
550  if ($mixedRet !== null) {
551 
552  return $mixedRet;
553 
554  } else {
555 
556  $mixedRet = call_user_func_array(array($this, $sFunc),
557  $aArgs); // pass other function parameters as database function parameters
558 
559  $oCache->setData($sKey, $mixedRet);
560  }
561 
562  return $mixedRet;
563  }
564 
565  public function cleanCache($sName)
566  {
567  $oCache = $this->getDbCacheObject();
568 
569  $sKey = $this->genDbCacheKey($sName);
570 
571  return $oCache->delData($sKey);
572  }
573 
574  public function & fromMemory($sName, $sFunc)
575  {
576  if (array_key_exists($sName, $GLOBALS['gl_db_cache'])) {
577  return $GLOBALS['gl_db_cache'][$sName];
578  }
579 
580  $aArgs = func_get_args();
581  array_shift($aArgs); // shift $sName
582  array_shift($aArgs); // shift $sFunc
583 
584  // pass other function parameters as database function parameters
585  $GLOBALS['gl_db_cache'][$sName] = call_user_func_array(array($this, $sFunc), $aArgs);
586 
587  return $GLOBALS['gl_db_cache'][$sName];
588 
589  }
590 
591  public function cleanMemory($sName)
592  {
593  if (isset($GLOBALS['gl_db_cache'][$sName])) {
594  unset($GLOBALS['gl_db_cache'][$sName]);
595 
596  return true;
597  }
598 
599  return false;
600  }
601 
609  public function arrayToSQL($a, $sDiv = ',')
610  {
611  $s = '';
612  foreach($a as $k => $v)
613  $s .= "`{$k}` = " . $this->escape($v) . $sDiv;
614 
615  return trim($s, $sDiv);
616  }
617 
624  public function escape($sText, $bReal = true)
625  {
626  $pdoEscapted = $this->link->quote($sText);
627 
628  if ($bReal) {
629  return $pdoEscapted;
630  }
631 
632  // don't need the actual quotes pdo adds, so it
633  // behaves kinda like mysql_real_escape_string
634  // p.s. things we do for legacy code
635  return 0 === mb_strpos($pdoEscapted, "'") ? mb_substr($pdoEscapted, 1, -1) : $pdoEscapted;
636  }
637 
650  public function implode_escape ($mixed)
651  {
652  if (is_array($mixed)) {
653  $s = '';
654  foreach ($mixed as $v)
655  $s .= (is_numeric($v) ? $v : $this->escape($v)) . ',';
656  if ($s)
657  return substr($s, 0, -1);
658  else
659  return 'NULL';
660  }
661 
662  return is_numeric($mixed) ? $mixed : ($mixed ? $this->escape($mixed) : 'NULL');
663  }
664 
670  public function unescape($mixed)
671  {
672  if (is_array($mixed)) {
673  foreach ($mixed as $k => $v) {
674  $mixed[$k] = $this->getOne("SELECT '$v'");
675  }
676 
677  return $mixed;
678  } else {
679  return $this->getOne("SELECT '$mixed'");
680  }
681  }
682 }
ChWsbDb\getParam
getParam($sName, $bCache=true)
Definition: ChWsbDb.php:454
ChWsbDb\$iCurrentFetchStyle
$iCurrentFetchStyle
Definition: ChWsbDb.php:34
ChWsbDb\$oParams
$oParams
Definition: ChWsbDb.php:39
ChWsbDb\fetchField
fetchField($mixedQuery, $iField, $aBindings=[])
Definition: ChWsbDb.php:504
ChWsbDb\arrayToSQL
arrayToSQL($a, $sDiv=',')
Definition: ChWsbDb.php:609
ChWsbDb\disconnect
disconnect()
Definition: ChWsbDb.php:120
$aResult
$aResult
Definition: index.php:19
ChWsbDb\setTimezone
setTimezone($sTimezone)
Definition: ChWsbDb.php:130
ChWsbParams
Definition: ChWsbParams.php:11
php
ChWsbDb\$socket
$socket
Definition: ChWsbDb.php:14
ChWsbDb\fillArray
fillArray($oStmt, $iFetchType=PDO::FETCH_ASSOC)
Definition: ChWsbDb.php:430
ChWsbDb\getAll
getAll($sQuery, $aBindings=[], $iFetchType=PDO::FETCH_ASSOC)
Definition: ChWsbDb.php:206
ChWsbDb\getPairs
getPairs($sQuery, $sFieldKey, $sFieldValue, $aBindings=[])
Definition: ChWsbDb.php:363
ChWsbDb\$link
$link
Definition: ChWsbDb.php:19
ChWsbDb\fromCache
fromCache($sName, $sFunc)
Definition: ChWsbDb.php:534
ChWsbDb\$dbname
$dbname
Definition: ChWsbDb.php:14
$oCache
$oCache
Definition: prof.inc.php:10
ChWsbDb\$oDbCacheObject
$oDbCacheObject
Definition: ChWsbDb.php:46
ChWsbDb\getNumRows
getNumRows($oStmt=null)
Definition: ChWsbDb.php:398
ChWsbDb\getRow
getRow($sQuery, $aBindings=[], $iFetchStyle=PDO::FETCH_ASSOC)
Definition: ChWsbDb.php:225
$iIndex
$iIndex
Definition: bottom_menu_compose.php:142
ChWsbDb\getFirstRow
getFirstRow($sQuery, $aBindings=[], $iFetchStyle=PDO::FETCH_ASSOC)
Definition: ChWsbDb.php:284
$aFields
$aFields
Definition: preValues.php:19
ChWsbDb\cleanMemory
cleanMemory($sName)
Definition: ChWsbDb.php:591
ChWsbDb\unescape
unescape($mixed)
Definition: ChWsbDb.php:670
ChWsbDb\query
query($sQuery, $aBindings=[])
Definition: ChWsbDb.php:386
ChWsbDb\$port
$port
Definition: ChWsbDb.php:14
ChWsbDb\$password
$password
Definition: ChWsbDb.php:14
$site
$site['ver']
Definition: version.inc.php:8
ChWsbDb\isFieldExists
isFieldExists($sTable, $sFieldName)
Definition: ChWsbDb.php:497
ChWsbDb\$instance
static $instance
Definition: ChWsbDb.php:24
ch_instance
ch_instance($sClassName, $aParams=array(), $aModule=array())
Definition: utils.inc.php:1264
ChWsbDb\res
res($sQuery, $aBindings=[], $bReplaying=false)
Definition: ChWsbDb.php:150
ChWsbDb\getFields
getFields($sTable)
Definition: ChWsbDb.php:483
global
if(!defined("GLOBAL_MODULE")) define("GLOBAL_MODULE" global
Definition: header.inc.php:25
ChWsbDb\$user
$user
Definition: ChWsbDb.php:14
ChWsbDb\getOne
getOne($sQuery, $aBindings=[], $iIndex=0)
Definition: ChWsbDb.php:263
ChWsbDb\getAffectedRows
getAffectedRows($oStmt=null)
Definition: ChWsbDb.php:409
ChWsbDb\connect
connect()
Definition: ChWsbDb.php:94
ChWsbDb\getLink
getLink()
Definition: ChWsbDb.php:137
ChWsbDb\getNextRow
getNextRow()
Definition: ChWsbDb.php:309
ChWsbDb\implode_escape
implode_escape($mixed)
Definition: ChWsbDb.php:650
$s
$s
Definition: embed.php:13
ChWsbDb\genDbCacheKey
genDbCacheKey($sName)
Definition: ChWsbDb.php:527
ChWsbDb\setParam
setParam($sName, $sValue)
Definition: ChWsbDb.php:459
ChWsbDb\fromMemory
& fromMemory($sName, $sFunc)
Definition: ChWsbDb.php:574
ChWsbDb\listTables
listTables()
Definition: ChWsbDb.php:471
ChWsbDb\$oCurrentStmt
$oCurrentStmt
Definition: ChWsbDb.php:29
ChWsbDb\cleanCache
cleanCache($sName)
Definition: ChWsbDb.php:565
ChWsbDb\lastId
lastId()
Definition: ChWsbDb.php:449
empty
Attr AllowedRel this is empty
Definition: Attr.AllowedRel.txt:7
$o
$o
Definition: cmd.php:193
ChWsbDb
Definition: ChWsbDb.php:13
ChWsbDb\getDbCacheObject
getDbCacheObject()
Definition: ChWsbDb.php:512
as
as
Definition: Filter.ExtractStyleBlocks.Escaping.txt:10
ChWsbDb\getAllWithKey
getAllWithKey($sQuery, $sFieldKey, $aBindings=[], $iFetchType=PDO::FETCH_ASSOC)
Definition: ChWsbDb.php:338
ChWsbDb\getInstance
static getInstance()
Definition: ChWsbDb.php:82
$sName
$sName
Definition: ChWsbAdminTools.php:853
ChWsbDb\$host
$host
Definition: ChWsbDb.php:14
ChWsbDb\escape
escape($sText, $bReal=true)
Definition: ChWsbDb.php:624
$GLOBALS
$GLOBALS['iAdminPage']
Definition: advanced_settings.php:10
ChWsbDb\__construct
__construct()
Definition: ChWsbDb.php:52
ChWsbDb\getColumn
getColumn($sQuery, $aBindings=[])
Definition: ChWsbDb.php:243