mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-04-01 17:15:28 +00:00
implement connection cache
This commit is contained in:
parent
089bf67a5b
commit
03ac7647b7
6 changed files with 215 additions and 58 deletions
|
|
@ -4,15 +4,22 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Yggverse\Yoda\Abstract\Model;
|
namespace Yggverse\Yoda\Abstract\Model;
|
||||||
|
|
||||||
|
use \Yggverse\Yoda\Model\Database;
|
||||||
use \Yggverse\Yoda\Model\Pool;
|
use \Yggverse\Yoda\Model\Pool;
|
||||||
|
|
||||||
abstract class Connection implements \Yggverse\Yoda\Interface\Model\Connection
|
abstract class Connection implements \Yggverse\Yoda\Interface\Model\Connection
|
||||||
{
|
{
|
||||||
|
private Database $_database;
|
||||||
|
|
||||||
private Pool $_pool;
|
private Pool $_pool;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
Database $database,
|
||||||
?Pool $pool = null
|
?Pool $pool = null
|
||||||
) {
|
) {
|
||||||
|
// Init database connection to store cached results
|
||||||
|
$this->_database = $database;
|
||||||
|
|
||||||
// Use shared memory pool for async operations
|
// Use shared memory pool for async operations
|
||||||
$this->_pool = $pool ? $pool : new Pool;
|
$this->_pool = $pool ? $pool : new Pool;
|
||||||
|
|
||||||
|
|
@ -228,6 +235,37 @@ abstract class Connection implements \Yggverse\Yoda\Interface\Model\Connection
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCache(
|
||||||
|
string $request
|
||||||
|
): ?object
|
||||||
|
{
|
||||||
|
if ($cache = $this->_database->findCache($request))
|
||||||
|
{
|
||||||
|
if (empty($cache[0]))
|
||||||
|
{
|
||||||
|
throw new \Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cache[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cache(
|
||||||
|
string $request
|
||||||
|
): void
|
||||||
|
{
|
||||||
|
$this->_database->renewCache(
|
||||||
|
$request,
|
||||||
|
$this->getMime(),
|
||||||
|
$this->getTitle(),
|
||||||
|
$this->getSubtitle(),
|
||||||
|
$this->getTooltip(),
|
||||||
|
$this->getData()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function reset(): void
|
public function reset(): void
|
||||||
{
|
{
|
||||||
$this->_pool->reset();
|
$this->_pool->reset();
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,9 @@ class Page
|
||||||
$this->response->hide();
|
$this->response->hide();
|
||||||
|
|
||||||
// Update content using multi-protocol driver
|
// Update content using multi-protocol driver
|
||||||
$connection = new Connection;
|
$connection = new Connection(
|
||||||
|
$this->container->browser->database
|
||||||
|
);
|
||||||
|
|
||||||
// Async request
|
// Async request
|
||||||
$connection->request(
|
$connection->request(
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Yggverse\Yoda\Interface\Model;
|
namespace Yggverse\Yoda\Interface\Model;
|
||||||
|
|
||||||
|
use \Yggverse\Yoda\Model\Database;
|
||||||
use \Yggverse\Yoda\Model\Pool;
|
use \Yggverse\Yoda\Model\Pool;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -13,6 +14,7 @@ use \Yggverse\Yoda\Model\Pool;
|
||||||
interface Connection
|
interface Connection
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
Database $database,
|
||||||
?Pool $pool = null
|
?Pool $pool = null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -74,6 +76,14 @@ interface Connection
|
||||||
|
|
||||||
public function getLength(): ?int;
|
public function getLength(): ?int;
|
||||||
|
|
||||||
|
public function getCache(
|
||||||
|
string $request
|
||||||
|
): ?object;
|
||||||
|
|
||||||
|
public function cache(
|
||||||
|
string $request
|
||||||
|
): void;
|
||||||
|
|
||||||
public function reset(): void;
|
public function reset(): void;
|
||||||
|
|
||||||
public function close(): void;
|
public function close(): void;
|
||||||
|
|
|
||||||
|
|
@ -109,11 +109,16 @@ class Gemini
|
||||||
$address->get()
|
$address->get()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update content data
|
// Set data
|
||||||
$this->_connection->setData(
|
$this->_connection->setData(
|
||||||
$response->getBody()
|
$response->getBody()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
$this->_connection->cache(
|
||||||
|
$address->get()
|
||||||
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31: // redirect
|
case 31: // redirect
|
||||||
|
|
@ -149,35 +154,65 @@ class Gemini
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
$this->_connection->setTitle(
|
// Try cache
|
||||||
_('Oops!')
|
if ($cache = $this->_connection->getCache($address->get()))
|
||||||
);
|
{
|
||||||
|
$this->_connection->setTitle(
|
||||||
|
$cache->title
|
||||||
|
);
|
||||||
|
|
||||||
$this->_connection->setSubtitle(
|
$this->_connection->setSubtitle(
|
||||||
$address->getHost()
|
date(
|
||||||
);
|
'c',
|
||||||
|
$cache->time
|
||||||
|
) # $cache->subtitle
|
||||||
|
);
|
||||||
|
|
||||||
$this->_connection->setTooltip(
|
$this->_connection->setTooltip(
|
||||||
sprintf(
|
$cache->tooltip
|
||||||
'Could not open request (code: %d)',
|
);
|
||||||
intval(
|
|
||||||
$response->getCode()
|
$this->_connection->setData(
|
||||||
|
$cache->data
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setMime(
|
||||||
|
$cache->mime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->_connection->setTitle(
|
||||||
|
_('Oops!')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setSubtitle(
|
||||||
|
$address->getHost()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setTooltip(
|
||||||
|
sprintf(
|
||||||
|
'Could not open request (code: %d)',
|
||||||
|
intval(
|
||||||
|
$response->getCode()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
$this->_connection->setData(
|
$this->_connection->setData(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Could not open request (code: %d)',
|
'Could not open request (code: %d)',
|
||||||
intval(
|
intval(
|
||||||
$response->getCode()
|
$response->getCode()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
$this->_connection->setMime(
|
$this->_connection->setMime(
|
||||||
Filesystem::MIME_TEXT_GEMINI
|
Filesystem::MIME_TEXT_GEMINI
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_connection->setCompleted(
|
$this->_connection->setCompleted(
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class Nex
|
||||||
$timeout
|
$timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Success
|
||||||
if ($response)
|
if ($response)
|
||||||
{
|
{
|
||||||
// Detect MIME type
|
// Detect MIME type
|
||||||
|
|
@ -67,9 +68,42 @@ class Nex
|
||||||
$address->get()
|
$address->get()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set data
|
||||||
$this->_connection->setData(
|
$this->_connection->setData(
|
||||||
$response
|
$response
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
$this->_connection->cache(
|
||||||
|
$address->get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try cache
|
||||||
|
if ($cache = $this->_connection->getCache())
|
||||||
|
{
|
||||||
|
$this->_connection->setTitle(
|
||||||
|
$cache->title
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setSubtitle(
|
||||||
|
date(
|
||||||
|
'c',
|
||||||
|
$cache->time
|
||||||
|
) # $cache->subtitle
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setTooltip(
|
||||||
|
$cache->tooltip
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setData(
|
||||||
|
$cache->data
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_connection->setMime(
|
||||||
|
$cache->mime
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Yggverse\Yoda\Model;
|
||||||
|
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
private \PDO $_database;
|
private \PDO $_connection;
|
||||||
|
|
||||||
private bool $_exists;
|
private bool $_exists;
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ class Database
|
||||||
);
|
);
|
||||||
|
|
||||||
// Init database connection
|
// Init database connection
|
||||||
$this->_database = new \PDO(
|
$this->_connection = new \PDO(
|
||||||
sprintf(
|
sprintf(
|
||||||
'sqlite:%s',
|
'sqlite:%s',
|
||||||
$filename
|
$filename
|
||||||
|
|
@ -30,28 +30,32 @@ class Database
|
||||||
$password
|
$password
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->_database->setAttribute(
|
$this->_connection->setAttribute(
|
||||||
\PDO::ATTR_ERRMODE,
|
\PDO::ATTR_ERRMODE,
|
||||||
\PDO::ERRMODE_EXCEPTION
|
\PDO::ERRMODE_EXCEPTION
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->_database->setAttribute(
|
$this->_connection->setAttribute(
|
||||||
\PDO::ATTR_DEFAULT_FETCH_MODE,
|
\PDO::ATTR_DEFAULT_FETCH_MODE,
|
||||||
\PDO::FETCH_OBJ
|
\PDO::FETCH_OBJ
|
||||||
);
|
);
|
||||||
|
|
||||||
// Init tables
|
// Init tables
|
||||||
$this->_database->query('
|
$this->_connection->query('
|
||||||
CREATE TABLE IF NOT EXISTS `cache`
|
CREATE TABLE IF NOT EXISTS `cache`
|
||||||
(
|
(
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
`time` INTEGER NOT NULL,
|
`time` INTEGER NOT NULL,
|
||||||
`request` VARCHAR(1024),
|
`request` VARCHAR(1024),
|
||||||
`data` BLOB
|
`mime` VARCHAR(255),
|
||||||
|
`title` VARCHAR(255),
|
||||||
|
`subtitle` VARCHAR(255),
|
||||||
|
`tooltip` VARCHAR(255),
|
||||||
|
`data` BLOB
|
||||||
);
|
);
|
||||||
');
|
');
|
||||||
|
|
||||||
$this->_database->query('
|
$this->_connection->query('
|
||||||
CREATE TABLE IF NOT EXISTS `history`
|
CREATE TABLE IF NOT EXISTS `history`
|
||||||
(
|
(
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
|
@ -61,7 +65,7 @@ class Database
|
||||||
)
|
)
|
||||||
');
|
');
|
||||||
|
|
||||||
$this->_database->query('
|
$this->_connection->query('
|
||||||
CREATE TABLE IF NOT EXISTS `session`
|
CREATE TABLE IF NOT EXISTS `session`
|
||||||
(
|
(
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
|
@ -83,24 +87,48 @@ class Database
|
||||||
// Cache
|
// Cache
|
||||||
public function addCache(
|
public function addCache(
|
||||||
?string $request = null,
|
?string $request = null,
|
||||||
|
?string $mime = null,
|
||||||
|
?string $title = null,
|
||||||
|
?string $subtitle = null,
|
||||||
|
?string $tooltip = null,
|
||||||
?string $data = null,
|
?string $data = null,
|
||||||
?int $time = null
|
?int $time = null
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
'INSERT INTO `cache` (`time`, `request`, `data`) VALUES (:time, :request, :data)'
|
'INSERT INTO `cache` (
|
||||||
|
`time`,
|
||||||
|
`request`,
|
||||||
|
`mime`,
|
||||||
|
`title`,
|
||||||
|
`subtitle`,
|
||||||
|
`tooltip`,
|
||||||
|
`data`
|
||||||
|
) VALUES (
|
||||||
|
:time,
|
||||||
|
:request,
|
||||||
|
:mime,
|
||||||
|
:title,
|
||||||
|
:subtitle,
|
||||||
|
:tooltip,
|
||||||
|
:data
|
||||||
|
)'
|
||||||
);
|
);
|
||||||
|
|
||||||
$query->execute(
|
$query->execute(
|
||||||
[
|
[
|
||||||
':time' => $time ? $time : time(),
|
':time' => $time ? $time : time(),
|
||||||
':request' => $request,
|
':request' => $request,
|
||||||
':data' => $data
|
':mime' => $mime,
|
||||||
|
':title' => $title,
|
||||||
|
':subtitle' => $subtitle,
|
||||||
|
':tooltip' => $tooltip,
|
||||||
|
':data' => $data
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return intval(
|
return intval(
|
||||||
$this->_database->lastInsertId()
|
$this->_connection->lastInsertId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +138,7 @@ class Database
|
||||||
int $limit = 1000
|
int $limit = 1000
|
||||||
): array
|
): array
|
||||||
{
|
{
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
sprintf(
|
sprintf(
|
||||||
'SELECT * FROM `cache`
|
'SELECT * FROM `cache`
|
||||||
WHERE `request` LIKE :request
|
WHERE `request` LIKE :request
|
||||||
|
|
@ -138,7 +166,7 @@ class Database
|
||||||
int $id
|
int $id
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
sprintf(
|
sprintf(
|
||||||
'DELETE FROM `cache` WHERE `id` = %d',
|
'DELETE FROM `cache` WHERE `id` = %d',
|
||||||
$id
|
$id
|
||||||
|
|
@ -152,7 +180,7 @@ class Database
|
||||||
int $timeout = 0
|
int $timeout = 0
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
sprintf(
|
sprintf(
|
||||||
'DELETE FROM `cache` WHERE `time` + %d < %d',
|
'DELETE FROM `cache` WHERE `time` + %d < %d',
|
||||||
$timeout,
|
$timeout,
|
||||||
|
|
@ -165,11 +193,16 @@ class Database
|
||||||
|
|
||||||
public function renewCache(
|
public function renewCache(
|
||||||
string $request,
|
string $request,
|
||||||
?string $title = null
|
?string $mime = null,
|
||||||
|
?string $title = null,
|
||||||
|
?string $subtitle = null,
|
||||||
|
?string $tooltip = null,
|
||||||
|
?string $data = null,
|
||||||
|
?int $time = null
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
// Find same records match URL
|
// Find same records match URL
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
'SELECT * FROM `cache` WHERE `request` LIKE :request'
|
'SELECT * FROM `cache` WHERE `request` LIKE :request'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -190,7 +223,12 @@ class Database
|
||||||
// Add new record
|
// Add new record
|
||||||
$this->addCache(
|
$this->addCache(
|
||||||
$request,
|
$request,
|
||||||
$data
|
$mime,
|
||||||
|
$title,
|
||||||
|
$subtitle,
|
||||||
|
$tooltip,
|
||||||
|
$data,
|
||||||
|
$time
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +238,7 @@ class Database
|
||||||
?string $title = null
|
?string $title = null
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
'INSERT INTO `history` (`time`, `url`, `title`) VALUES (:time, :url, :title)'
|
'INSERT INTO `history` (`time`, `url`, `title`) VALUES (:time, :url, :title)'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -213,7 +251,7 @@ class Database
|
||||||
);
|
);
|
||||||
|
|
||||||
return intval(
|
return intval(
|
||||||
$this->_database->lastInsertId()
|
$this->_connection->lastInsertId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +261,7 @@ class Database
|
||||||
int $limit = 1000
|
int $limit = 1000
|
||||||
): array
|
): array
|
||||||
{
|
{
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
sprintf(
|
sprintf(
|
||||||
'SELECT * FROM `history`
|
'SELECT * FROM `history`
|
||||||
WHERE `url` LIKE :value OR `title` LIKE :value
|
WHERE `url` LIKE :value OR `title` LIKE :value
|
||||||
|
|
@ -250,7 +288,7 @@ class Database
|
||||||
int $id
|
int $id
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
sprintf(
|
sprintf(
|
||||||
'DELETE FROM `history` WHERE `id` = %d',
|
'DELETE FROM `history` WHERE `id` = %d',
|
||||||
$id
|
$id
|
||||||
|
|
@ -264,7 +302,7 @@ class Database
|
||||||
int $timeout = 0
|
int $timeout = 0
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
sprintf(
|
sprintf(
|
||||||
'DELETE FROM `history` WHERE `time` + %d < %d',
|
'DELETE FROM `history` WHERE `time` + %d < %d',
|
||||||
$timeout,
|
$timeout,
|
||||||
|
|
@ -282,7 +320,7 @@ class Database
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
// Find same records match URL
|
// Find same records match URL
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
'SELECT * FROM `history` WHERE `url` LIKE :url'
|
'SELECT * FROM `history` WHERE `url` LIKE :url'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -313,7 +351,7 @@ class Database
|
||||||
?int $time = null
|
?int $time = null
|
||||||
): int
|
): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->prepare(
|
$query = $this->_connection->prepare(
|
||||||
'INSERT INTO `session` (`time`, `request`) VALUES (:time, :request)'
|
'INSERT INTO `session` (`time`, `request`) VALUES (:time, :request)'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -325,13 +363,13 @@ class Database
|
||||||
);
|
);
|
||||||
|
|
||||||
return intval(
|
return intval(
|
||||||
$this->_database->lastInsertId()
|
$this->_connection->lastInsertId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSession(): array
|
public function getSession(): array
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
'SELECT * FROM `session`'
|
'SELECT * FROM `session`'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -345,7 +383,7 @@ class Database
|
||||||
|
|
||||||
public function cleanSession(): int
|
public function cleanSession(): int
|
||||||
{
|
{
|
||||||
$query = $this->_database->query(
|
$query = $this->_connection->query(
|
||||||
'DELETE FROM `session`'
|
'DELETE FROM `session`'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue