20 private $dbLinks = array();
23 private $queryCount = 0;
36 private $queryCache = null;
41 private $queryCacheSize = 50;
58 private $delayedQueries = array();
61 private $installed =
false;
77 $this->logger = $logger;
78 $this->config = $config;
80 $this->tablePrefix = $config->getTablePrefix();
82 $this->enableQueryCache();
98 if (isset($this->dbLinks[
$type])) {
99 return $this->dbLinks[
$type];
100 }
else if (isset($this->dbLinks[
'readwrite'])) {
101 return $this->dbLinks[
'readwrite'];
103 $this->setupConnections();
104 return $this->getLink($type);
118 if ($this->config->isDatabaseSplit()) {
119 $this->establishLink(
'read');
120 $this->establishLink(
'write');
122 $this->establishLink(
'readwrite');
140 $conf = $this->config->getConnectionConfig($dblinkname);
143 $this->dbLinks[$dblinkname] = mysql_connect($conf[
'host'], $conf[
'user'], $conf[
'password'],
true);
144 if (!$this->dbLinks[$dblinkname]) {
145 $msg =
"Elgg couldn't connect to the database using the given credentials. Check the settings file.";
146 throw new \DatabaseException($msg);
149 if (!mysql_select_db($conf[
'database'], $this->dbLinks[$dblinkname])) {
150 $msg =
"Elgg couldn't select the database '{$conf['database']}'. Please check that the database is created and you have access to it.";
151 throw new \DatabaseException($msg);
155 mysql_query(
"SET NAMES utf8");
174 public function getData($query, $callback =
'') {
175 return $this->getResults($query, $callback,
false);
192 return $this->getResults($query, $callback,
true);
208 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
210 $dblink = $this->getLink(
'write');
212 $this->invalidateQueryCache();
214 if ($this->executeQuery(
"$query", $dblink)) {
215 return mysql_insert_id($dblink);
234 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
236 $dblink = $this->getLink(
'write');
238 $this->invalidateQueryCache();
240 if ($this->executeQuery(
"$query", $dblink)) {
242 return mysql_affected_rows($dblink);
263 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
265 $dblink = $this->getLink(
'write');
267 $this->invalidateQueryCache();
269 if ($this->executeQuery(
"$query", $dblink)) {
270 return mysql_affected_rows($dblink);
290 if (is_string($callback)) {
293 if (is_object($callback)) {
294 return spl_object_hash($callback) .
"::__invoke";
296 if (is_array($callback)) {
297 if (is_string($callback[0])) {
298 return "{$callback[0]}::{$callback[1]}";
300 return spl_object_hash($callback[0]) .
"::{$callback[1]}";
318 protected function getResults($query, $callback = null, $single =
false) {
323 $query_id = (int)$single . $query .
'|';
325 $is_callable = is_callable($callback);
327 $query_id .= $this->fingerprintCallback($callback);
333 $is_callable =
false;
336 $hash = md5($query_id);
339 if ($this->queryCache) {
340 if (isset($this->queryCache[$hash])) {
341 $this->logger->log(
"DB query $query results returned from cache (hash: $hash)", \
Elgg\Logger::INFO);
342 return $this->queryCache[$hash];
346 $dblink = $this->getLink(
'read');
349 if (
$result = $this->executeQuery(
"$query", $dblink)) {
352 $row = call_user_func($callback,
$row);
365 $this->logger->log(
"DB query $query returned no results.", \
Elgg\Logger::INFO);
369 if ($this->queryCache) {
370 $this->queryCache[$hash] =
$return;
371 $this->logger->log(
"DB query $query results cached (hash: $hash)", \
Elgg\Logger::INFO);
392 if ($query == null) {
393 throw new \DatabaseException(
"Query cannot be null");
396 if (!is_resource($dblink)) {
397 throw new \DatabaseException(
"Connection to database was lost.");
402 $result = mysql_query($query, $dblink);
404 if (mysql_errno($dblink)) {
405 throw new \DatabaseException(mysql_error($dblink) .
"\n\n QUERY: $query");
436 $script = file_get_contents($scriptlocation);
442 $script = preg_replace(
'/^(?:--|#) .*$/m',
'', $script);
445 $sql_statements = preg_split(
'/;[\n\r]+/',
"$script\n");
447 foreach ($sql_statements as $statement) {
448 $statement = trim($statement);
449 $statement = str_replace(
"prefix_", $this->tablePrefix, $statement);
450 if (!empty($statement)) {
452 $this->updateData($statement);
454 $errors[] = $e->getMessage();
458 if (!empty($errors)) {
460 foreach ($errors as
$error) {
461 $errortxt .=
" {$error};";
464 $msg =
"There were a number of issues: " . $errortxt;
465 throw new \DatabaseException($msg);
468 $msg =
"Elgg couldn't find the requested database script at " . $scriptlocation .
".";
469 throw new \DatabaseException($msg);
493 $delayed_query = array();
494 $delayed_query[
'q'] = $query;
495 $delayed_query[
'l'] =
$type;
498 $this->delayedQueries[] = $delayed_query;
514 foreach ($this->delayedQueries as $query_details) {
516 $link = $query_details[
'l'];
518 if ($link ==
'read' || $link ==
'write') {
519 $link = $this->getLink($link);
520 } elseif (!is_resource($link)) {
521 $msg =
"Link for delayed query not valid resource or db_link type. Query: {$query_details['q']}";
522 $this->logger->log($msg, \
Elgg\Logger::WARNING);
525 $result = $this->executeQuery($query_details[
'q'], $link);
527 if ((isset($query_details[
'h'])) && (is_callable($query_details[
'h']))) {
545 if ($this->config->isQueryCacheEnabled() && $this->queryCache === null) {
547 $this->queryCache = new \Elgg\Cache\LRUCache($this->queryCacheSize);
560 $this->queryCache = null;
569 if ($this->queryCache) {
570 $this->queryCache->clear();
571 $this->logger->log(
"Query cache invalidated", \
Elgg\Logger::INFO);
588 $dblink = $this->getLink(
'read');
589 mysql_query(
"SELECT value FROM {$this->tablePrefix}datalists WHERE name = 'installed'", $dblink);
590 if (mysql_errno($dblink) > 0) {
591 throw new \DatabaseException();
594 throw new \InstallationException(
"Unable to handle this request. This site is not configured or the database is down.");
606 return $this->queryCount;
615 return $this->tablePrefix;
628 if ($signed ===
false) {
644 return mysql_real_escape_string(
$value);
if(!$owner||!($owner instanceof ElggUser)||!$owner->canEdit()) $error
getData($query, $callback= '')
Retrieve rows from the database.
getQueryCount()
Get the number of queries made to the database.
getDataRow($query, $callback= '')
Retrieve a single row from the database.
getLink($type)
Gets (if required, also creates) a database link resource.
invalidateQueryCache()
Invalidate the query cache.
$CONFIG installed
Is the site fully installed.
deleteData($query)
Delete data from the database.
executeQuery($query, $dblink)
Execute a query.
insertData($query)
Insert a row into the database.
sanitizeInt($value, $signed=true)
Sanitizes an integer value for use in a query.
sanitizeString($value)
Sanitizes a string for use in a query.
assertInstalled()
Test that the Elgg database is installed.
runSqlScript($scriptlocation)
Runs a full database script from disk.
registerDelayedQuery($query, $type, $handler="")
Queue a query for execution upon shutdown.
fingerprintCallback($callback)
Get a string that uniquely identifies a callback during the current request.
__construct(\Elgg\Database\Config $config,\Elgg\Logger $logger)
Constructor.
updateData($query, $getNumRows=false)
Update the database.
disableQueryCache()
Disable the query cache.
enableQueryCache()
Enable the query cache.
getResults($query, $callback=null, $single=false)
Handles queries that return results, running the results through a an optional callback function...
establishLink($dblinkname="readwrite")
Establish a connection to the database server.
executeDelayedQueries()
Trigger all queries that were registered as "delayed" queries.
setupConnections()
Establish database connections.
getTablePrefix()
Get the prefix for Elgg's tables.