2023-07-28 23:17:33 +00:00
|
|
|
<?php
|
|
|
|
namespace Misuzu\Counters;
|
|
|
|
|
|
|
|
use InvalidArgumentException;
|
|
|
|
use Index\Data\DbStatementCache;
|
|
|
|
use Index\Data\DbTools;
|
|
|
|
use Index\Data\IDbConnection;
|
|
|
|
use Misuzu\Pagination;
|
|
|
|
|
|
|
|
// insert increment and decrement calls in places someday
|
|
|
|
|
|
|
|
class Counters {
|
|
|
|
private DbStatementCache $cache;
|
|
|
|
|
|
|
|
public function __construct(IDbConnection $dbConn) {
|
|
|
|
$this->cache = new DbStatementCache($dbConn);
|
|
|
|
}
|
|
|
|
|
|
|
|
private const GET_COUNTERS_SORT = [
|
|
|
|
'name' => 'counter_name',
|
|
|
|
'value' => 'counter_value',
|
|
|
|
'updated' => 'counter_updated',
|
|
|
|
];
|
|
|
|
|
|
|
|
public function getCounters(
|
|
|
|
?string $orderBy = null,
|
|
|
|
?Pagination $pagination = null
|
2024-02-07 00:04:45 +00:00
|
|
|
): iterable {
|
2023-07-28 23:17:33 +00:00
|
|
|
$hasOrderBy = $orderBy !== null;
|
|
|
|
$hasPagination = $pagination !== null;
|
|
|
|
|
|
|
|
$query = 'SELECT counter_name, counter_value, UNIX_TIMESTAMP(counter_updated) FROM msz_counters';
|
|
|
|
if($hasOrderBy) {
|
|
|
|
if(!array_key_exists($orderBy, self::GET_COUNTERS_SORT))
|
|
|
|
throw new InvalidArgumentException('Invalid sort specified.');
|
|
|
|
|
|
|
|
$query .= ' ORDER BY ' . self::GET_COUNTERS_SORT[$orderBy];
|
|
|
|
}
|
|
|
|
if($hasPagination)
|
|
|
|
$query .= ' LIMIT ? OFFSET ?';
|
|
|
|
|
|
|
|
$args = 0;
|
|
|
|
$stmt = $this->cache->get($query);
|
|
|
|
if($hasPagination) {
|
|
|
|
$stmt->addParameter(++$args, $pagination->getRange());
|
|
|
|
$stmt->addParameter(++$args, $pagination->getOffset());
|
|
|
|
}
|
|
|
|
$stmt->execute();
|
|
|
|
|
2024-02-07 00:04:45 +00:00
|
|
|
return $stmt->getResult()->getIterator(CounterInfo::fromResult(...));
|
2023-07-28 23:17:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function get(array|string $names): array|int {
|
|
|
|
if(is_string($names)) {
|
|
|
|
$returnFirst = true;
|
|
|
|
$names = [$names];
|
|
|
|
} else $returnFirst = false;
|
|
|
|
|
|
|
|
$args = 0;
|
|
|
|
$stmt = $this->cache->get(sprintf(
|
|
|
|
'SELECT counter_name, counter_value FROM msz_counters WHERE counter_name IN (%s)',
|
|
|
|
DbTools::prepareListString($names)
|
|
|
|
));
|
|
|
|
foreach($names as $name)
|
|
|
|
$stmt->addParameter(++$args, (string)$name);
|
|
|
|
$stmt->execute();
|
|
|
|
|
|
|
|
$values = [];
|
|
|
|
$result = $stmt->getResult();
|
|
|
|
|
|
|
|
while($result->next())
|
|
|
|
$values[$result->getString(0)] = $result->getInteger(1);
|
|
|
|
|
|
|
|
return $returnFirst ? $values[array_key_first($values)] : $values;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function set(string|array $nameOrValues, ?int $value = null): void {
|
|
|
|
if(empty($nameOrValues))
|
|
|
|
throw new InvalidArgumentException('$nameOrValues may not be empty.');
|
|
|
|
|
|
|
|
if(is_string($nameOrValues)) {
|
|
|
|
if($value === null)
|
|
|
|
throw new InvalidArgumentException('$value may not be null.');
|
|
|
|
$values = [$nameOrValues => $value];
|
|
|
|
} else $values = $nameOrValues;
|
|
|
|
|
|
|
|
|
|
|
|
$args = 0;
|
|
|
|
$stmt = $this->cache->get(sprintf(
|
|
|
|
'REPLACE INTO msz_counters (counter_name, counter_value) VALUES %s',
|
|
|
|
DbTools::prepareListString($values, '(?, ?)')
|
|
|
|
));
|
|
|
|
|
|
|
|
foreach($values as $name => $value) {
|
|
|
|
$stmt->addParameter(++$args, (string)$name);
|
|
|
|
$stmt->addParameter(++$args, (int)$value);
|
|
|
|
}
|
|
|
|
|
|
|
|
$stmt->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function reset(string|array $names): void {
|
|
|
|
if(empty($names))
|
|
|
|
throw new InvalidArgumentException('$names may not be empty.');
|
|
|
|
if(is_string($names))
|
|
|
|
$names = [$names];
|
|
|
|
|
|
|
|
$args = 0;
|
|
|
|
$stmt = $this->cache->get(sprintf(
|
|
|
|
'DELETE FROM msz_counters WHERE counter_name IN (%s)',
|
|
|
|
DbTools::prepareListString($names)
|
|
|
|
));
|
|
|
|
foreach($names as $name)
|
|
|
|
$stmt->addParameter(++$args, (string)$name);
|
|
|
|
$stmt->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function increment(string $name, int $step = 1): void {
|
|
|
|
$stmt = $this->cache->get('INSERT INTO msz_counters (counter_name, counter_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE counter_value = counter_value + ?');
|
|
|
|
$stmt->addParameter(1, $name);
|
|
|
|
$stmt->addParameter(2, $step);
|
|
|
|
$stmt->addParameter(3, $step);
|
|
|
|
$stmt->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function decrement(string $name, int $step = 1): void {
|
|
|
|
$stmt = $this->cache->get('INSERT INTO msz_counters (counter_name, counter_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE counter_value = counter_value - ?');
|
|
|
|
$stmt->addParameter(1, $name);
|
|
|
|
$stmt->addParameter(2, -$step);
|
|
|
|
$stmt->addParameter(3, $step);
|
|
|
|
$stmt->execute();
|
|
|
|
}
|
|
|
|
}
|