aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorwinter2025-01-23 20:54:10 +0000
committerwinter2025-01-23 20:54:10 +0000
commit8a83b9092b0bf0b6f77d3504b522d186d8e57580 (patch)
treef830a5c0e20dcf2ae691e64bbcc8fa83a7d96194
parent18a66a2cab290a82f1099e538ae70e5e730d724d (diff)
cache model lookups
-rw-r--r--Digitigrade/Db.php2
-rw-r--r--Digitigrade/Model.php56
-rw-r--r--index.php2
3 files changed, 54 insertions, 6 deletions
diff --git a/Digitigrade/Db.php b/Digitigrade/Db.php
index c9f9df9..8ee23b9 100644
--- a/Digitigrade/Db.php
+++ b/Digitigrade/Db.php
@@ -1,8 +1,6 @@
<?php
namespace Digitigrade;
-use Digitigrade\Model\Actor;
-
class Db extends Singleton {
private const INIT_SCHEMA_PATH = __DIR__ . '/../schema.sql';
diff --git a/Digitigrade/Model.php b/Digitigrade/Model.php
index 71cfa5c..6a4fe27 100644
--- a/Digitigrade/Model.php
+++ b/Digitigrade/Model.php
@@ -6,6 +6,9 @@ use Digitigrade\Model\FetchableModel;
abstract class Model {
private bool $saved = false;
+ protected static array $cachedLookups = [];
+ private static bool $memoEnabled = false;
+
protected function setOwnerId(int $id) {
}
@@ -148,9 +151,22 @@ abstract class Model {
$className = $classNameParts[count($classNameParts) - 1];
$tableName = self::mangleName($className);
- $stmt = Db::getInstance()->getPdo()->prepare("SELECT * FROM $tableName WHERE $whereClause LIMIT 1");
+ $query = "SELECT * FROM $tableName WHERE $whereClause LIMIT 1";
+
+ if (self::$memoEnabled) {
+ $memoKey = $query . implode('~~~', $parameters);
+ if (isset(self::$cachedLookups[$memoKey]))
+ return self::$cachedLookups[$memoKey];
+ }
+
+ $stmt = Db::getInstance()->getPdo()->prepare($query);
$stmt->execute($parameters);
- return static::fromDbRow($stmt->fetch(\PDO::FETCH_ASSOC));
+
+ $result = static::fromDbRow($stmt->fetch(\PDO::FETCH_ASSOC));
+ if (self::$memoEnabled) {
+ self::$cachedLookups[$memoKey] = $result;
+ }
+ return $result;
}
public static function findAllWhere(
@@ -171,11 +187,23 @@ abstract class Model {
if ($limit != null) {
$query .= " LIMIT $limit OFFSET $offset";
}
+
+ if (self::$memoEnabled) {
+ $memoKey = $query . implode('~~~', $parameters);
+ if (isset(self::$cachedLookups[$memoKey]))
+ return self::$cachedLookups[$memoKey];
+ }
+
$stmt = Db::getInstance()->getPdo()->prepare($query);
$stmt->execute($parameters);
- return array_map(function ($row) {
+
+ $result = array_map(function ($row) {
return static::fromDbRow($row);
}, $stmt->fetchAll(\PDO::FETCH_ASSOC));
+ if (self::$memoEnabled) {
+ self::$cachedLookups[$memoKey] = $result;
+ }
+ return $result;
}
public static function findAll(): array {
@@ -189,9 +217,21 @@ abstract class Model {
$tableName = self::mangleName($className);
$query = "SELECT count(*) FROM $tableName WHERE $whereClause";
+
+ if (self::$memoEnabled) {
+ $memoKey = $query . implode('~~~', $parameters);
+ if (isset(self::$cachedLookups[$memoKey]))
+ return self::$cachedLookups[$memoKey];
+ }
+
$stmt = Db::getInstance()->getPdo()->prepare($query);
$stmt->execute($parameters);
- return $stmt->fetchColumn(0);
+
+ $result = $stmt->fetchColumn(0);
+ if (self::$memoEnabled) {
+ self::$cachedLookups[$memoKey] = $result;
+ }
+ return $result;
}
public static function count(): int {
@@ -289,6 +329,14 @@ abstract class Model {
}
/**
+ * Enables caching of lookups for all Models.
+ * @return void
+ */
+ public static function enableMemoisation() {
+ self::$memoEnabled = true;
+ }
+
+ /**
* Converts the model to an opaque string, to be used for equality checking or debugging purposes only.
* @return string
*/
diff --git a/index.php b/index.php
index fe0357d..4a2c2be 100644
--- a/index.php
+++ b/index.php
@@ -15,4 +15,6 @@ $lang = get_ui_language();
header('Content-Language: ' . str_replace('_', '-', $lang));
Digitigrade\Text::setDefaultLanguage($lang);
+Digitigrade\Model::enableMemoisation();
+
Digitigrade\Router::getInstance()->processRequest();