21 private $dbLinks = array();
24 private $queryCount = 0;
37 private $queryCache = null;
42 private $queryCacheSize = 50;
59 private $delayedQueries = array();
62 private $installed =
false;
78 $this->logger = $logger;
79 $this->config = $config;
81 $this->tablePrefix = $config->getTablePrefix();
83 $this->enableQueryCache();
99 if (isset($this->dbLinks[
$type])) {
100 return $this->dbLinks[
$type];
101 }
else if (isset($this->dbLinks[
'readwrite'])) {
102 return $this->dbLinks[
'readwrite'];
104 $this->setupConnections();
105 return $this->getLink($type);
119 if ($this->config->isDatabaseSplit()) {
120 $this->establishLink(
'read');
121 $this->establishLink(
'write');
123 $this->establishLink(
'readwrite');
141 $conf = $this->config->getConnectionConfig($dblinkname);
144 $this->dbLinks[$dblinkname] = mysql_connect($conf[
'host'], $conf[
'user'], $conf[
'password'],
true);
145 if (!$this->dbLinks[$dblinkname]) {
146 $msg =
"Elgg couldn't connect to the database using the given credentials. Check the settings file.";
147 throw new \DatabaseException($msg);
150 if (!mysql_select_db($conf[
'database'], $this->dbLinks[$dblinkname])) {
151 $msg =
"Elgg couldn't select the database '{$conf['database']}'. Please check that the database is created and you have access to it.";
152 throw new \DatabaseException($msg);
156 mysql_query(
"SET NAMES utf8", $this->dbLinks[$dblinkname]);
175 public function getData($query, $callback =
'') {
176 return $this->getResults($query, $callback,
false);
193 return $this->getResults($query, $callback,
true);
209 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
211 $dblink = $this->getLink(
'write');
213 $this->invalidateQueryCache();
215 if ($this->executeQuery(
"$query", $dblink)) {
216 return mysql_insert_id($dblink);
235 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
237 $dblink = $this->getLink(
'write');
239 $this->invalidateQueryCache();
241 if ($this->executeQuery(
"$query", $dblink)) {
243 return mysql_affected_rows($dblink);
264 $this->logger->log(
"DB query $query", \
Elgg\Logger::INFO);
266 $dblink = $this->getLink(
'write');
268 $this->invalidateQueryCache();
270 if ($this->executeQuery(
"$query", $dblink)) {
271 return mysql_affected_rows($dblink);
291 if (is_string($callback)) {
294 if (is_object($callback)) {
295 return spl_object_hash($callback) .
"::__invoke";
297 if (is_array($callback)) {
298 if (is_string($callback[0])) {
299 return "{$callback[0]}::{$callback[1]}";
301 return spl_object_hash($callback[0]) .
"::{$callback[1]}";
319 protected function getResults($query, $callback = null, $single =
false) {
324 $query_id = (int)$single . $query .
'|';
326 $is_callable = is_callable($callback);
328 $query_id .= $this->fingerprintCallback($callback);
334 $is_callable =
false;
337 $hash = md5($query_id);
340 if ($this->queryCache) {
341 if (isset($this->queryCache[$hash])) {
342 $this->logger->log(
"DB query $query results returned from cache (hash: $hash)", \
Elgg\Logger::INFO);
343 return $this->queryCache[$hash];
347 $dblink = $this->getLink(
'read');
350 if (
$result = $this->executeQuery(
"$query", $dblink)) {
353 $row = call_user_func($callback,
$row);
366 $this->logger->log(
"DB query $query returned no results.", \
Elgg\Logger::INFO);
370 if ($this->queryCache) {
371 $this->queryCache[$hash] =
$return;
372 $this->logger->log(
"DB query $query results cached (hash: $hash)", \
Elgg\Logger::INFO);
393 if ($query == null) {
394 throw new \DatabaseException(
"Query cannot be null");
397 if (!is_resource($dblink)) {
398 throw new \DatabaseException(
"Connection to database was lost.");
403 $result = mysql_query($query, $dblink);
405 if (mysql_errno($dblink)) {
406 throw new \DatabaseException(mysql_error($dblink) .
"\n\n QUERY: $query");
437 $script = file_get_contents($scriptlocation);
443 $script = preg_replace(
'/^(?:--|#) .*$/m',
'', $script);
446 $sql_statements = preg_split(
'/;[\n\r]+/',
"$script\n");
448 foreach ($sql_statements as $statement) {
449 $statement = trim($statement);
450 $statement = str_replace(
"prefix_", $this->tablePrefix, $statement);
451 if (!empty($statement)) {
453 $this->updateData($statement);
455 $errors[] = $e->getMessage();
459 if (!empty($errors)) {
461 foreach ($errors as
$error) {
462 $errortxt .=
" {$error};";
465 $msg =
"There were a number of issues: " . $errortxt;
466 throw new \DatabaseException($msg);
469 $msg =
"Elgg couldn't find the requested database script at " . $scriptlocation .
".";
470 throw new \DatabaseException($msg);
494 $delayed_query = array();
495 $delayed_query[
'q'] = $query;
496 $delayed_query[
'l'] =
$type;
499 $this->delayedQueries[] = $delayed_query;
515 foreach ($this->delayedQueries as $query_details) {
517 $link = $query_details[
'l'];
519 if ($link ==
'read' || $link ==
'write') {
520 $link = $this->getLink($link);
521 } elseif (!is_resource($link)) {
522 $msg =
"Link for delayed query not valid resource or db_link type. Query: {$query_details['q']}";
523 $this->logger->log($msg, \
Elgg\Logger::WARNING);
526 $result = $this->executeQuery($query_details[
'q'], $link);
528 if ((isset($query_details[
'h'])) && (is_callable($query_details[
'h']))) {
546 if ($this->config->isQueryCacheEnabled() && $this->queryCache === null) {
548 $this->queryCache = new \Elgg\Cache\LRUCache($this->queryCacheSize);
561 $this->queryCache = null;
570 if ($this->queryCache) {
571 $this->queryCache->clear();
572 $this->logger->log(
"Query cache invalidated", \
Elgg\Logger::INFO);
589 $dblink = $this->getLink(
'read');
590 mysql_query(
"SELECT value FROM {$this->tablePrefix}datalists WHERE name = 'installed'", $dblink);
591 if (mysql_errno($dblink) > 0) {
592 throw new \DatabaseException();
595 throw new \InstallationException(
"Unable to handle this request. This site is not configured or the database is down.");
607 return $this->queryCount;
616 return $this->tablePrefix;
629 if ($signed ===
false) {
647 if (isset($this->dbLinks[
'read'])) {
648 return mysql_real_escape_string(
$value, $this->dbLinks[
'read']);
651 return mysql_real_escape_string(
$value);
662 return mysql_get_server_info($this->getLink(
$type));
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.
getServerVersion($type)
Get the server version number.
executeDelayedQueries()
Trigger all queries that were registered as "delayed" queries.
setupConnections()
Establish database connections.
getTablePrefix()
Get the prefix for Elgg's tables.