Skip to content

Commit f4c913b

Browse files
committed
Added support for readonly connections
1 parent 14de4fe commit f4c913b

4 files changed

Lines changed: 74 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change Log
22

3+
### 1.5.2
4+
5+
* Added: Read/Write connection splitting support
6+
* Added: Read only connection stem settings
7+
38
### 1.5.1
49

510
* Fixed: MysqlJsonColumn now supports $decodeAsArrays

src/Repositories/MySql/MySql.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ protected function fetchMissingObjectData(Model $object, $uniqueIdentifier, $rel
107107

108108
$data = self::returnFirstRow(
109109
"SELECT * FROM `" . $table . "` WHERE `{$schema->uniqueIdentifierColumnName}` = :id",
110-
["id" => $uniqueIdentifier]
110+
["id" => $uniqueIdentifier],
111+
self::getReadOnlyConnection()
111112
);
112113

113114
if ($data != null) {
@@ -301,12 +302,13 @@ public function createCursorForCollection(RepositoryCollection $collection)
301302
$sql = preg_replace("/^SELECT /", "SELECT SQL_CALC_FOUND_ROWS ", $sql);
302303
}
303304

304-
$statement = static::executeStatement((string)$sql, $params);
305+
$connection = self::getReadOnlyConnection();
306+
$statement = static::executeStatement((string)$sql, $params, $connection);
305307

306308
$count = $statement->rowCount();
307309

308310
if ($hasLimit){
309-
$count = static::returnSingleValue("SELECT FOUND_ROWS()");
311+
$count = static::returnSingleValue("SELECT FOUND_ROWS()", [], $connection);
310312
}
311313

312314
$cursor = new MySqlCursor($statement, $this, $count, $collection->additionalColumns);

src/Repositories/PdoRepository.php

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ abstract class PdoRepository extends Repository
4444
*/
4545
protected static $defaultConnection = null;
4646

47+
protected static $readOnlyConnection = null;
48+
4749
private static $pdoParamAliasesUsed = [];
4850

4951
/**
@@ -81,11 +83,46 @@ public static function getDefaultConnection()
8183
$databaseSettings = StemSettings::singleton();
8284

8385
self::$defaultConnection = static::getConnection($databaseSettings);
86+
87+
if ($databaseSettings->stickyWriteConnection) {
88+
self::$readOnlyConnection = self::$defaultConnection;
89+
}
8490
}
8591

8692
return self::$defaultConnection;
8793
}
8894

95+
public static function getReadOnlyConnection()
96+
{
97+
if (self::$readOnlyConnection === null) {
98+
$databaseSettings = StemSettings::singleton();
99+
100+
if (
101+
// readonly port/host are different to default
102+
$databaseSettings->readOnlyHost !== $databaseSettings->host
103+
|| $databaseSettings->readOnlyPort !== $databaseSettings->port
104+
) {
105+
$readOnlySettings = clone StemSettings::singleton();
106+
$readOnlyMap = [
107+
'host' => 'readOnlyHost',
108+
'port' => 'readOnlyPort',
109+
'username' => 'readOnlyUsername',
110+
'password' => 'readOnlyPassword',
111+
];
112+
foreach ($readOnlyMap as $primaryProp => $readOnlyProp) {
113+
if ($readOnlySettings->$readOnlyProp) {
114+
$readOnlySettings->$primaryProp = $readOnlySettings->$readOnlyProp;
115+
}
116+
}
117+
self::$readOnlyConnection = static::getConnection($readOnlySettings);
118+
} else {
119+
self::$readOnlyConnection = self::getDefaultConnection();
120+
}
121+
}
122+
123+
return self::$readOnlyConnection;
124+
}
125+
89126
/**
90127
* @param StemSettings $dbSettings
91128
* @return \PDO
@@ -104,6 +141,13 @@ public static function resetDefaultConnection()
104141
self::$defaultConnection = null;
105142
}
106143

144+
/**
145+
* Discards the default connection.
146+
*/
147+
public static function resetReadOnlyConnection()
148+
{
149+
self::$readOnlyConnection = null;
150+
}
107151

108152
/**
109153
* A collection of PDO objects for each active connection.
@@ -231,7 +275,11 @@ public static function executeInsertStatement($sql, $namedParameters = [], $conn
231275
*/
232276
public static function returnSingleValue($statement, $namedParameters = [], $connection = null)
233277
{
234-
$statement = self::executeStatement($statement, $namedParameters, $connection);
278+
$statement = self::executeStatement(
279+
$statement,
280+
$namedParameters,
281+
$connection !== null ? $connection : self::getReadOnlyConnection()
282+
);
235283

236284
return $statement->fetchColumn(0);
237285
}
@@ -246,7 +294,11 @@ public static function returnSingleValue($statement, $namedParameters = [], $con
246294
*/
247295
public static function returnFirstRow($statement, $namedParameters = [], $connection = null)
248296
{
249-
$statement = self::executeStatement($statement, $namedParameters, $connection);
297+
$statement = self::executeStatement(
298+
$statement,
299+
$namedParameters,
300+
$connection !== null ? $connection : self::getReadOnlyConnection()
301+
);
250302

251303
return $statement->fetch(\PDO::FETCH_ASSOC);
252304
}

src/StemSettings.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ class StemSettings extends Settings
3232
public $password = "";
3333
public $database = "";
3434

35+
// allows connections to be split so that reads and writes
36+
public $readOnlyHost = "";
37+
public $readOnlyPort = "";
38+
public $readOnlyUsername = "";
39+
public $readOnlyPassword = "";
40+
41+
// Useful if you intend to read immediately after writing and your read only connection has lag (eg replication).
42+
// This will probably make read only connections pointless if writes happen throughout reads (eg db logging).
43+
public $stickyWriteConnection = false;
44+
3545
/**
3646
* @var \DateTimeZone
3747
*/

0 commit comments

Comments
 (0)