Change to PDODocument library

This commit is contained in:
2024-06-04 19:56:06 -04:00
parent 1ca7dbdedd
commit 7231a95fca
18 changed files with 197 additions and 233 deletions

View File

@@ -2,19 +2,19 @@
namespace FeedReaderCentral;
use BitBadger\Documents\DocumentException;
use BitBadger\Documents\DocumentList;
use BitBadger\Documents\Field;
use BitBadger\Documents\Query;
use BitBadger\Documents\SQLite\Configuration;
use BitBadger\Documents\SQLite\Custom;
use BitBadger\Documents\SQLite\Document;
use BitBadger\Documents\SQLite\Exists;
use BitBadger\Documents\SQLite\Find;
use BitBadger\Documents\SQLite\Parameters;
use BitBadger\Documents\SQLite\Patch;
use BitBadger\PDODocument\Configuration;
use BitBadger\PDODocument\Custom;
use BitBadger\PDODocument\Document;
use BitBadger\PDODocument\DocumentException;
use BitBadger\PDODocument\DocumentList;
use BitBadger\PDODocument\Exists;
use BitBadger\PDODocument\Field;
use BitBadger\PDODocument\Find;
use BitBadger\PDODocument\Parameters;
use BitBadger\PDODocument\Patch;
use BitBadger\PDODocument\Query;
use DateTimeInterface;
use SQLite3;
use PDO;
/**
* An RSS or Atom feed
@@ -75,23 +75,23 @@ class Feed
* @param int $feedId The ID of the feed to which these items belong
* @param ParsedFeed $parsed The extracted Atom or RSS feed items
* @param DateTimeInterface $lastChecked When this feed was last checked (only new items will be added)
* @param PDO $pdo The database connection over which items should be updated
* @return array ['ok' => true] if successful, ['error' => message] if not
*/
public static function updateItems(int $feedId, ParsedFeed $parsed, DateTimeInterface $lastChecked,
SQLite3 $db): array
public static function updateItems(int $feedId, ParsedFeed $parsed, DateTimeInterface $lastChecked, PDO $pdo): array
{
$results =
array_map(function ($item) use ($db, $feedId) {
array_map(function ($item) use ($pdo, $feedId) {
try {
$existing = Find::firstByFields(Table::ITEM,
[Field::EQ('feed_id', $feedId), Field::EQ('item_guid', $item->guid)], Item::class);
if ($existing) {
if ($existing->published_on != $item->publishedOn
|| ($existing->updated_on != ($item->updatedOn ?? ''))) {
Patch::byId(Table::ITEM, $existing->id, $item->patchFields(), $db);
Patch::byId(Table::ITEM, $existing->id, $item->patchFields(), $pdo);
}
} else {
Document::insert(Table::ITEM, Item::fromFeedItem($feedId, $item), $db);
Document::insert(Table::ITEM, Item::fromFeedItem($feedId, $item), $pdo);
}
return ['ok' => true];
} catch (DocumentException $ex) {
@@ -107,10 +107,10 @@ class Feed
* Purge items for a feed
*
* @param int $feedId The ID of the feed to be purged
* @param SQLite3 $db The database connection on which items should be purged
* @param PDO $pdo The database connection on which items should be purged
* @return array|string[]|true[] ['ok' => true] if purging was successful, ['error' => message] if not
*/
private static function purgeItems(int $feedId, SQLite3 $db): array
private static function purgeItems(int $feedId, PDO $pdo): array
{
if (!array_search(PURGE_TYPE, [self::PURGE_READ, self::PURGE_BY_DAYS, self::PURGE_BY_COUNT])) {
return ['error' => 'Unrecognized purge type ' . PURGE_TYPE];
@@ -127,7 +127,7 @@ class Feed
$sql .= " AND date(coalesce(data->>'updated_on', data->>'published_on)) < date(@oldest)";
} elseif (PURGE_TYPE == self::PURGE_BY_COUNT) {
$fields[] = Field::EQ('', PURGE_NUMBER, '@keep');
$id = Configuration::idField();
$id = Configuration::$idField;
$table = Table::ITEM;
$sql .= ' ' . <<<SQL
AND data->>'$id' IN (
@@ -139,7 +139,7 @@ class Feed
SQL;
}
try {
Custom::nonQuery($sql, Parameters::addFields($fields, []), $db);
Custom::nonQuery($sql, Parameters::addFields($fields, []), $pdo);
return ['ok' => true];
} catch (DocumentException $ex) {
return ['error' => "$ex"];
@@ -151,10 +151,11 @@ class Feed
*
* @param int $feedId The ID of the feed to be refreshed
* @param string $url The URL of the feed to be refreshed
* @param SQLite3 $db A database connection to use to refresh the feed
* @param PDO $pdo A database connection to use to refresh the feed
* @return array|string[]|true[] ['ok' => true] if successful, ['error' => message] if not
*/
public static function refreshFeed(int $feedId, string $url, SQLite3 $db): array {
public static function refreshFeed(int $feedId, string $url, PDO $pdo): array
{
$feedRetrieval = ParsedFeed::retrieve($url);
if (key_exists('error', $feedRetrieval)) return $feedRetrieval;
$feed = $feedRetrieval['ok'];
@@ -164,7 +165,7 @@ class Feed
if (!$feedDoc) return ['error' => 'Could not derive date last checked for feed'];
$lastChecked = date_create_immutable($feedDoc->checked_on ?? WWW_EPOCH);
$itemUpdate = self::updateItems($feedId, $feed, $lastChecked, $db);
$itemUpdate = self::updateItems($feedId, $feed, $lastChecked, $pdo);
if (key_exists('error', $itemUpdate)) return $itemUpdate;
$patch = [
@@ -173,12 +174,12 @@ class Feed
'checked_on' => Data::formatDate('now')
];
if ($url == $feed->url) $patch['url'] = $feed->url;
Patch::byId(Table::FEED, $feedId, $patch, $db);
Patch::byId(Table::FEED, $feedId, $patch, $pdo);
} catch (DocumentException $ex) {
return ['error' => "$ex"];
}
return PURGE_TYPE == self::PURGE_NONE ? ['ok' => true] : self::purgeItems($feedId, $db);
return PURGE_TYPE == self::PURGE_NONE ? ['ok' => true] : self::purgeItems($feedId, $pdo);
}
/**
@@ -187,30 +188,32 @@ class Feed
* @param string $url The URL of the RSS feed to add
* @return array ['ok' => feedId] if successful, ['error' => message] if not
*/
public static function add(string $url, SQLite3 $db): array {
public static function add(string $url): array
{
$feedExtract = ParsedFeed::retrieve($url);
if (key_exists('error', $feedExtract)) return $feedExtract;
$feed = $feedExtract['ok'];
try {
$pdo = Configuration::dbConn();
$fields = [Field::EQ('user_id', $_SESSION[Key::USER_ID]), Field::EQ('url', $feed->url)];
if (Exists::byFields(Table::FEED, $fields, $db)) {
if (Exists::byFields(Table::FEED, $fields, $pdo)) {
return ['error' => "Already subscribed to feed $feed->url"];
}
Document::insert(Table::FEED, self::fromParsed($feed), $db);
Document::insert(Table::FEED, self::fromParsed($feed), $pdo);
$doc = Find::firstByFields(Table::FEED, $fields, self::class);
if (!$doc) return ['error' => 'Could not retrieve inserted feed'];
$result = self::updateItems($doc->id, $feed, date_create_immutable(WWW_EPOCH), $pdo);
if (key_exists('error', $result)) return $result;
return ['ok' => $doc->id];
} catch (DocumentException $ex) {
return ['error' => "$ex"];
}
$result = self::updateItems($doc->id, $feed, date_create_immutable(WWW_EPOCH), $db);
if (key_exists('error', $result)) return $result;
return ['ok' => $doc->id];
}
/**
@@ -218,19 +221,20 @@ class Feed
*
* @param Feed $existing The existing feed
* @param string $url The URL with which the existing feed should be modified
* @param SQLite3 $db The database connection on which to execute the update
* @return bool[]|string[] [ 'ok' => true ] if successful, [ 'error' => message ] if not
*/
public static function update(Feed $existing, string $url, SQLite3 $db): array {
public static function update(Feed $existing, string $url): array
{
try {
$pdo = Configuration::dbConn();
Patch::byFields(Table::FEED,
[Field::EQ(Configuration::idField(), $existing->id), Field::EQ('user_id', $_SESSION[Key::USER_ID])],
['url' => $url], $db);
[Field::EQ(Configuration::$idField, $existing->id), Field::EQ('user_id', $_SESSION[Key::USER_ID])],
['url' => $url], $pdo);
return self::refreshFeed($existing->id, $url, $pdo);
} catch (DocumentException $ex) {
return ['error' => "$ex"];
}
return self::refreshFeed($existing->id, $url, $db);
}
/**
@@ -250,18 +254,18 @@ class Feed
/**
* Refresh all feeds
*
* @param SQLite3 $db The database connection to use for refreshing feeds
* @return array|true[]|string[] ['ok' => true] if successful,
* ['error' => message] if not (may have multiple error lines)
*/
public static function refreshAll(SQLite3 $db): array
public static function refreshAll(): array
{
try {
$feeds = self::retrieveAll($_SESSION[Key::USER_ID]);
$pdo = Configuration::dbConn();
$errors = [];
foreach ($feeds->items() as $feed) {
$result = self::refreshFeed($feed->id, $feed->url, $db);
$result = self::refreshFeed($feed->id, $feed->url, $pdo);
if (key_exists('error', $result)) $errors[] = $result['error'];
}
} catch (DocumentException $ex) {
@@ -278,8 +282,9 @@ class Feed
* @return static|false The data for the feed if found, false if not found
* @throws DocumentException If any is encountered
*/
public static function retrieveById(int $feedId): static|false {
$doc = Find::byId(Table::FEED, $feedId, self::class);
public static function retrieveById(int $feedId): static|false
{
$doc = Find::byId(Table::FEED, $feedId, static::class);
return $doc && $doc->user_id == $_SESSION[Key::USER_ID] ? $doc : false;
}
}