Skip to content

Commit

Permalink
Merge pull request #340 from perftools/pdo-repository
Browse files Browse the repository at this point in the history
  • Loading branch information
glensc authored Oct 4, 2020
2 parents 9e7a877 + 129b90c commit 5357d09
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 200 deletions.
230 changes: 230 additions & 0 deletions src/Xhgui/Db/PdoRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
<?php

namespace XHGui\Db;

use Generator;
use PDO;
use RuntimeException;

class PdoRepository
{
/** @var PDO */
private $pdo;

/** @var string */
private $table;

/**
* @param PDO $pdo An open database connection
* @param string $table Table name where Xhgui profiles are stored
*/
public function __construct(PDO $pdo, string $table)
{
$this->pdo = $pdo;
$this->table = sprintf('"%s"', $table);
}

public function getLatest(): array
{
$query = sprintf('
SELECT
"id",
"profile",
"url",
"SERVER",
"GET",
"ENV",
"simple_url",
"request_ts",
"request_ts_micro,"
"request_date"
FROM %s
ORDER BY "request_date" ASC
LIMIT 1',
$this->table
);
$stmt = $this->pdo->query($query);

$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row === false) {
throw new RuntimeException('No profile available yet.');
}

return $row;
}

public function getById(string $id): array
{
$query = sprintf('
SELECT
"profile",
"url",
"SERVER",
"GET",
"ENV",
"simple_url",
"request_ts",
"request_ts_micro",
"request_date"
FROM %s
WHERE id = :id
', $this->table);
$stmt = $this->pdo->prepare($query);
$stmt->execute(['id' => $id]);

$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row === false) {
throw new RuntimeException('No profile data found.');
}

return $row;
}

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

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

public function findByUrl(string $url, string $direction, int $skip, int $perPage): Generator
{
$query = sprintf('
SELECT
"id",
"url",
"SERVER",
"GET",
"ENV",
"simple_url",
"request_ts",
"request_ts_micro",
"request_date",
"main_wt",
"main_ct",
"main_cpu",
"main_mu",
"main_pmu"
FROM %s
WHERE "simple_url" LIKE :url
ORDER BY "request_ts" %s
LIMIT %d OFFSET %d',
$this->table,
$direction,
$skip,
$perPage
);
$stmt = $this->pdo->prepare($query);
$stmt->execute(['url' => '%' . $url . '%']);

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

public function deleteById(string $id)
{
$stmt = $this->pdo->prepare(sprintf('
DELETE FROM %s
WHERE id = :id
', $this->table));

$stmt->execute(['id' => $id]);
}

public function deleteAll()
{
return is_int(
$this->pdo->exec(sprintf('DELETE FROM %s', $this->table))
);
}

public function getStatistics()
{
$stmt = $this->pdo->query(
sprintf(
'
SELECT
COUNT(*) AS profiles,
MAX("request_ts") AS latest,
SUM(LENGTH("profile")) AS bytes
FROM %s',
$this->table
),
PDO::FETCH_ASSOC
);

$row = $stmt->fetch(PDO::FETCH_ASSOC);

return $row ?: null;
}

public function initSchema()
{
$this->pdo->exec(sprintf('
CREATE TABLE IF NOT EXISTS %s (
"id" CHAR(24) PRIMARY KEY,
"profile" TEXT NOT NULL,
"url" TEXT NULL,
"SERVER" TEXT NULL,
"GET" TEXT NULL,
"ENV" TEXT NULL,
"simple_url" TEXT NULL,
"request_ts" INTEGER NOT NULL,
"request_ts_micro" NUMERIC(15, 4) NOT NULL,
"request_date" DATE NOT NULL,
"main_wt" INTEGER NOT NULL,
"main_ct" INTEGER NOT NULL,
"main_cpu" INTEGER NOT NULL,
"main_mu" INTEGER NOT NULL,
"main_pmu" INTEGER NOT NULL
)
', $this->table));
}

public function saveProfile(array $data)
{
$stmt = $this->pdo->prepare(sprintf('
INSERT INTO %s (
"id",
"profile",
"url",
"SERVER",
"GET",
"ENV",
"simple_url",
"request_ts",
"request_ts_micro",
"request_date",
"main_wt",
"main_ct",
"main_cpu",
"main_mu",
"main_pmu"
) VALUES (
:id,
:profile,
:url,
:SERVER,
:GET,
:ENV,
:simple_url,
:request_ts,
:request_ts_micro,
:request_date,
:main_wt,
:main_ct,
:main_cpu,
:main_mu,
:main_pmu
)
', $this->table));
$stmt->execute($data);
}
}
87 changes: 7 additions & 80 deletions src/Xhgui/Saver/PdoSaver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,86 +2,18 @@

namespace XHGui\Saver;

use PDO;
use PDOStatement;
use XHGui\Db\PdoRepository;
use XHGui\Util;

class PdoSaver implements SaverInterface
{
const TABLE_DDL = <<<SQL
/** @var PdoRepository */
private $db;

CREATE TABLE IF NOT EXISTS "%s" (
"id" CHAR(24) PRIMARY KEY,
"profile" TEXT NOT NULL,
"url" TEXT NULL,
"SERVER" TEXT NULL,
"GET" TEXT NULL,
"ENV" TEXT NULL,
"simple_url" TEXT NULL,
"request_ts" INTEGER NOT NULL,
"request_ts_micro" NUMERIC(15, 4) NOT NULL,
"request_date" DATE NOT NULL,
"main_wt" INTEGER NOT NULL,
"main_ct" INTEGER NOT NULL,
"main_cpu" INTEGER NOT NULL,
"main_mu" INTEGER NOT NULL,
"main_pmu" INTEGER NOT NULL
);
SQL;

const INSERT_DML = <<<SQL
INSERT INTO "%s" (
"id",
"profile",
"url",
"SERVER",
"GET",
"ENV",
"simple_url",
"request_ts",
"request_ts_micro",
"request_date",
"main_wt",
"main_ct",
"main_cpu",
"main_mu",
"main_pmu"
) VALUES (
:id,
:profile,
:url,
:SERVER,
:GET,
:ENV,
:simple_url,
:request_ts,
:request_ts_micro,
:request_date,
:main_wt,
:main_ct,
:main_cpu,
:main_mu,
:main_pmu
);
SQL;

/**
* @var PDOStatement
*/
private $stmt;

/**
* @param PDO $pdo
* @param string $table
*/
public function __construct(PDO $pdo, $table)
public function __construct(PdoRepository $db)
{
$pdo->exec(sprintf(self::TABLE_DDL, $table));

$this->stmt = $pdo->prepare(sprintf(self::INSERT_DML, $table));
$db->initSchema();
$this->db = $db;
}

public function save(array $data)
Expand All @@ -93,7 +25,7 @@ public function save(array $data)
$sec = $ts['sec'];
$usec = $ts['usec'];

$this->stmt->execute([
$this->db->saveProfile([
'id' => $data['_id'] ?? Util::generateId(),
'profile' => json_encode($data['profile']),
'url' => $data['meta']['url'],
Expand All @@ -111,9 +43,4 @@ public function save(array $data)
'main_pmu' => $main['pmu'],
]);
}

public function __destruct()
{
$this->stmt->closeCursor();
}
}
Loading

0 comments on commit 5357d09

Please sign in to comment.