CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

Database.php
Go to the documentation of this file.
1 <?PHP
2
3 #
4 # Axis--Database.php
5 # A Simple SQL Database Abstraction Object
6 #
7 # Copyright 1999-2002 Axis Data
8 # This code is free software that can be used or redistributed under the
9 # terms of Version 2 of the GNU General Public License, as published by the
10 # Free Software Foundation (http://www.fsf.org).
11 #
12 # Author: Edward Almasy (almasy@axisdata.com)
13 #
14 # Part of the AxisPHP library v1.2.5
15 # For more information see http://www.axisdata.com/AxisPHP/
16 #
17
22 class Database
23 {
24
25 # ---- PUBLIC INTERFACE --------------------------------------------------
26 /*@(*/
28
43 public function __construct(
44 $UserName = NULL, $Password = NULL, $DatabaseName = NULL, $HostName = NULL)
45 {
46 # save DB access parameter values
47 $this->DBUserName = $UserName ? $UserName : self::$GlobalDBUserName;
48 $this->DBPassword = $Password ? $Password : self::$GlobalDBPassword;
49 $this->DBHostName = $HostName ? $HostName :
50 (isset(self::$GlobalDBHostName) ? self::$GlobalDBHostName
51 : "localhost");
52 $this->DBName = $DatabaseName ? $DatabaseName : self::$GlobalDBName;
53
54 # set memory threshold for cache clearing
55 if (!isset(self::$CacheMemoryThreshold))
56 {
57 self::$CacheMemoryThreshold = self::GetPhpMemoryLimit() / 4;
58 }
59
60 # if we don't already have a connection or DB access parameters were supplied
61 $HandleIndex = $this->DBHostName.":".$this->DBName;
62 if (!array_key_exists($HandleIndex, self::$ConnectionHandles)
63 || $UserName || $Password || $DatabaseName || $HostName)
64 {
65 # open connection to DB server and select database
66 $this->Handle = self::ConnectAndSelectDB($this->DBHostName,
67 $this->DBUserName, $this->DBPassword, $this->DBName);
68 self::$ConnectionHandles[$HandleIndex] = $this->Handle;
69 }
70 else
71 {
72 # set local connection handle
73 $this->Handle = self::$ConnectionHandles[$HandleIndex];
74 }
75 }
76
81 public function __sleep()
82 {
83 return array("DBUserName", "DBPassword", "DBHostName", "DBName");
84 }
90 public function __wakeup()
91 {
92 # if we don't already have a database server connection
93 $HandleIndex = $this->DBHostName.":".$this->DBName;
94 if (!array_key_exists($HandleIndex, self::$ConnectionHandles))
95 {
96 # open connection to DB server and select database
97 try
98 {
99 $this->Handle = self::ConnectAndSelectDB($this->DBHostName,
100 $this->DBUserName, $this->DBPassword, $this->DBName);
101 }
102 catch (Exception $Exception)
103 {
104 if (isset(self::$GlobalDBUserName)
105 && isset(self::$GlobalDBPassword)
106 && isset(self::$GlobalDBName))
107 {
108 $this->DBUserName = self::$GlobalDBUserName;
109 $this->DBPassword = self::$GlobalDBPassword;
110 $this->DBName = self::$GlobalDBName;
111 $this->DBHostName = isset(self::$GlobalDBHostName)
112 ? self::$GlobalDBHostName : "localhost";
113 $this->Handle = self::ConnectAndSelectDB($this->DBHostName,
114 $this->DBUserName, $this->DBPassword, $this->DBName);
115 }
116 else
117 {
118 throw $Exception;
119 }
120 }
121 self::$ConnectionHandles[$HandleIndex] = $this->Handle;
122 }
123 else
124 {
125 # set local connection handle
126 $this->Handle = self::$ConnectionHandles[$HandleIndex];
127 }
128 }
138 public static function SetGlobalServerInfo(
139 $UserName, $Password, $HostName = "localhost")
140 {
141 # save default DB access parameters
142 self::$GlobalDBUserName = $UserName;
143 self::$GlobalDBPassword = $Password;
144 self::$GlobalDBHostName = $HostName;
145
146 # clear any existing DB connection handles
147 self::$ConnectionHandles = array();
148 }
149
154 public static function SetGlobalDatabaseName($DatabaseName)
155 {
156 # save new default DB name
157 self::$GlobalDBName = $DatabaseName;
158
159 # clear any existing DB connection handles
160 self::$ConnectionHandles = array();
161 }
162
167 public function SetDefaultStorageEngine($Engine)
168 {
169 # choose config variable to use based on server version number
170 $ConfigVar = version_compare($this->GetServerVersion(), "5.5", "<")
171 ? "storage_engine" : "default_storage_engine";
172
173 # set storage engine in database
174 $this->Query("SET ".$ConfigVar." = ".$Engine);
175 }
176
183 public function GetServerVersion($FullVersion=FALSE)
184 {
185 # retrieve version string
186 $Version = $this->Query("SELECT VERSION() AS ServerVer", "ServerVer");
187
188 if (!$FullVersion)
189 {
190 # strip off any build/config suffix
191 $Pieces = explode("-", $Version);
192 $Version = array_shift($Pieces);
193 }
194
195 # return version number to caller
196 return $Version;
197 }
198
207 public function GetClientVersion()
208 {
209 return mysqli_get_client_info();
210 }
211
217 public function GetHostInfo()
218 {
219 return mysqli_get_host_info($this->Handle);
220 }
221
227 public function DBHostName()
228 {
229 return $this->DBHostName;
230 }
231
237 public function DBName()
238 {
239 return $this->DBName;
240 }
241
247 public function DBUserName()
248 {
249 return $this->DBUserName;
250 }
251
259 public static function Caching($NewSetting = NULL)
260 {
261 # if cache setting has changed
262 if (($NewSetting !== NULL) && ($NewSetting != self::$CachingFlag))
263 {
264 # save new setting
265 self::$CachingFlag = $NewSetting;
266
267 # clear any existing cached results
268 self::$QueryResultCache = array();
269 }
270
271 # return current setting to caller
272 return self::$CachingFlag;
273 }
274
285 public static function AdvancedCaching($NewSetting = NULL)
286 {
287 if ($NewSetting !== NULL)
288 {
289 self::$AdvancedCachingFlag = $NewSetting;
290 }
291 return self::$AdvancedCachingFlag;
292 }
293
313 public function SetQueryErrorsToIgnore($ErrorsToIgnore, $NormalizeWhitespace = TRUE)
314 {
315 if ($NormalizeWhitespace && ($ErrorsToIgnore !== NULL))
316 {
317 $RevisedErrorsToIgnore = array();
318 foreach ($ErrorsToIgnore as $SqlPattern => $ErrMsgPattern)
319 {
320 $SqlPattern = preg_replace("/\\s+/", "\\s+", $SqlPattern);
321 $RevisedErrorsToIgnore[$SqlPattern] = $ErrMsgPattern;
322 }
323 $ErrorsToIgnore = $RevisedErrorsToIgnore;
324 }
325 $this->ErrorsToIgnore = $ErrorsToIgnore;
326 }
327
333 public function IgnoredError()
334 {
335 return $this->ErrorIgnored;
336 }
337
338 /*@)*/ /* Setup/Initialization */ /*@(*/
340
351 public function Query($QueryString, $FieldName = "")
352 {
353 # clear flag that indicates whether query error was ignored
354 $this->ErrorIgnored = FALSE;
355
356 # if caching is enabled
357 if (self::$CachingFlag)
358 {
359 # if SQL statement is read-only
360 if ($this->IsReadOnlyStatement($QueryString))
361 {
362 # if we have statement in cache
363 if (isset(self::$QueryResultCache[$QueryString]["NumRows"]))
364 {
365 if (self::$QueryDebugOutputFlag)
366 { print("DB-C: $QueryString<br>\n"); }
367
368 # make sure query result looks okay
369 $this->QueryHandle = TRUE;
370
371 # increment cache hit counter
372 self::$CachedQueryCounter++;
373
374 # make local copy of results
375 $this->QueryResults = self::$QueryResultCache[$QueryString];
376 $this->NumRows = self::$QueryResultCache[$QueryString]["NumRows"];
377
378 # set flag to indicate that results should be retrieved from cache
379 $this->GetResultsFromCache = TRUE;
380 }
381 else
382 {
383 # execute SQL statement
384 $this->QueryHandle = $this->RunQuery($QueryString);
385 if (!$this->QueryHandle instanceof mysqli_result) { return FALSE; }
386
387 # save number of rows in result
388 $this->NumRows = mysqli_num_rows($this->QueryHandle);
389
390 # if too many rows to cache
391 if ($this->NumRows >= self::$CacheRowsThreshold)
392 {
393 # set flag to indicate that query results should not
394 # be retrieved from cache
395 $this->GetResultsFromCache = FALSE;
396 }
397 else
398 {
399 # if we are low on memory
400 if (self::GetFreeMemory() < self::$CacheMemoryThreshold)
401 {
402 # clear out all but last few rows from cache
403 self::$QueryResultCache = array_slice(
404 self::$QueryResultCache,
405 (0 - self::$CacheRowsToLeave));
406 }
407
408 # if advanced caching is enabled
409 if (self::$AdvancedCachingFlag)
410 {
411 # save tables accessed by query
412 self::$QueryResultCache[$QueryString]["TablesAccessed"] =
413 $this->TablesAccessed($QueryString);
414 }
415
416 # if rows found
417 if ($this->NumRows > 0)
418 {
419 # load query results
420 for ($Row = 0; $Row < $this->NumRows; $Row++)
421 {
422 $this->QueryResults[$Row] =
423 mysqli_fetch_assoc($this->QueryHandle);
424 }
425
426 # cache query results
427 self::$QueryResultCache[$QueryString] = $this->QueryResults;
428 }
429 else
430 {
431 # clear local query results
432 unset($this->QueryResults);
433 }
434
435 # cache number of rows
436 self::$QueryResultCache[$QueryString]["NumRows"] = $this->NumRows;
437
438 # set flag to indicate that query results should be
439 # retrieved from cache
440 $this->GetResultsFromCache = TRUE;
441 }
442 }
443 }
444 else
445 {
446 # if advanced caching is enabled
447 if (self::$AdvancedCachingFlag)
448 {
449 # if table modified by statement is known
450 $TableModified = $this->TableModified($QueryString);
451 if ($TableModified)
452 {
453 # for each cached query
454 foreach (self::$QueryResultCache
455 as $CachedQueryString => $CachedQueryResult)
456 {
457 # if we know what tables were accessed
458 if ($CachedQueryResult["TablesAccessed"])
459 {
460 # if tables accessed include the one we may modify
461 if (in_array($TableModified,
462 $CachedQueryResult["TablesAccessed"]))
463 {
464 # clear cached query results
465 unset(self::$QueryResultCache[$CachedQueryString]);
466 }
467 }
468 else
469 {
470 # clear cached query results
471 unset(self::$QueryResultCache[$CachedQueryString]);
472 }
473 }
474 }
475 else
476 {
477 # clear entire query result cache
478 self::$QueryResultCache = array();
479 }
480 }
481 else
482 {
483 # clear entire query result cache
484 self::$QueryResultCache = array();
485 }
486
487 # execute SQL statement
488 $this->QueryHandle = $this->RunQuery($QueryString);
489 if ($this->QueryHandle === FALSE) { return FALSE; }
490
491 # set flag to indicate that query results should not be
492 # retrieved from cache
493 $this->GetResultsFromCache = FALSE;
494 }
495
496 # reset row counter
497 $this->RowCounter = 0;
498
499 # increment query counter
500 self::$QueryCounter++;
501 }
502 else
503 {
504 # execute SQL statement
505 $this->QueryHandle = $this->RunQuery($QueryString);
506 if ($this->QueryHandle === FALSE) { return FALSE; }
507 }
508
509 if (($FieldName != "") && ($this->QueryHandle !== FALSE))
510 {
511 return $this->FetchField($FieldName);
512 }
513 else
514 {
515 return $this->QueryHandle;
516 }
517 }
518
531 public function ExecuteQueriesFromFile($FileName)
532 {
533 # open file
534 $FHandle = fopen($FileName, "r");
535
536 # if file open succeeded
537 if ($FHandle !== FALSE)
538 {
539 # while lines left in file
540 $Query = "";
541 $QueryCount = 0;
542 while (!feof($FHandle))
543 {
544 # read in line from file
545 $Line = fgets($FHandle, 32767);
546
547 # trim whitespace from line
548 $Line = trim($Line);
549
550 # if line is not empty and not a comment
551 if (!preg_match("/^#/", $Line)
552 && !preg_match("/^--/", $Line)
553 && strlen($Line))
554 {
555 # add line to current query
556 $Query .= " ".$Line;
557
558 # if line completes a query
559 if (preg_match("/;$/", $Line))
560 {
561 # run query
562 $QueryCount++;
563 $Result = $this->Query($Query);
564 $Query = "";
565
566 # if query resulted in an error that is not ignorable
567 if ($Result === FALSE)
568 {
569 # stop processing queries and set error code
570 $QueryCount = NULL;
571 break;
572 }
573 }
574 }
575 }
576
577 # close file
578 fclose($FHandle);
579 }
580
581 # return number of executed queries to caller
582 return $QueryCount;
583 }
584
590 public function QueryErrMsg()
591 {
592 return $this->ErrMsg;
593 }
594
600 public function QueryErrNo()
601 {
602 return $this->ErrNo;
603 }
604
611 public static function DisplayQueryErrors($NewValue = NULL)
612 {
613 if ($NewValue !== NULL) { self::$DisplayErrors = $NewValue; }
614 return self::$DisplayErrors;
615 }
616
621 public function NumRowsSelected()
622 {
623 # if caching is enabled and query was cached
624 if (self::$CachingFlag && $this->GetResultsFromCache)
625 {
626 # return cached number of rows to caller
627 return $this->NumRows;
628 }
629 else
630 {
631 # call to this method after an unsuccessful query
632 if (!$this->QueryHandle instanceof mysqli_result)
633 {
634 return 0;
635 }
636
637 # retrieve number of rows and return to caller
638 return mysqli_num_rows($this->QueryHandle);
639 }
640 }
641
647 public function NumRowsAffected()
648 {
649 # call to this method after an unsuccessful query
650 if ($this->QueryHandle === FALSE)
651 {
652 return 0;
653 }
654
655 # retrieve number of rows and return to caller
656 return mysqli_affected_rows($this->Handle);
657 }
658
664 public function FetchRow()
665 {
666 # if caching is enabled and query was cached
667 if (self::$CachingFlag && $this->GetResultsFromCache)
668 {
669 # if rows left to return
670 if ($this->RowCounter < $this->NumRows)
671 {
672 # retrieve row from cache
673 $Result = $this->QueryResults[$this->RowCounter];
674
675 # increment row counter
676 $this->RowCounter++;
677 }
678 else
679 {
680 # return nothing
681 $Result = FALSE;
682 }
683 }
684 else
685 {
686 # call to this method after successful query
687 if ($this->QueryHandle instanceof mysqli_result)
688 {
689 $Result = mysqli_fetch_assoc($this->QueryHandle);
690 if ($Result === NULL) { $Result = FALSE; }
691 }
692
693 # call to this method after unsuccessful query
694 else
695 {
696 $Result = FALSE;
697 }
698 }
699
700 # return row to caller
701 return $Result;
702 }
703
710 public function FetchRows($NumberOfRows = NULL)
711 {
712 # assume no rows will be returned
713 $Result = array();
714
715 # for each available row
716 $RowsFetched = 0;
717 while ((($RowsFetched < $NumberOfRows) || ($NumberOfRows == NULL))
718 && ($Row = $this->FetchRow()))
719 {
720 # add row to results
721 $Result[] = $Row;
722 $RowsFetched++;
723 }
724
725 # return array of rows to caller
726 return $Result;
727 }
728
745 public function FetchColumn($FieldName, $IndexFieldName = NULL)
746 {
747 $Array = array();
748 while ($Record = $this->FetchRow())
749 {
750 if ($IndexFieldName != NULL)
751 {
752 $Array[$Record[$IndexFieldName]] = $Record[$FieldName];
753 }
754 else
755 {
756 $Array[] = $Record[$FieldName];
757 }
758 }
759 return $Array;
760 }
761
770 public function FetchField($FieldName)
771 {
772 $Record = $this->FetchRow();
773 return isset($Record[$FieldName]) ? $Record[$FieldName] : NULL;
774 }
775
782 public function LastInsertId()
783 {
784 return (int)$this->Query(
785 "SELECT LAST_INSERT_ID() AS InsertId",
786 "InsertId");
787 }
788
799 public function GetNextInsertId($TableName)
800 {
801 if (!$this->TableExists($TableName))
802 {
803 throw new Exception(
804 "Table ".$TableName." does not exist");
805 }
806
807 return (int)$this->Query(
808 "SELECT `AUTO_INCREMENT` AS Id FROM INFORMATION_SCHEMA.TABLES "
809 ."WHERE TABLE_SCHEMA='".addslashes($this->DBName())."' "
810 ."AND TABLE_NAME = '".addslashes($TableName)."'", "Id");
811 }
812
827 public function UpdateValue(
828 $TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
829 {
830 # expand condition if supplied
831 if ($Condition != NULL) { $Condition = " WHERE ".$Condition; }
832
833 # if cached values not already loaded
834 if (!isset($CachedRecord))
835 {
836 # read cached record from database
837 $this->Query("SELECT * FROM `".$TableName."` ".$Condition);
838 $CachedRecord = $this->FetchRow();
839
840 # error out if requested column does not exist in specified table
841 if ($NewValue === DB_NOVALUE)
842 {
843 $RowsFound = ($this->NumRowsSelected() > 0);
844 if (($RowsFound && !array_key_exists($FieldName, $CachedRecord))
845 || (!$RowsFound && !$this->FieldExists($TableName, $FieldName)))
846 {
847 throw new Exception("Column '".$FieldName
848 ."' not found in table '".$TableName."'.");
849 }
850 }
851 }
852
853 # if new value supplied
854 if ($NewValue !== DB_NOVALUE)
855 {
856 # error out if we are trying to update a nonexistent record or field
857 if (!count($CachedRecord))
858 {
859 throw new Exception("No records found when attempting to update"
860 ." column '".$FieldName."' in table '".$TableName."'"
861 .(($Condition != NULL)
862 ? " using condition '".$Condition."'" : "")
863 .".");
864 }
865 else
866 {
867 if (!array_key_exists($FieldName, $CachedRecord))
868 {
869 throw new Exception("Attempting to update column '".$FieldName
870 ."', which does not exist in table '".$TableName."'.");
871 }
872 }
873
874 # update value in database
875 $this->Query("UPDATE `".$TableName."` SET `".$FieldName."` = "
876 .(($NewValue === NULL) ? "NULL" : "'"
877 .mysqli_real_escape_string($this->Handle, $NewValue)."'")
878 .$Condition);
879
880 # update value in cached record
881 $CachedRecord[$FieldName] = $NewValue;
882 }
883
884 # return value from cached record to caller
885 return isset($CachedRecord[$FieldName])
886 ? $CachedRecord[$FieldName] : NULL;
887 }
888
905 public function UpdateIntValue(
906 $TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
907 {
908 return $this->UpdateValue($TableName, $FieldName,
909 (($NewValue === DB_NOVALUE) ? DB_NOVALUE : (int)$NewValue),
910 $Condition, $CachedRecord);
911 }
912
929 public function UpdateFloatValue(
930 $TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
931 {
932 return $this->UpdateValue($TableName, $FieldName,
933 (($NewValue === DB_NOVALUE) ? DB_NOVALUE : (float)$NewValue),
934 $Condition, $CachedRecord);
935 }
936
948 public function CopyValues($TableName, $IdColumn, $SrcId, $DstId,
949 $ColumnsToExclude = array())
950 {
951 # retrieve names of all columns in table
952 $AllColumns = $this->GetColumns($TableName);
953
954 # remove columns to be excluded from copy
955 $ColumnsToExclude[] = $IdColumn;
956 $ColumnsToCopy = array_diff($AllColumns, $ColumnsToExclude);
957
958 # normalize destination IDs
959 $DstIds = is_array($DstId) ? $DstId : array($DstId);
960 $DstIds = array_diff($DstIds, array($SrcId));
961
962 # if there are columns to copy and we have destinations
963 if (count($ColumnsToCopy) && count($DstIds))
964 {
965 # construct and execute query to perform copy
966 $Query = "UPDATE `".$TableName."` AS Target"
967 ." LEFT JOIN `".$TableName."` AS Source"
968 ." ON Source.`".$IdColumn."` = '".addslashes($SrcId)."'";
969 $QuerySets = array();
970 foreach ($ColumnsToCopy as $ColumnName)
971 {
972 $QuerySets[] = "Target.`".$ColumnName."` = Source.`".$ColumnName."`";
973 }
974 $Query .= " SET ".implode(", ", $QuerySets);
975 $QueryConditions = array();
976 foreach ($DstIds as $Id)
977 {
978 $QueryConditions[] = "Target.`".$IdColumn."` = '".addslashes($DstId)."'";
979 }
980 $Query .= " WHERE ".implode(" OR ", $QueryConditions);
981 $this->Query($Query);
982 }
983 }
984
998 public function InsertArray($Table, $ValueField, $Values,
999 $KeyField = NULL, $AvgDataLength = 20)
1000 {
1001 # pick some ballpark values
1002 $ChunkSizeAssumedSafe = 100;
1003 $QueryLengthAssumedSafe = 10486576; # (1 MB)
1004
1005 # exit without doing anything if there are no values
1006 $ValueCount = count($Values);
1007 if ($ValueCount == 0)
1008 {
1009 return;
1010 }
1011
1012 # determine size of array chunk per INSERT statement
1013 $NonValueCharCount = 100;
1014 if ($ValueCount > $ChunkSizeAssumedSafe)
1015 {
1016 $MaxQueryLen = $this->GetMaxQueryLength();
1017 $ValueSegmentLen = $AvgDataLength + 6;
1018 if ($KeyField !== NULL)
1019 {
1020 $ValueSegmentLen = $ValueSegmentLen * 2;
1021 }
1022 $ValueChunkSize = $MaxQueryLen / $ValueSegmentLen;
1023 }
1024 else
1025 {
1026 $ValueChunkSize = $ChunkSizeAssumedSafe;
1027 }
1028
1029 # for each chunk of values
1030 foreach (array_chunk($Values, $ValueChunkSize, TRUE) as $ValueChunk)
1031 {
1032 # begin building query
1033 $Query = "INSERT INTO `".$Table."` (`".$ValueField."`";
1034
1035 # if key field was specified
1036 if ($KeyField !== NULL)
1037 {
1038 # add key field to query
1039 $Query .= ", `".$KeyField."`";
1040
1041 # assemble value segment with keys
1042 $ValueSegFunc = function($Carry, $Key) use ($ValueChunk)
1043 {
1044 $Carry .= "('".addslashes($ValueChunk[$Key])."','"
1045 .addslashes($Key)."'),";
1046 return $Carry;
1047 };
1048 $ValueSegment = array_reduce(array_keys($ValueChunk), $ValueSegFunc);
1049 }
1050 else
1051 {
1052 # assemble value segment
1053 $ValueSegFunc = function($Carry, $Value)
1054 {
1055 $Carry .= "('".addslashes($Value)."'),";
1056 return $Carry;
1057 };
1058 $ValueSegment = array_reduce($ValueChunk, $ValueSegFunc);
1059 }
1060
1061 # trim extraneous comma off of value segment
1062 $ValueSegment = substr($ValueSegment, 0, -1);
1063
1064 # add value segment to query
1065 $Query .= ") VALUES ".$ValueSegment;
1066
1067 # double check to make sure query isn't too long
1068 $QueryLen = strlen($Query);
1069 if ($QueryLen > $QueryLengthAssumedSafe)
1070 {
1071 if (!isset($MaxQueryLen))
1072 {
1073 $MaxQueryLen = $this->GetMaxQueryLength();
1074 }
1075 if ($QueryLen > $MaxQueryLen)
1076 {
1077 throw new Exception("Maximum query length ("
1078 .$MaxQueryLen.") exceeded (".$QueryLen.").");
1079 }
1080 }
1081
1082 # run query
1083 $this->Query($Query);
1084 }
1085 }
1086
1087 /*@)*/ /* Data Manipulation */ /*@(*/
1089
1098 public function EscapeString($String)
1099 {
1100 return mysqli_real_escape_string($this->Handle, $String);
1101 }
1102
1109 public function LogComment($String)
1110 {
1111 $this->Query("-- ".$String);
1112 }
1113
1119 public function TableExists($TableName)
1120 {
1121 $this->Query("SHOW TABLES LIKE '".addslashes($TableName)."'");
1122 return $this->NumRowsSelected() ? TRUE : FALSE;
1123 }
1124
1131 public function FieldExists($TableName, $FieldName)
1132 {
1133 $this->Query("DESC ".$TableName);
1134 while ($CurrentFieldName = $this->FetchField("Field"))
1135 {
1136 if ($CurrentFieldName == $FieldName) { return TRUE; }
1137 }
1138 return FALSE;
1139 }
1140
1147 public function GetFieldType($TableName, $FieldName)
1148 {
1149 $this->Query("DESC ".$TableName);
1150 $AllTypes = $this->FetchColumn("Type", "Field");
1151 return $AllTypes[$FieldName];
1152 }
1153
1159 public function GetColumns($TableName)
1160 {
1161 $this->Query("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS"
1162 ." WHERE TABLE_SCHEMA = '".addslashes($this->DBName)
1163 ."' AND TABLE_NAME = '".addslashes($TableName)."'");
1164 return $this->FetchColumn("COLUMN_NAME");
1165 }
1166
1171 public function GetMaxQueryLength()
1172 {
1173 return $this->Query("SHOW VARIABLES LIKE 'max_allowed_packet'",
1174 "Value");
1175 }
1176
1182 public static function QueryDebugOutput($NewSetting)
1183 {
1184 self::$QueryDebugOutputFlag = $NewSetting;
1185 }
1186
1192 public static function NumQueries()
1193 {
1194 return self::$QueryCounter;
1195 }
1196
1203 public static function NumCacheHits()
1204 {
1205 return self::$CachedQueryCounter;
1206 }
1207
1213 public static function CacheHitRate()
1214 {
1215 if (self::$QueryCounter)
1216 {
1217 return (self::$CachedQueryCounter / self::$QueryCounter) * 100;
1218 }
1219 else
1220 {
1221 return 0;
1222 }
1223 }
1224
1225 /*@)*/ /* Miscellaneous */
1226
1227 # ---- PRIVATE INTERFACE -------------------------------------------------
1228
1229 protected $DBUserName;
1230 protected $DBPassword;
1231 protected $DBHostName;
1232 protected $DBName;
1233
1234 private $Handle;
1235 private $QueryHandle;
1236 private $QueryResults;
1237 private $RowCounter;
1238 private $NumRows;
1239 private $GetResultsFromCache;
1240 private $ErrorIgnored = FALSE;
1241 private $ErrorsToIgnore = NULL;
1242 private $ErrMsg = NULL;
1243 private $ErrNo = NULL;
1244
1245 private static $DisplayErrors = FALSE;
1246
1247 private static $GlobalDBUserName;
1248 private static $GlobalDBPassword;
1249 private static $GlobalDBHostName;
1250 private static $GlobalDBName;
1251
1252 # debug output flag
1253 private static $QueryDebugOutputFlag = FALSE;
1254 # flag for whether caching is turned on
1255 private static $CachingFlag = TRUE;
1256 # query result advanced caching flag
1257 private static $AdvancedCachingFlag = FALSE;
1258 # global cache for query results
1259 private static $QueryResultCache = array();
1260 # stats counters
1261 private static $QueryCounter = 0;
1262 private static $CachedQueryCounter = 0;
1263 # database connection link handles
1264 private static $ConnectionHandles = array();
1265 # do not cache queries that return more than this number of rows
1266 private static $CacheRowsThreshold = 250;
1267 # prune the query cache if there is less than this amount of memory free
1268 private static $CacheMemoryThreshold;
1269 # number of rows to leave in cache when pruning
1270 private static $CacheRowsToLeave = 10;
1271 # number of retry attempts to make to connect to database
1272 private static $ConnectRetryAttempts = 3;
1273 # number of seconds to wait between connection retry attempts
1274 private static $ConnectRetryInterval = 5;
1275
1276 # server connection error codes
1277 const CR_CONNECTION_ERROR = 2002; # Can't connect to local MySQL server
1278 # through socket '%s' (%d)
1279 const CR_CONN_HOST_ERROR = 2003; # Can't connect to MySQL server on '%s' (%d)
1280 const CR_SERVER_GONE_ERROR = 2006; # MySQL server has gone away
1281 const CR_SERVER_LOST = 2013; # Lost connection to MySQL server during query
1282
1283 # limits on int variables
1284 # https://dev.mysql.com/doc/refman/5.7/en/integer-types.html
1285 const TINYINT_MAX_VALUE = 127;
1286 const SMALLINT_MAX_VALUE = 32767;
1287 const MEDIUMINT_MAX_VALUE = 8388607;
1288 const INT_MAX_VALUE = 2147483647;
1289 const BIGINT_MAX_VALUE = 9223372036854775807;
1290
1291 # connection error codes that may be recoverable
1292 private static $RecoverableConnectionErrors = array(
1293 self::CR_CONNECTION_ERROR,
1294 );
1295
1306 private static function ConnectAndSelectDB(
1307 $DBHostName, $DBUserName, $DBPassword, $DBName)
1308 {
1309 $ConnectAttemptsLeft = self::$ConnectRetryAttempts + 1;
1310 do
1311 {
1312 # if this is not our first connection attempt
1313 if (isset($Handle))
1314 {
1315 # wait for the retry interval
1316 sleep(self::$ConnectRetryInterval);
1317 }
1318
1319 # attempt to connect to server
1320 $Handle = @mysqli_connect($DBHostName, $DBUserName, $DBPassword);
1321 $ConnectAttemptsLeft--;
1322 }
1323 # repeat if we do not have a connection and there are retry attempts
1324 # left and the connection error code indicates a retry may succeed
1325 // @codingStandardsIgnoreStart
1326 // (because phpcs apparently doesn't know how to handle do-while loops)
1327 while (!$Handle && $ConnectAttemptsLeft
1328 && in_array(mysqli_connect_errno(),
1329 self::$RecoverableConnectionErrors));
1330 // @codingStandardsIgnoreEnd
1331
1332 # throw exception if connection attempts failed
1333 if (!$Handle)
1334 {
1335 throw new Exception("Could not connect to database: "
1336 .mysqli_connect_error()." (errno: ".mysqli_connect_errno().")");
1337 }
1338
1339 # select DB
1340 $Result = mysqli_select_db($Handle, $DBName);
1341 if ($Result !== TRUE)
1342 {
1343 throw new Exception("Could not select database: "
1344 .mysqli_error($Handle)." (errno: ".mysqli_errno($Handle).")");
1345 }
1346
1347 # return new connection to caller
1348 return $Handle;
1349 }
1350
1356 private function IsReadOnlyStatement($QueryString)
1357 {
1358 return preg_match("/^[ ]*SELECT /i", $QueryString) ? TRUE : FALSE;
1359 }
1360
1367 private function TableModified($QueryString)
1368 {
1369 # assume we're not going to be able to determine table
1370 $TableName = FALSE;
1371
1372 # split query into pieces
1373 $QueryString = trim($QueryString);
1374 $Words = preg_split("/\s+/", $QueryString);
1375
1376 # if INSERT statement
1377 $WordIndex = 1;
1378 if (strtoupper($Words[0]) == "INSERT")
1379 {
1380 # skip over modifying keywords
1381 while ((strtoupper($Words[$WordIndex]) == "LOW_PRIORITY")
1382 || (strtoupper($Words[$WordIndex]) == "DELAYED")
1383 || (strtoupper($Words[$WordIndex]) == "IGNORE")
1384 || (strtoupper($Words[$WordIndex]) == "INTO"))
1385 {
1386 $WordIndex++;
1387 }
1388
1389 # next word is table name
1390 $TableName = $Words[$WordIndex];
1391 }
1392 # else if UPDATE statement
1393 elseif (strtoupper($Words[0]) == "UPDATE")
1394 {
1395 # skip over modifying keywords
1396 while ((strtoupper($Words[$WordIndex]) == "LOW_PRIORITY")
1397 || (strtoupper($Words[$WordIndex]) == "IGNORE"))
1398 {
1399 $WordIndex++;
1400 }
1401
1402 # if word following next word is SET
1403 if (strtoupper($Words[$WordIndex + 1]) == "SET")
1404 {
1405 # next word is table name
1406 $TableName = $Words[$WordIndex];
1407 }
1408 }
1409 # else if DELETE statement
1410 elseif (strtoupper($Words[0]) == "DELETE")
1411 {
1412 # skip over modifying keywords
1413 while ((strtoupper($Words[$WordIndex]) == "LOW_PRIORITY")
1414 || (strtoupper($Words[$WordIndex]) == "IGNORE")
1415 || (strtoupper($Words[$WordIndex]) == "QUICK"))
1416 {
1417 $WordIndex++;
1418 }
1419
1420 # if next term is FROM
1421 if (strtoupper($Words[$WordIndex]) == "FROM")
1422 {
1423 # next word is table name
1424 $WordIndex++;
1425 $TableName = $Words[$WordIndex];
1426 }
1427 }
1428
1429 # discard table name if it looks at all suspicious
1430 if ($TableName)
1431 {
1432 if (!preg_match("/[a-zA-Z0-9]+/", $TableName))
1433 {
1434 $TableName = FALSE;
1435 }
1436 }
1437
1438 # return table name (or lack thereof) to caller
1439 return $TableName;
1440 }
1441
1448 private function TablesAccessed($QueryString)
1449 {
1450 # assume we're not going to be able to determine tables
1451 $TableNames = FALSE;
1452
1453 # split query into pieces
1454 $QueryString = trim($QueryString);
1455 $Words = preg_split("/\s+/", $QueryString);
1456 $UQueryString = strtoupper($QueryString);
1457 $UWords = preg_split("/\s+/", $UQueryString);
1458
1459 # if SELECT statement
1460 if ($UWords[0] == "SELECT")
1461 {
1462 # keep going until we hit FROM or last word
1463 $WordIndex = 1;
1464 while (($UWords[$WordIndex] != "FROM")
1465 && strlen($UWords[$WordIndex]))
1466 {
1467 $WordIndex++;
1468 }
1469
1470 # if we hit FROM
1471 if ($UWords[$WordIndex] == "FROM")
1472 {
1473 # for each word after FROM
1474 $WordIndex++;
1475 while (strlen($UWords[$WordIndex]))
1476 {
1477 # if current word ends with comma
1478 if (preg_match("/,$/", $Words[$WordIndex]))
1479 {
1480 # strip off comma and add word to table name list
1481 $TableNames[] = substr($Words[$WordIndex], 0, -1);
1482 }
1483 else
1484 {
1485 # add word to table name list
1486 $TableNames[] = $Words[$WordIndex];
1487
1488 # if next word is not comma
1489 $WordIndex++;
1490 if ($Words[$WordIndex] != ",")
1491 {
1492 # if word begins with comma
1493 if (preg_match("/^,/", $Words[$WordIndex]))
1494 {
1495 # strip off comma (NOTE: modifies $Words array!)
1496 $Words[$WordIndex] = substr($Words[$WordIndex], 1);
1497
1498 # decrement index so we start with this word next pass
1499 $WordIndex--;
1500 }
1501 else
1502 {
1503 # stop scanning words (non-basic JOINs not yet handled)
1504 break;
1505 }
1506 }
1507 }
1508
1509 # move to next word
1510 $WordIndex++;
1511 }
1512 }
1513 }
1514
1515 # discard table names if they look at all suspicious
1516 if ($TableNames)
1517 {
1518 foreach ($TableNames as $Name)
1519 {
1520 if (!preg_match("/^[a-zA-Z0-9]+$/", $Name))
1521 {
1522 $TableNames = FALSE;
1523 break;
1524 }
1525 }
1526 }
1527
1528 # return table name (or lack thereof) to caller
1529 return $TableNames;
1530 }
1531
1538 private function RunQuery($QueryString)
1539 {
1540 # log query start time if debugging output is enabled
1541 if (self::$QueryDebugOutputFlag) { $QueryStartTime = microtime(TRUE); }
1542
1543 # run query against database
1544 $this->QueryHandle = mysqli_query($this->Handle, $QueryString) ;
1545
1546 # print query and execution time if debugging output is enabled
1547 if (self::$QueryDebugOutputFlag)
1548 {
1549 print "DB: ".$QueryString." ["
1550 .sprintf("%.2f", microtime(TRUE) - $QueryStartTime)
1551 ."s]"."<br>\n";
1552 }
1553
1554 # if query failed and there are errors that we can ignore
1555 if (($this->QueryHandle === FALSE) && $this->ErrorsToIgnore)
1556 {
1557 # for each pattern for an error that we can ignore
1558 foreach ($this->ErrorsToIgnore as $SqlPattern => $ErrMsgPattern)
1559 {
1560 # if error matches pattern
1561 $ErrorMsg = mysqli_error($this->Handle);
1562 if (preg_match($SqlPattern, $QueryString)
1563 && preg_match($ErrMsgPattern, $ErrorMsg))
1564 {
1565 # set return value to indicate error was ignored
1566 $this->QueryHandle = TRUE;
1567
1568 # set internal flag to indicate that an error was ignored
1569 $this->ErrorIgnored = $ErrorMsg;
1570
1571 # stop looking at patterns
1572 break;
1573 }
1574 }
1575 }
1576
1577 # if query failed
1578 if ($this->QueryHandle === FALSE)
1579 {
1580 # clear stored value for number of rows retrieved
1581 $this->NumRows = 0;
1582
1583 # retrieve error info
1584 $this->ErrMsg = mysqli_error($this->Handle);
1585 $this->ErrNo = mysqli_errno($this->Handle);
1586
1587 # if we are supposed to be displaying errors
1588 if (self::$DisplayErrors)
1589 {
1590 # print error info
1591 print("<b>SQL Error:</b> <i>".$this->ErrMsg
1592 ."</i> (".$this->ErrNo.")<br/>\n");
1593 print("<b>SQL Statement:</b> <i>"
1594 .htmlspecialchars($QueryString)."</i><br/>\n");
1595
1596 # retrieve execution trace that got us to this point
1597 $Trace = debug_backtrace();
1598
1599 # remove current context from trace
1600 array_shift($Trace);
1601
1602 # make sure file name and line number are available
1603 foreach ($Trace as $Index => $Loc)
1604 {
1605 if (!array_key_exists("file", $Loc))
1606 {
1607 $Trace[$Index]["file"] = "UNKNOWN";
1608 }
1609 if (!array_key_exists("line", $Loc))
1610 {
1611 $Trace[$Index]["line"] = "??";
1612 }
1613 }
1614
1615 # determine length of leading path common to all file names in trace
1616 $LocString = "";
1617 $OurFile = __FILE__;
1618 $PrefixLen = 9999;
1619 foreach ($Trace as $Loc)
1620 {
1621 if ($Loc["file"] != "UNKNOWN")
1622 {
1623 $Index = 0;
1624 $FNameLength = strlen($Loc["file"]);
1625 while ($Index < $FNameLength &&
1626 $Loc["file"][$Index] == $OurFile[$Index])
1627 { $Index++; }
1628 $PrefixLen = min($PrefixLen, $Index);
1629 }
1630 }
1631
1632 foreach ($Trace as $Loc)
1633 {
1634 $Sep = "";
1635 $ArgString = "";
1636 foreach ($Loc["args"] as $Arg)
1637 {
1638 $ArgString .= $Sep;
1639 switch (gettype($Arg))
1640 {
1641 case "boolean":
1642 $ArgString .= $Arg ? "TRUE" : "FALSE";
1643 break;
1644
1645 case "integer":
1646 case "double":
1647 $ArgString .= $Arg;
1648 break;
1649
1650 case "string":
1651 $ArgString .= '"<i>'.htmlspecialchars(substr($Arg, 0, 40))
1652 .((strlen($Arg) > 40) ? "..." : "").'</i>"';
1653 break;
1654
1655 case "array":
1656 case "resource":
1657 case "NULL":
1658 $ArgString .= strtoupper(gettype($Arg));
1659 break;
1660
1661 case "object":
1662 $ArgString .= get_class($Arg);
1663 break;
1664
1665 case "unknown type":
1666 $ArgString .= "UNKNOWN";
1667 break;
1668 }
1669 $Sep = ",";
1670 }
1671 $Loc["file"] = substr($Loc["file"], $PrefixLen);
1672 $LocString .= "&nbsp;&nbsp;";
1673 if (array_key_exists("class", $Loc))
1674 { $LocString .= $Loc["class"]."::"; }
1675 $LocString .= $Loc["function"]."(".$ArgString.")"
1676 ." - ".$Loc["file"].":".$Loc["line"]
1677 ."<br>\n";
1678 }
1679 print("<b>Trace:</b><br>\n".$LocString);
1680 }
1681 }
1682 return $this->QueryHandle;
1683 }
1684
1689 static private function GetPhpMemoryLimit()
1690 {
1691 $Str = strtoupper(ini_get("memory_limit"));
1692 if (substr($Str, -1) == "B") { $Str = substr($Str, 0, strlen($Str) - 1); }
1693 switch (substr($Str, -1))
1694 {
1695 case "K":
1696 $MemoryLimit = (int)$Str * 1024;
1697 break;
1698
1699 case "M":
1700 $MemoryLimit = (int)$Str * 1048576;
1701 break;
1702
1703 case "G":
1704 $MemoryLimit = (int)$Str * 1073741824;
1705 break;
1706
1707 default:
1708 $MemoryLimit = (int)$Str;
1709 break;
1710 }
1711 return $MemoryLimit;
1712 }
1713
1718 static private function GetFreeMemory()
1719 {
1720 return self::GetPhpMemoryLimit() - memory_get_usage();
1721 }
1722 }
1723
1724 # define return values (numerical values correspond to MySQL error codes)
1725 // @codingStandardsIgnoreStart (to silence warning about multiple spaces)
1726 define("DB_OKAY", 0);
1727 define("DB_ERROR", 1);
1728 define("DB_ACCESSDENIED", 2);
1729 define("DB_UNKNOWNDB", 3);
1730 define("DB_UNKNOWNTABLE", 4);
1731 define("DB_SYNTAXERROR", 5);
1732 define("DB_DBALREADYEXISTS", 6);
1733 define("DB_DBDOESNOTEXIST", 7);
1734 define("DB_DISKFULL", 8);
1735 // @codingStandardsIgnoreEnd
1736
1737 # define value to designate omitted arguments (so DB values can be set to NULL)
1738 define("DB_NOVALUE", "!-_-_-DB_NOVALUE-_-_-!");
1739
1740 # MySQL error code mapping
1741 $APDBErrorCodeMappings = array(
1742 1045 => DB_ACCESSDENIED,
1743 1049 => DB_UNKNOWNDB,
1744 1046 => DB_UNKNOWNTABLE,
1745 1064 => DB_SYNTAXERROR,
1746 1007 => DB_DBALREADYEXISTS, # ? (not sure)
1747 1008 => DB_DBDOESNOTEXIST, # ? (not sure)
1748 1021 => DB_DISKFULL, # ? (not sure)
1749 );
1750
1751 # date() format for SQL dates
1752 define("DATE_SQL", "Y-m-d H:i:s");
Database\QueryErrMsg
QueryErrMsg()
Get most recent error message text set by Query().
Definition: Database.php:590
Database\$DBName
$DBName
Definition: Database.php:1232
Database\Caching
static Caching($NewSetting=NULL)
Get or set whether query result caching is currently enabled.
Definition: Database.php:259
Database\__sleep
__sleep()
Definition: Database.php:81
Database\GetServerVersion
GetServerVersion($FullVersion=FALSE)
Get database server version number.
Definition: Database.php:183
Database\SetGlobalDatabaseName
static SetGlobalDatabaseName($DatabaseName)
Set default database name.
Definition: Database.php:154
Database\CR_CONNECTION_ERROR
const CR_CONNECTION_ERROR
Definition: Database.php:1277
DB_ACCESSDENIED
const DB_ACCESSDENIED
Definition: Database.php:1728
Database\SetDefaultStorageEngine
SetDefaultStorageEngine($Engine)
Set default database storage engine.
Definition: Database.php:167
Database\ExecuteQueriesFromFile
ExecuteQueriesFromFile($FileName)
Execute queries from specified file.
Definition: Database.php:531
Database\$DBPassword
$DBPassword
Definition: Database.php:1230
Database\$DBUserName
$DBUserName
Definition: Database.php:1229
Database\UpdateIntValue
UpdateIntValue($TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
A convenience function to get or set an integer value in the database.
Definition: Database.php:905
Database
SQL database abstraction object with smart query caching.
Definition: Database.php:22
Database\SetQueryErrorsToIgnore
SetQueryErrorsToIgnore($ErrorsToIgnore, $NormalizeWhitespace=TRUE)
Set query errors to ignore.
Definition: Database.php:313
Database\CR_SERVER_GONE_ERROR
const CR_SERVER_GONE_ERROR
Definition: Database.php:1280
Database\DBUserName
DBUserName()
Get name used to connect with database server.
Definition: Database.php:247
Database\GetNextInsertId
GetNextInsertId($TableName)
For tables that have an AUTO_INCREMENT column, get the next value that will be assigned.
Definition: Database.php:799
Database\EscapeString
EscapeString($String)
Escape a string that may contain null bytes.
Definition: Database.php:1098
Database\FetchRow
FetchRow()
Get next database row retrieved by most recent query.
Definition: Database.php:664
Database\LastInsertId
LastInsertId()
Get ID of row added by the last SQL "INSERT" statement.
Definition: Database.php:782
Database\CR_SERVER_LOST
const CR_SERVER_LOST
Definition: Database.php:1281
DB_SYNTAXERROR
const DB_SYNTAXERROR
Definition: Database.php:1731
Database\__construct
__construct($UserName=NULL, $Password=NULL, $DatabaseName=NULL, $HostName=NULL)
Object constructor.
Definition: Database.php:43
Database\TableExists
TableExists($TableName)
Get whether specified table exists.
Definition: Database.php:1119
DB_DISKFULL
const DB_DISKFULL
Definition: Database.php:1734
Database\INT_MAX_VALUE
const INT_MAX_VALUE
Definition: Database.php:1288
Database\SetGlobalServerInfo
static SetGlobalServerInfo($UserName, $Password, $HostName="localhost")
Set default login and host info for database server.
Definition: Database.php:138
$APDBErrorCodeMappings
$APDBErrorCodeMappings
Definition: Database.php:1741
Database\$DBHostName
$DBHostName
Definition: Database.php:1231
PHP
PHP
Definition: RSSClient--Test.php:12
Database\GetClientVersion
GetClientVersion()
Get version number of the client libraries being used to connect to the database server (Currently th...
Definition: Database.php:207
Database\GetFieldType
GetFieldType($TableName, $FieldName)
Get field (column) type.
Definition: Database.php:1147
DB_NOVALUE
const DB_NOVALUE
Definition: Database.php:1738
Database\MEDIUMINT_MAX_VALUE
const MEDIUMINT_MAX_VALUE
Definition: Database.php:1287
Database\NumRowsSelected
NumRowsSelected()
Get number of rows returned by last SELECT or SHOW query.
Definition: Database.php:621
Database\SMALLINT_MAX_VALUE
const SMALLINT_MAX_VALUE
Definition: Database.php:1286
Database\FetchRows
FetchRows($NumberOfRows=NULL)
Get specified number of database rows retrieved by most recent query.
Definition: Database.php:710
Database\QueryDebugOutput
static QueryDebugOutput($NewSetting)
Enable or disable debugging output for queries.
Definition: Database.php:1182
Database\Query
Query($QueryString, $FieldName="")
Query database (with caching if enabled).
Definition: Database.php:351
Database\GetColumns
GetColumns($TableName)
Get column (database field) names.
Definition: Database.php:1159
Database\FetchField
FetchField($FieldName)
Pull next row from last DB query and get a specific value from that row.
Definition: Database.php:770
Database\FieldExists
FieldExists($TableName, $FieldName)
Get whether specified field exists in specified table.
Definition: Database.php:1131
Database\NumCacheHits
static NumCacheHits()
Get the number of queries that have resulted in cache hits since program execution began...
Definition: Database.php:1203
DB_UNKNOWNTABLE
const DB_UNKNOWNTABLE
Definition: Database.php:1730
Database\FetchColumn
FetchColumn($FieldName, $IndexFieldName=NULL)
Get all available values for specified database field retrieved by most recent query.
Definition: Database.php:745
Database\DBHostName
DBHostName()
Get host name of system on which database server resides.
Definition: Database.php:227
DB_DBDOESNOTEXIST
const DB_DBDOESNOTEXIST
Definition: Database.php:1733
Database\NumRowsAffected
NumRowsAffected()
Get number of rows affected by last INSERT, UPDATE, REPLACE, or DELETE query.
Definition: Database.php:647
Database\UpdateFloatValue
UpdateFloatValue($TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
A convenience function to get or set a float value in the database.
Definition: Database.php:929
DB_DBALREADYEXISTS
const DB_DBALREADYEXISTS
Definition: Database.php:1732
Database\InsertArray
InsertArray($Table, $ValueField, $Values, $KeyField=NULL, $AvgDataLength=20)
Insert an array of values with a minimum number of INSERT statements.
Definition: Database.php:998
Database\QueryErrNo
QueryErrNo()
Get most recent error code set by Query().
Definition: Database.php:600
DB_UNKNOWNDB
const DB_UNKNOWNDB
Definition: Database.php:1729
Database\GetHostInfo
GetHostInfo()
Get database connection type and hostname.
Definition: Database.php:217
Database\UpdateValue
UpdateValue($TableName, $FieldName, $NewValue, $Condition, &$CachedRecord)
A convenience function to get or set a value in the database.
Definition: Database.php:827
Database\AdvancedCaching
static AdvancedCaching($NewSetting=NULL)
Get or set whether advanced query result cachine is currently enabled.
Definition: Database.php:285
Database\BIGINT_MAX_VALUE
const BIGINT_MAX_VALUE
Definition: Database.php:1289
Database\TINYINT_MAX_VALUE
const TINYINT_MAX_VALUE
Definition: Database.php:1285
Database\DisplayQueryErrors
static DisplayQueryErrors($NewValue=NULL)
Get/set whether Query() errors will be displayed.
Definition: Database.php:611
Database\CacheHitRate
static CacheHitRate()
Get the ratio of query cache hits to queries as a percentage.
Definition: Database.php:1213
Database\GetMaxQueryLength
GetMaxQueryLength()
Get maximum size for query string.
Definition: Database.php:1171
Database\IgnoredError
IgnoredError()
Check whether an error was ignored by the most recent query.
Definition: Database.php:333
Database\DBName
DBName()
Get current database name.
Definition: Database.php:237
Database\CopyValues
CopyValues($TableName, $IdColumn, $SrcId, $DstId, $ColumnsToExclude=array())
A convenience function to copy values from one row to another.
Definition: Database.php:948
Database\LogComment
LogComment($String)
Peform query that consists of SQL comment statement.
Definition: Database.php:1109
Database\__wakeup
__wakeup()
Restore database connection when unserialized.
Definition: Database.php:90
Database\NumQueries
static NumQueries()
Get the number of queries that have been run since program execution began.
Definition: Database.php:1192