diff --git a/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php b/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php index 8ed679c53efe..45dbec70c809 100755 --- a/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php +++ b/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php @@ -22,6 +22,8 @@ class ilSessionStatistics { private const int SLOT_SIZE = 15; + protected static ?ilDBStatement $number_of_active_raw_sessions_statement = null; + /** * Is session statistics active at all? */ @@ -171,19 +173,16 @@ protected static function getNumberOfActiveRawSessions(int $a_time): int $ilDB = $DIC['ilDB']; - $sql = 'SELECT COUNT(*) counter FROM usr_session_stats_raw' . - ' WHERE (end_time IS NULL OR end_time >= ' . $ilDB->quote($a_time, 'integer') . ')' . - ' AND start_time <= ' . $ilDB->quote($a_time, 'integer') . - ' AND ' . $ilDB->in('type', ilSessionControl::$session_types_controlled, false, 'integer'); - $res = $ilDB->query($sql); - $row = $ilDB->fetchAssoc($res); + $statement = self::getNumberOfActiveRawSessionsPreparedStatement(); + $row = $DIC->database()->fetchAssoc($DIC->database()->execute($statement, [$a_time, $a_time])); return (int) $row['counter']; } /** * Read raw data for timespan + * @return Generator> */ - protected static function getRawData(int $a_begin, int $a_end): array + protected static function getRawData(int $a_begin, int $a_end): Generator { global $DIC; @@ -195,11 +194,9 @@ protected static function getRawData(int $a_begin, int $a_end): array ' AND ' . $ilDB->in('type', ilSessionControl::$session_types_controlled, false, 'integer') . ' ORDER BY start_time'; $res = $ilDB->query($sql); - $all = []; while ($row = $ilDB->fetchAssoc($res)) { - $all[] = $row; + yield $row; } - return $all; } /** @@ -247,25 +244,89 @@ public static function aggretateRaw(int $a_now): void } $slot = self::createNewAggregationSlot($a_now); + $prepared_statement = self::getAggregatedRawDataPreparedStatement(); + $raw_data = []; while (is_array($slot)) { - self::aggregateRawHelper($slot[0], $slot[1]); + $raw_data[] = self::aggregateRawHelper($slot[0], $slot[1]); $slot = self::createNewAggregationSlot($a_now); } + if ($raw_data !== []) { + global $DIC; + $DIC->database()->executeMultiple($prepared_statement, $raw_data); + } + // #12728 self::deleteAggregatedRaw($a_now); } + protected static function getNumberOfActiveRawSessionsPreparedStatement(): ilDbStatement + { + if (self::$number_of_active_raw_sessions_statement === null) { + global $DIC; + self::$number_of_active_raw_sessions_statement = $DIC->database()->prepare( + 'SELECT COUNT(*) counter FROM usr_session_stats_raw ' + . 'WHERE (end_time IS NULL OR end_time >= ?) ' + . 'AND start_time <= ? ' + . 'AND ' . $DIC->database()->in('type', ilSessionControl::$session_types_controlled, false, 'integer'), + [ilDBConstants::T_INTEGER, ilDBConstants::T_INTEGER] + ); + } + + return self::$number_of_active_raw_sessions_statement; + } + + protected static function getAggregatedRawDataPreparedStatement(): ilDBStatement + { + global $DIC; + return $DIC->database()->prepareManip( + 'UPDATE usr_session_stats ' + . 'SET active_min = ?, ' + . 'active_max = ?, ' + . 'active_avg = ?, ' + . 'active_end = ?, ' + . 'opened = ?, ' + . 'closed_manual = ?, ' + . 'closed_expire = ?, ' + . 'closed_login = ?, ' + . 'closed_misc = ? ' + . 'WHERE slot_begin = ? AND slot_end = ?', + [ + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER, + ilDBConstants::T_INTEGER + ] + ); + } + /** * Aggregate statistics data for one slot - * + * @return array{ + * active_min: int, + * active_max: int, + * active_avg: float|int, + * active_end: int, + * opened: int, + * closed_manual: int, + * closed_expire: int, + * closed_login: int, + * closed_misc: int, + * slot_begin: int, + * slot_end: int + * } */ - public static function aggregateRawHelper(int $a_begin, int $a_end): void + public static function aggregateRawHelper(int $a_begin, int $a_end): array { global $DIC; - $ilDB = $DIC['ilDB']; - // "relevant" closing types $separate_closed = [ ilSession::SESSION_CLOSE_USER, @@ -355,26 +416,19 @@ public static function aggregateRawHelper(int $a_begin, int $a_end): void } unset($events); - // save aggregated data - $fields = [ - 'active_min' => ['integer', $active_min], - 'active_max' => ['integer', $active_max], - 'active_avg' => ['integer', $active_avg], - 'active_end' => ['integer', $active_end], - 'opened' => ['integer', $opened_counter], - 'closed_manual' => ['integer', (int) ($closed_counter[ilSession::SESSION_CLOSE_USER] ?? 0)], - 'closed_expire' => ['integer', (int) ($closed_counter[ilSession::SESSION_CLOSE_EXPIRE] ?? 0)], - 'closed_login' => ['integer', (int) ($closed_counter[ilSession::SESSION_CLOSE_LOGIN] ?? 0)], - 'closed_misc' => ['integer', (int) ($closed_counter[0] ?? 0)], + return [ + 'active_min' => $active_min, + 'active_max' => $active_max, + 'active_avg' => $active_avg, + 'active_end' => $active_end, + 'opened' => $opened_counter, + 'closed_manual' => (int) ($closed_counter[ilSession::SESSION_CLOSE_USER] ?? 0), + 'closed_expire' => (int) ($closed_counter[ilSession::SESSION_CLOSE_EXPIRE] ?? 0), + 'closed_login' => (int) ($closed_counter[ilSession::SESSION_CLOSE_LOGIN] ?? 0), + 'closed_misc' => (int) ($closed_counter[0] ?? 0), + 'slot_begin' => $a_begin, + 'slot_end' => $a_end, ]; - $ilDB->update( - 'usr_session_stats', - $fields, - [ - 'slot_begin' => ['integer', $a_begin], - 'slot_end' => ['integer', $a_end] - ] - ); } /**