Skip to content

Commit

Permalink
Implement profile: getForUrl(), getPercentileForUrl(), getAll()
Browse files Browse the repository at this point in the history
  • Loading branch information
fengqi committed Nov 8, 2021
1 parent 829febc commit 96350cf
Show file tree
Hide file tree
Showing 2 changed files with 285 additions and 61 deletions.
200 changes: 189 additions & 11 deletions src/Db/PdoRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use Generator;
use PDO;
use RuntimeException;
use DateTime;
use DateInterval;
use XHGui\Searcher\SearcherInterface;

class PdoRepository
{
Expand Down Expand Up @@ -86,20 +89,22 @@ public function getById(string $id): array
return $row;
}

public function countByUrl(string $url): int
public function countByUrl(array $options): int
{
$query = sprintf('
SELECT COUNT(*) AS count
FROM %s
WHERE "simple_url" LIKE :url
', $this->table);
WHERE %s',
$this->table,
$options['where']['conditions']
);
$stmt = $this->pdo->prepare($query);
$stmt->execute(['url' => '%' . $url . '%']);
$stmt->execute($options['where']['params']);

return (int)$stmt->fetchColumn();
}

public function findByUrl(string $url, string $direction, int $skip, int $perPage): Generator
public function findByUrl(array $options = []): Generator
{
$query = sprintf('
SELECT
Expand All @@ -118,16 +123,18 @@ public function findByUrl(string $url, string $direction, int $skip, int $perPag
"main_mu",
"main_pmu"
FROM %s
WHERE "simple_url" LIKE :url
ORDER BY "request_ts" %s
WHERE %s
ORDER BY %s %s
LIMIT %d OFFSET %d',
$this->table,
$direction,
$perPage,
$skip
$options['where']['conditions'],
$options['sort'],
$options['direction'],
$options['perPage'],
$options['skip']
);
$stmt = $this->pdo->prepare($query);
$stmt->execute(['url' => '%' . $url . '%']);
$stmt->execute($options['where']['params']);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
yield $row;
Expand Down Expand Up @@ -302,4 +309,175 @@ public function truncateWatches()
$this->pdo->exec(sprintf('DELETE FROM %s', $this->tableWatches))
);
}

public function aggregate(array $options)
{
$query = sprintf('
SELECT
"id",
"request_ts",
"main_wt",
"main_ct",
"main_cpu",
"main_mu",
"main_pmu"
FROM %s
WHERE %s
ORDER BY %s %s',
$this->table,
$options['where']['conditions'],
$options['sort'],
$options['direction']
);
$stmt = $this->pdo->prepare($query);
$stmt->execute($options['where']['params']);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
yield $row;
}
}

/**
* Convert request data keys into pdo query.
*/
public function buildQuery(array $options): array
{
return [
'where' => $this->buildWhere($options['conditions']),
'sort' => $this->buildSort($options),
'direction' => $this->buildDirection($options),
'perPage' => $options['perPage'] ?? SearcherInterface::DEFAULT_PER_PAGE,
];
}

/**
* build pdo where
*
* @param array $search
*
* @return array
*/
public function buildWhere(array $search): array
{
$where = ['conditions' => '1=1', 'params' => []];

if (empty($search)) {
return $where;
}

if (!empty($search['limit_custom']) && $search['limit_custom'][0] === 'P') {
$search['limit'] = $search['limit_custom'];
}
$hasLimit = (!empty($search['limit']) && $search['limit'] != -1);

// simple_url equals match
if (isset($search['simple_url'])) {
$where['conditions'] .= ' and simple_url = :simple_url';
$where['params']['simple_url'] = $search['simple_url'];
}

if (!empty($search['date_start']) && !$hasLimit) {
$where['conditions'] .= ' and request_date >= :date_start';
$where['params']['date_start'] = $search['date_start'];
}

if (!empty($search['date_end']) && !$hasLimit) {
$where['conditions'] .= ' and request_date <= :date_end';
$where['params']['date_end'] = $search['date_end'];
}

if (!empty($search['request_start'])) {
$where['conditions'] .= ' and request_ts >= :request_start';
$where['params']['request_start'] = strtotime($search['request_start']);
}

if (!empty($search['request_end'])) {
$where['conditions'] .= ' and request_ts <= :request_end';
$where['params']['request_end'] = strtotime($search['request_end']);
}

// TODO need JSON support
if (!empty($search['remote_addr'])) {
$where['conditions'] .= ' and SERVER like :remote_addr';
$where['params']['remote_addr'] = '%' . $search['remote_addr'] . '%';
}

if (isset($search['cookie'])) {
$where['conditions'] .= ' and SERVER like :cookie';
$where['params']['cookie'] = '%' . $search['cookie'] . '%';
}

if (!empty($search['server_name'])) {
$where['conditions'] .= ' and SERVER like :server_name';
$where['params']['server_name'] = '%' . $search['server_name'] . '%';
}

if ($hasLimit && $search['limit'][0] === 'P') {
$date = new DateTime();
try {
$date->sub(new DateInterval($search['limit']));
$where['conditions'] .= ' and request_ts >= :limit_start';
$where['params']['limit_start'] = $date->getTimestamp();
} catch (\Exception $e) {
$where['conditions'] .= ' and request_ts >= :limit_start';
$where['params']['limit_start'] = time() + 86400;
}
}

// fuzzy match
if (isset($search['url'])) {
$where['conditions'] .= ' and url like :url';
$where['params']['url'] = '%' . $search['url'] . '%';
}

return $where;
}

/**
* build pdo order sort
*
* @param array $options
*
* @return string
*/
private function buildSort(array $options): string
{
if (empty($options['sort'])) {
return 'request_ts';
}

$valid = ['time', 'wt', 'mu', 'cpu', 'pmu'];
if (isset($options['sort'])) {
if ($options['sort'] === 'time') {
return 'request_ts';
}

if (in_array($options['sort'], $valid, true)) {
return 'main_'.$options['sort'];
}
}

return $options['sort'];
}

/**
* build pdo order direction
*
* @param array $options
*
* @return string
*/
private function buildDirection(array $options): string
{
if (empty($options['direction'])) {
return SearcherInterface::DEFAULT_DIRECTION;
}

$valid = ['desc', 'asc'];
if (in_array($options['direction'], $valid, true)) {
return $options['direction'];
}

return 'desc';
}
}
Loading

0 comments on commit 96350cf

Please sign in to comment.