mirror of
https://codeberg.org/demostf/api.git
synced 2026-06-03 09:54:17 +02:00
Use query builder and proper typed result for user search
This commit is contained in:
parent
79d9f779f5
commit
e61c5fc249
3 changed files with 88 additions and 15 deletions
48
src/Data/SteamUser.php
Normal file
48
src/Data/SteamUser.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Demostf\API\Data;
|
||||
|
||||
class SteamUser implements \JsonSerializable {
|
||||
/** @var int */
|
||||
private $id;
|
||||
/** @var string */
|
||||
private $steamId;
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
public function __construct(int $id, string $steamId, string $name) {
|
||||
$this->id = $id;
|
||||
$this->steamId = $steamId;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getSteamId(): string {
|
||||
return $this->steamId;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
'id' => $this->getId(),
|
||||
'steamid' => $this->getSteamId(),
|
||||
'name' => $this->getName()
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromRow(array $row): SteamUser {
|
||||
return new self(
|
||||
(int) $row['id'],
|
||||
$row['steamid'],
|
||||
$row['name']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Demostf\API\Providers;
|
||||
|
||||
use Demostf\API\Data\SteamUser;
|
||||
use Demostf\API\Data\User;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use RandomLib\Generator;
|
||||
|
|
@ -71,22 +72,29 @@ class UserProvider extends BaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public function search($query): array {
|
||||
$bySteamId = $this->searchBySteamId($query);
|
||||
/**
|
||||
* @param string $search
|
||||
* @return SteamUser[]
|
||||
*/
|
||||
public function search(string $search): array {
|
||||
$bySteamId = $this->searchBySteamId($search);
|
||||
if ($bySteamId) {
|
||||
return [
|
||||
$bySteamId,
|
||||
];
|
||||
}
|
||||
|
||||
$sql = 'SELECT user_id, players.name, count(demo_id) AS count, steamid,
|
||||
1-(players.name <-> ?) AS sim FROM players
|
||||
INNER JOIN users ON users.id = players.user_id
|
||||
WHERE players.name % ? OR players.name ~* ?
|
||||
GROUP BY players.name, user_id, steamid
|
||||
ORDER BY count DESC
|
||||
LIMIT 100';
|
||||
$result = $this->query($sql, [$query, $query, $query]);
|
||||
$query = $this->getQueryBuilder();
|
||||
$nameParameter = $query->createNamedParameter($search, \PDO::PARAM_STR, ':query');
|
||||
$query->select('user_id', 'p.name', 'count(demo_id) AS count', 'steamid', "1 - (p.name <-> $nameParameter) AS sim")
|
||||
->from('players', 'p')
|
||||
->innerJoin('p', 'users', 'u', $query->expr()->eq('u.id', 'p.user_id'))
|
||||
->where($query->expr()->comparison('p.name', '%', $nameParameter))
|
||||
->orWhere($query->expr()->comparison('p.name', '~*', $nameParameter))
|
||||
->groupBy('p.name', 'user_id', 'steamid')
|
||||
->orderBy('count', 'DESC')
|
||||
->setMaxResults(100);
|
||||
$result = $query->execute();
|
||||
$players = $result->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
usort($players, function ($b, $a) use ($query) {
|
||||
|
|
@ -107,11 +115,7 @@ class UserProvider extends BaseProvider {
|
|||
foreach ($players as $player) {
|
||||
$id = $player['user_id'];
|
||||
if (!isset($result[$id])) {
|
||||
$result[$id] = [
|
||||
'id' => $id,
|
||||
'name' => $player['name'],
|
||||
'steamid' => $player['steamid'],
|
||||
];
|
||||
$result[$id] = new SteamUser($id, $player['steamid'], $player['name']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@ declare(strict_types=1);
|
|||
|
||||
namespace Demostf\API\Test\Providers;
|
||||
|
||||
use Demostf\API\Data\Player;
|
||||
use Demostf\API\Providers\PlayerProvider;
|
||||
use Demostf\API\Providers\UserProvider;
|
||||
use Demostf\API\Test\TestCase;
|
||||
|
||||
class UserProviderTest extends TestCase {
|
||||
/** @var UserProvider */
|
||||
private $provider;
|
||||
/** @var PlayerProvider */
|
||||
private $playerProvider;
|
||||
|
||||
/** @var \SteamId */
|
||||
private $steamId;
|
||||
|
|
@ -19,6 +23,7 @@ class UserProviderTest extends TestCase {
|
|||
|
||||
$this->steamId = $this->getSteamId('76561198024494988', 'Icewind');
|
||||
$this->provider = new UserProvider($this->getDatabaseConnection(), $this->getRandomGenerator());
|
||||
$this->playerProvider = new PlayerProvider($this->getDatabaseConnection());
|
||||
}
|
||||
|
||||
public function testGetNonExisting() {
|
||||
|
|
@ -59,6 +64,22 @@ class UserProviderTest extends TestCase {
|
|||
$result = $this->provider->search('__NOT__FOUND__');
|
||||
|
||||
$this->assertCount(0, $result);
|
||||
|
||||
$this->provider->store($this->steamId);
|
||||
$user = $this->provider->get($this->steamId->getSteamId64());
|
||||
$this->playerProvider->store(new Player(
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
$user->getId(),
|
||||
$user->getName(),
|
||||
'red',
|
||||
'scout'
|
||||
));
|
||||
|
||||
$result = $this->provider->search('Icewind');
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($this->steamId->getSteamId64(), $result[0]->getSteamId());
|
||||
}
|
||||
|
||||
public function testGetIdExisting() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue