diff options
| author | winter | 2025-01-23 20:54:10 +0000 |
|---|---|---|
| committer | winter | 2025-01-23 20:54:10 +0000 |
| commit | 8a83b9092b0bf0b6f77d3504b522d186d8e57580 (patch) | |
| tree | f830a5c0e20dcf2ae691e64bbcc8fa83a7d96194 | |
| parent | 18a66a2cab290a82f1099e538ae70e5e730d724d (diff) | |
cache model lookups
| -rw-r--r-- | Digitigrade/Db.php | 2 | ||||
| -rw-r--r-- | Digitigrade/Model.php | 56 | ||||
| -rw-r--r-- | index.php | 2 |
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 */ @@ -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(); |
