Skip to content

Commit c80957c

Browse files
committed
Share PDO object between multiple Database instances
This improves performance by a lot. This is ugly, but this is the best we can do without a proper container and dependency managment.
1 parent 2fb6113 commit c80957c

File tree

1 file changed

+96
-92
lines changed

1 file changed

+96
-92
lines changed

lib/Database.php

Lines changed: 96 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class Database
7474
*********************************************************************************/
7575

7676
/** @var PDO PHP Data Object */
77-
private $pdo = null;
77+
private static $pdo = null;
7878

7979
/** @var bool */
8080
private $transaction_active = false;
@@ -102,101 +102,105 @@ public function __construct()
102102
{
103103
global $config;
104104

105-
// connect with database
106-
try {
107-
switch ($config['db']['type']) {
108-
case 'mysql': // MySQL
109-
//Split hostname in adress and port
110-
$host = parse_url($config['db']['host'], PHP_URL_HOST);
111-
$port = parse_url($config['db']['host'], PHP_URL_PORT);
112-
113-
if($host == null || $port == null)
114-
{
115-
$host = $config['db']['host'];
116-
$port = "3306";
117-
}
105+
if(self::$pdo === null) {
106+
// connect with database
107+
try {
108+
switch ($config['db']['type']) {
109+
case 'mysql': // MySQL
110+
//Split hostname in adress and port
111+
$host = parse_url($config['db']['host'], PHP_URL_HOST);
112+
$port = parse_url($config['db']['host'], PHP_URL_PORT);
113+
114+
if($host == null || $port == null)
115+
{
116+
$host = $config['db']['host'];
117+
$port = "3306";
118+
}
118119

119-
//If a unix socket is given in $dbo
120-
if (isPathabsoluteAndUnix($config['db']['host'], false)) {
121-
$this->pdo = new PDO(
122-
'mysql:unix_socket='.$config['db']['host'].';dbname='.$config['db']['name'].';charset=utf8',
123-
$config['db']['user'],
124-
$config['db']['password'],
125-
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
126-
PDO::ATTR_PERSISTENT => false)
127-
);
128-
} else {
129-
//Check if a space fix is activated.
130-
if ($config['db']['space_fix'] == false) {
131-
$this->pdo = new PDO(
132-
'mysql:host='.$host.';port='.$port.';dbname='.$config['db']['name'].';charset=utf8',
133-
$config['db']['user'],
134-
$config['db']['password'],
135-
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
136-
PDO::ATTR_PERSISTENT => false)
137-
);
138-
} else { //Include space between mysql and host in dsn string.
139-
$this->pdo = new PDO(
140-
'mysql: host='.$host.';port='.$port.';dbname='.$config['db']['name'].';charset=utf8',
120+
//If a unix socket is given in $dbo
121+
if (isPathabsoluteAndUnix($config['db']['host'], false)) {
122+
self::$pdo = new PDO(
123+
'mysql:unix_socket='.$config['db']['host'].';dbname='.$config['db']['name'].';charset=utf8',
141124
$config['db']['user'],
142125
$config['db']['password'],
143126
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
144127
PDO::ATTR_PERSISTENT => false)
145128
);
129+
} else {
130+
//Check if a space fix is activated.
131+
if ($config['db']['space_fix'] == false) {
132+
self::$pdo = new PDO(
133+
'mysql:host='.$host.';port='.$port.';dbname='.$config['db']['name'].';charset=utf8',
134+
$config['db']['user'],
135+
$config['db']['password'],
136+
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
137+
PDO::ATTR_PERSISTENT => false)
138+
);
139+
} else { //Include space between mysql and host in dsn string.
140+
self::$pdo = new PDO(
141+
'mysql: host='.$host.';port='.$port.';dbname='.$config['db']['name'].';charset=utf8',
142+
$config['db']['user'],
143+
$config['db']['password'],
144+
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
145+
PDO::ATTR_PERSISTENT => false)
146+
);
147+
}
146148
}
147-
}
148149

149-
break;
150+
break;
150151

151-
//case 'sqlite': // SQLite 3
152-
//case 'sqlite2': //SQLite 2
153-
//$filename = realpath($config['db']['name']) ? realpath($config['db']['name']) : $config['db']['name'];
154-
//$this->pdo = new PDO($config['db']['type'].':'.$filename, NULL, NULL);
155-
break;
152+
//case 'sqlite': // SQLite 3
153+
//case 'sqlite2': //SQLite 2
154+
//$filename = realpath($config['db']['name']) ? realpath($config['db']['name']) : $config['db']['name'];
155+
//self::$pdo = new PDO($config['db']['type'].':'.$filename, NULL, NULL);
156+
break;
156157

157-
default:
158-
throw new Exception(_('Unbekannter Datenbanktyp: "').$config['db']['type'].'"');
159-
break;
158+
default:
159+
throw new Exception(_('Unbekannter Datenbanktyp: "').$config['db']['type'].'"');
160+
break;
161+
}
162+
163+
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
164+
self::$pdo->exec("SET SQL_MODE='".$this->sql_mode."'");
165+
} catch (PDOException $e) {
166+
debug(
167+
'error',
168+
'Konnte nicht mit Datenbank verbinden: '.$e->getMessage(),
169+
__FILE__,
170+
__LINE__,
171+
__METHOD__
172+
);
173+
174+
throw new Exception(_("Es konnte nicht mit der Datenbank verbunden werden! \n".
175+
'Überprüfen Sie, ob die Zugangsdaten korrekt sind.') . "\n\n".
176+
_("Details: ") . $e->getMessage());
160177
}
161178

162-
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
163-
$this->pdo->exec("SET SQL_MODE='".$this->sql_mode."'");
164-
} catch (PDOException $e) {
165-
debug(
166-
'error',
167-
'Konnte nicht mit Datenbank verbinden: '.$e->getMessage(),
168-
__FILE__,
169-
__LINE__,
170-
__METHOD__
171-
);
172-
173-
throw new Exception(_("Es konnte nicht mit der Datenbank verbunden werden! \n".
174-
'Überprüfen Sie, ob die Zugangsdaten korrekt sind.') . "\n\n".
175-
_("Details: ") . $e->getMessage());
176-
}
177-
178-
// make some checks
179-
if ($this->getCurrentVersion() > 12) {
180-
// Check if all tables uses the engine "InnoDB" (this is very important for all database versions greater than 12!)
181-
// Without InnoDB, transactions are not supported!
182-
$wrong_engine_tables = array();
183-
$query_data = $this->query('SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA=?', array($config['db']['name']));
184-
foreach ($query_data as $row) {
185-
if (strtoupper($row['ENGINE']) != 'INNODB') {
186-
$wrong_engine_tables[] = '"'.$row['TABLE_NAME'].'" ('.$row['ENGINE'].')';
179+
// make some checks
180+
if ($this->getCurrentVersion() > 12) {
181+
// Check if all tables uses the engine "InnoDB" (this is very important for all database versions greater than 12!)
182+
// Without InnoDB, transactions are not supported!
183+
$wrong_engine_tables = array();
184+
$query_data = $this->query('SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA=?', array($config['db']['name']));
185+
foreach ($query_data as $row) {
186+
if (strtoupper($row['ENGINE']) != 'INNODB') {
187+
$wrong_engine_tables[] = '"'.$row['TABLE_NAME'].'" ('.$row['ENGINE'].')';
188+
}
189+
}
190+
191+
if (count($wrong_engine_tables) > 0) {
192+
throw new Exception(_("Die folgenden MySQL Tabellen haben eine falsche Speicherengine (benötigt wird \"InnoDB\"): \n").
193+
implode(', ', $wrong_engine_tables));
187194
}
188195
}
189196

190-
if (count($wrong_engine_tables) > 0) {
191-
throw new Exception(_("Die folgenden MySQL Tabellen haben eine falsche Speicherengine (benötigt wird \"InnoDB\"): \n").
192-
implode(', ', $wrong_engine_tables));
197+
if (PDBDebugBar::isActivated()) {
198+
self::$pdo = new TraceablePDO(self::$pdo);
199+
PDBDebugBar::getInstance()->registerPDO(self::$pdo);
193200
}
194201
}
195202

196-
if (PDBDebugBar::isActivated()) {
197-
$this->pdo = new TraceablePDO($this->pdo);
198-
PDBDebugBar::getInstance()->registerPDO($this->pdo);
199-
}
203+
200204
}
201205

202206
/********************************************************************************
@@ -420,15 +424,15 @@ public function update($continue_last_attempt = true)
420424
}
421425

422426
try {
423-
$this->pdo->beginTransaction();
424-
$this->pdo->exec($query);
425-
if($this->pdo->inTransaction()) {
426-
$this->pdo->commit();
427+
self::$pdo->beginTransaction();
428+
self::$pdo->exec($query);
429+
if(self::$pdo->inTransaction()) {
430+
self::$pdo->commit();
427431
}
428432
$add_log(sprintf(_('Schritt: %s ...OK'), $query));
429433
} catch (PDOException $e) {
430434
try {
431-
$this->pdo->rollback();
435+
self::$pdo->rollback();
432436
} catch (PDOException $e2) {
433437
} // rollback last query, ignore exceptions
434438
//Ignore "Column already exists:" errors
@@ -447,7 +451,7 @@ public function update($continue_last_attempt = true)
447451
if (! $error) {
448452
try {
449453
if ($current != 0) { // The DB Version was set in the first update step, so we mustn't set the version here!!
450-
$pdo_statement = $this->pdo->prepare("UPDATE internal SET keyValue=? WHERE keyName='dbVersion'");
454+
$pdo_statement = self::$pdo->prepare("UPDATE internal SET keyValue=? WHERE keyName='dbVersion'");
451455
$pdo_statement->bindValue(1, $current + 1);
452456
$pdo_statement->execute();
453457
}
@@ -590,7 +594,7 @@ public function beginTransaction()
590594
// start a new transaction
591595
try {
592596
$this->active_transaction_id++;
593-
$this->pdo->beginTransaction();
597+
self::$pdo->beginTransaction();
594598
$this->transaction_active = true;
595599
return $this->active_transaction_id;
596600
} catch (PDOException $e) {
@@ -628,13 +632,13 @@ public function commit($transaction_id)
628632
// all OK, we commit the transaction
629633
try {
630634
$this->transaction_active = false;
631-
if ($this->pdo->inTransaction()) {
632-
$this->pdo->commit();
635+
if (self::$pdo->inTransaction()) {
636+
self::$pdo->commit();
633637
}
634638
} catch (PDOException $e) {
635639
try {
636640
// try to roll back
637-
$this->pdo->rollback();
641+
self::$pdo->rollback();
638642
} catch (PDOException $e) {
639643
}
640644

@@ -658,7 +662,7 @@ public function rollback()
658662

659663
try {
660664
$this->transaction_active = false;
661-
$this->pdo->rollback();
665+
self::$pdo->rollback();
662666
} catch (PDOException $e) {
663667
return false;
664668
}
@@ -705,7 +709,7 @@ public function execute($query, $values = array())
705709
}
706710

707711
try {
708-
$pdo_statement = $this->pdo->prepare($query);
712+
$pdo_statement = self::$pdo->prepare($query);
709713

710714
if (! $pdo_statement) {
711715
debug('error', 'PDO Prepare Fehler!', __FILE__, __LINE__, __METHOD__);
@@ -734,7 +738,7 @@ public function execute($query, $values = array())
734738
}
735739

736740
if ($is_insert_statement == true) {
737-
$result = $this->pdo->lastInsertId('id');
741+
$result = self::$pdo->lastInsertId('id');
738742
} else {
739743
$result = $pdo_statement->rowCount();
740744
}
@@ -778,7 +782,7 @@ public function query($query, $values = array(), $fetch_style = PDO::FETCH_ASSOC
778782
}
779783

780784
try {
781-
$pdo_statement = $this->pdo->prepare($query);
785+
$pdo_statement = self::$pdo->prepare($query);
782786

783787
if (! $pdo_statement) {
784788
debug('error', _('PDO Prepare Fehler!'), __FILE__, __LINE__, __METHOD__);

0 commit comments

Comments
 (0)