From 08e4128ddce9dcffe0a4224ae57ad664609935b2 Mon Sep 17 00:00:00 2001
From: Jonas Kohl
Date: Sun, 22 Dec 2024 13:06:42 +0100
Subject: Add statistics

---
 src/application/appdef.php                |  2 +-
 src/application/messages/de.msg           |  6 +++++
 src/application/mystic/forum/Database.php | 38 ++++++++++++++++++++++---------
 src/application/templates/old/base.twig   |  8 +++++++
 4 files changed, 42 insertions(+), 12 deletions(-)

(limited to 'src/application')

diff --git a/src/application/appdef.php b/src/application/appdef.php
index b08bf14..6c69ee8 100644
--- a/src/application/appdef.php
+++ b/src/application/appdef.php
@@ -1,3 +1,3 @@
 <?php
 
-const MYSTICBB_VERSION = "0.6.3";
+const MYSTICBB_VERSION = "0.7.0";
diff --git a/src/application/messages/de.msg b/src/application/messages/de.msg
index b73a6fe..3ce96d4 100644
--- a/src/application/messages/de.msg
+++ b/src/application/messages/de.msg
@@ -534,3 +534,9 @@ metadata({
 
 : "Log out"
 = "Abmelden"
+
+: "Number of database queries: %count%"
+= "Anzahl der Datenbankabfragen: %count%"
+
+: "Page generation took %dur% second(s)"
+= "Seitenaufbau dauerte %dur% Sekunde(n)"
diff --git a/src/application/mystic/forum/Database.php b/src/application/mystic/forum/Database.php
index 632b2d6..1c2d710 100644
--- a/src/application/mystic/forum/Database.php
+++ b/src/application/mystic/forum/Database.php
@@ -17,12 +17,14 @@ use mystic\forum\orm\Entity;
 use mystic\forum\utils\ArrayUtils;
 use mystic\forum\utils\StringUtils;
 use PgSql\Connection;
+use PgSql\Result;
 use ReflectionClass;
 use ReflectionNamedType;
 use ReflectionProperty;
 
 class Database {
     private Connection $connection;
+    private int $queryCount = 0;
 
     private const PRIMARY_KEY = 0b0000_0001;
     private const NOT_NULL    = 0b0000_0010;
@@ -38,6 +40,20 @@ class Database {
         return hex2bin(substr($enc, 2));
     }
 
+    public function getQueryCount(): int {
+        return $this->queryCount;
+    }
+
+    protected function queryParams(string $query, array $params): Result|false {
+        ++$this->queryCount;
+        return \pg_query_params  ($this->connection, $query, $params);
+    }
+
+    protected function query(string $query): Result|false {
+        ++$this->queryCount;
+        return \pg_query  ($this->connection, $query);
+    }
+
     public static function generateId(int $length = 64): string {
         static $charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
         static $charsetLength = strlen($charset);
@@ -323,7 +339,7 @@ class Database {
         foreach (self::getColumnValues($entity, $cols) as $i => $value)
             $values[$i] = $value;
         $query = "INSERT INTO $tableName VALUES (" . implode(",", ArrayUtils::fill(fn($i) => "$" . ($i + 1), count($cols))) . ");";
-        $result = \pg_query_params($this->connection, $query, $values);
+        $result = $this->queryParams($query, $values);
         if ($result === false)
             throw new \RuntimeException("Insert failed: " . \pg_last_error($this->connection));
         \pg_free_result($result);
@@ -338,7 +354,7 @@ class Database {
         if ($primaryCol === null)
             throw new \RuntimeException("Fetching an entity requires a primary key column to be specified");
         $query = "SELECT * FROM $tableName WHERE $primaryCol = \$1 LIMIT 1;";
-        $result = \pg_query_params($this->connection, $query, [ $entity->{$cols[$primaryCol]["propertyName"]} ]);
+        $result = $this->queryParams($query, [ $entity->{$cols[$primaryCol]["propertyName"]} ]);
         if ($result === false)
             throw new \RuntimeException("Fetch failed: " . \pg_last_error($this->connection));
         $row = \pg_fetch_assoc($result);
@@ -371,7 +387,7 @@ class Database {
         }
         $whereClause = implode(" AND ", $whereClause);
         $query = "SELECT * FROM $tableName WHERE $whereClause LIMIT 1;";
-        $result = \pg_query_params($this->connection, $query, $columnValues);
+        $result = $this->queryParams($query, $columnValues);
         if ($result === false)
             throw new \RuntimeException("Fetch failed: " . \pg_last_error($this->connection));
         $row = \pg_fetch_assoc($result);
@@ -388,7 +404,7 @@ class Database {
         $reflClass = new ReflectionClass($entityClassName);
         $cols = self::getColumns($reflClass);
         $query = "SELECT * FROM $tableName;";
-        $result = \pg_query($this->connection, $query);
+        $result = $this->query($query);
         if ($result === false)
             throw new \RuntimeException("Fetch failed: " . \pg_last_error($this->connection));
         $items = [];
@@ -408,9 +424,9 @@ class Database {
         $cols = self::getColumns($reflClass);
         $query = "SELECT * FROM $tableName $customQuery;";
         if ($customQueryParams === null)
-            $result = \pg_query($this->connection, $query);
+            $result = $this->query($query);
         else
-            $result = \pg_query_params($this->connection, $query, $customQueryParams);
+            $result = $this->queryParams($query, $customQueryParams);
         if ($result === false)
             throw new \RuntimeException("Fetch failed: " . \pg_last_error($this->connection));
         $items = [];
@@ -426,9 +442,9 @@ class Database {
 
     public function execCustomQuery(string $query, ?array $customQueryParams = null, ?string $entityClassName = null): array {
         if ($customQueryParams === null)
-            $result = \pg_query($this->connection, $query);
+            $result = $this->query($query);
         else
-            $result = \pg_query_params($this->connection, $query, $customQueryParams);
+            $result = $this->queryParams($query, $customQueryParams);
         if ($result === false)
             throw new \RuntimeException("Query failed: " . \pg_last_error($this->connection));
         $cols = null;
@@ -460,7 +476,7 @@ class Database {
         if ($primaryCol === null)
             throw new \RuntimeException("Deleting an entity requires a primary key column to be specified");
         $query = "DELETE FROM $tableName WHERE $primaryCol = \$1;";
-        $result = \pg_query_params($this->connection, $query, [ $entity->{$cols[$primaryCol]["propertyName"]} ]);
+        $result = $this->queryParams($query, [ $entity->{$cols[$primaryCol]["propertyName"]} ]);
         if ($result === false)
             throw new \RuntimeException("Deletion failed: " . \pg_last_error($this->connection));
         $num_affected_rows = \pg_affected_rows($result);
@@ -489,7 +505,7 @@ class Database {
         $colDef = implode(", ", $qCols);
         $query = "UPDATE $tableName SET $colDef WHERE $primaryCol = \$1;";
         //$theCols = ArrayUtils::assocFromPairs($filteredCols);
-        $result = \pg_query_params($this->connection, $query, self::getColumnValues($entity, $cols));
+        $result = $this->queryParams($query, self::getColumnValues($entity, $cols));
         if ($result === false)
             throw new \RuntimeException("Update failed: " . \pg_last_error($this->connection));
         $num_affected_rows = \pg_affected_rows($result);
@@ -503,7 +519,7 @@ class Database {
         $query = "CREATE TABLE IF NOT EXISTS $tableName ();";
         foreach ($colDefs as $colDef)
             $query .= "ALTER TABLE $tableName ADD COLUMN IF NOT EXISTS $colDef;";
-        $result = \pg_query($this->connection, $query);
+        $result = $this->query($query);
         if ($result === false)
             throw new \RuntimeException("Table creation failed: " . \pg_last_error($this->connection));
         \pg_free_result($result);
diff --git a/src/application/templates/old/base.twig b/src/application/templates/old/base.twig
index bdad515..bdb9768 100644
--- a/src/application/templates/old/base.twig
+++ b/src/application/templates/old/base.twig
@@ -73,6 +73,14 @@
         &copy; {{ "now"|date("Y") }} {{ g.env.MYSTIC_FORUM_COPYRIGHT|default(g.env.MYSTIC_FORUM_TITLE)|default("Forum") }}.
         Powered by <a href="https://git.jkohl.link/mystic-forum.git/tag/?h=v{{ constant("MYSTICBB_VERSION")|url_encode }}">mysticBB v{{ constant("MYSTICBB_VERSION") }}</a>.
     </td>
+    <td align="center">
+        {{ __("Page generation took %dur% second(s)", {
+            dur: getRunTime()|round(3),
+        }) }}<br>
+        {{ __("Number of database queries: %count%", {
+            count: getQueryCount(),
+        }) }}
+    </td>
     <td align="right">
         <table><tr><td>
         <form action="?_action=settheme" method="post">
-- 
cgit v1.2.3