From 7231a95fcadf19a58a697565d0bc0bcd1052b0e1 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Tue, 4 Jun 2024 19:56:06 -0400 Subject: [PATCH] Change to PDODocument library --- src/app-config.php | 4 +- src/composer.json | 15 +++---- src/composer.lock | 51 +++++++-------------- src/lib/Data.php | 47 ++++++++++--------- src/lib/Feed.php | 95 ++++++++++++++++++++------------------- src/lib/ItemList.php | 21 +++++---- src/lib/ItemWithFeed.php | 22 ++++----- src/lib/Security.php | 6 +-- src/lib/User.php | 18 ++++---- src/public/bookmark.php | 4 +- src/public/feed/index.php | 14 +++--- src/public/feeds.php | 13 +++--- src/public/index.php | 5 +-- src/public/item.php | 6 +-- src/util/db-update.php | 56 +++++++++++------------ src/util/refresh.php | 15 +++---- src/util/search.php | 20 ++++----- src/util/user.php | 18 ++++---- 18 files changed, 197 insertions(+), 233 deletions(-) diff --git a/src/app-config.php b/src/app-config.php index 92d7df8..21fdabb 100644 --- a/src/app-config.php +++ b/src/app-config.php @@ -2,7 +2,7 @@ /** The current Feed Reader Central version */ -use BitBadger\Documents\SQLite\Configuration; +use BitBadger\PDODocument\Configuration; use FeedReaderCentral\Data; const FRC_VERSION = '1.0.0-beta1'; @@ -26,7 +26,7 @@ function display_version(): string { require __DIR__ . '/vendor/autoload.php'; require 'user-config.php'; -Configuration::useDbFileName(implode(DIRECTORY_SEPARATOR, [__DIR__, 'data', DATABASE_NAME])); +Configuration::$pdoDSN = 'sqlite:' . implode(DIRECTORY_SEPARATOR, [__DIR__, 'data', DATABASE_NAME]); Data::ensureDb(); /** @var string The date the world wide web was created */ diff --git a/src/composer.json b/src/composer.json index 62c4ceb..6920e7c 100644 --- a/src/composer.json +++ b/src/composer.json @@ -4,19 +4,16 @@ "repositories": [ { "type": "vcs", - "url": "https://git.bitbadger.solutions/bit-badger/documents-common" - }, - { - "type": "vcs", - "url": "https://git.bitbadger.solutions/bit-badger/documents-sqlite" + "url": "https://git.bitbadger.solutions/bit-badger/pdo-document" } ], "require": { - "bit-badger/documents-sqlite": "dev-conversion", - "ext-sqlite3": "*", - "ext-dom": "*", + "bit-badger/pdo-document": "dev-develop", "ext-curl": "*", - "ext-readline": "*" + "ext-dom": "*", + "ext-pdo": "*", + "ext-readline": "*", + "ext-sqlite3": "*" }, "autoload": { "psr-4": { diff --git a/src/composer.lock b/src/composer.lock index cf66c9b..40870d5 100644 --- a/src/composer.lock +++ b/src/composer.lock @@ -4,17 +4,18 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "029a3af4ce4e5cc5488c1ca634a8af61", + "content-hash": "e76207a80fdea0c9dc753a55e6f66bf0", "packages": [ { - "name": "bit-badger/documents-common", - "version": "dev-conversion", + "name": "bit-badger/pdo-document", + "version": "dev-develop", "source": { "type": "git", - "url": "https://git.bitbadger.solutions/bit-badger/documents-common", - "reference": "9dd8059e80423c67c79c62ff27e92f920d5f041b" + "url": "https://git.bitbadger.solutions/bit-badger/pdo-document", + "reference": "afc5d8009507a297c8169be93aee1085e652eedc" }, "require": { + "ext-pdo": "*", "netresearch/jsonmapper": "^4" }, "require-dev": { @@ -23,32 +24,9 @@ "type": "library", "autoload": { "psr-4": { - "BitBadger\\Documents\\": "./", - "BitBadger\\Documents\\Query\\": "./Query" - } - }, - "time": "2024-06-03T15:26:37+00:00" - }, - { - "name": "bit-badger/documents-sqlite", - "version": "dev-conversion", - "source": { - "type": "git", - "url": "https://git.bitbadger.solutions/bit-badger/documents-sqlite", - "reference": "1439742c40ee8b8accd8d70f2ce94df458c6bc42" - }, - "require": { - "bit-badger/documents-common": "dev-conversion", - "ext-sqlite3": "*" - }, - "require-dev": { - "phpunit/phpunit": "^11" - }, - "type": "library", - "autoload": { - "psr-4": { - "BitBadger\\Documents\\SQLite\\": "./src", - "BitBadger\\Documents\\SQLite\\Query\\": "./src/Query" + "BitBadger\\PDODocument\\": "./src", + "BitBadger\\PDODocument\\Mapper\\": "./src/Mapper", + "BitBadger\\PDODocument\\Query\\": "./src/Query" } }, "autoload-dev": { @@ -57,7 +35,7 @@ "Test\\Integration\\": "./tests/integration" } }, - "time": "2024-06-03T22:16:08+00:00" + "time": "2024-06-04T12:10:57+00:00" }, { "name": "netresearch/jsonmapper", @@ -115,15 +93,16 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { - "bit-badger/documents-sqlite": 20 + "bit-badger/pdo-document": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "ext-sqlite3": "*", - "ext-dom": "*", "ext-curl": "*", - "ext-readline": "*" + "ext-dom": "*", + "ext-pdo": "*", + "ext-readline": "*", + "ext-sqlite3": "*" }, "platform-dev": [], "plugin-api-version": "2.6.0" diff --git a/src/lib/Data.php b/src/lib/Data.php index 2558888..83599e0 100644 --- a/src/lib/Data.php +++ b/src/lib/Data.php @@ -2,16 +2,16 @@ namespace FeedReaderCentral; -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\Field; -use BitBadger\Documents\SQLite\Configuration; -use BitBadger\Documents\SQLite\Custom; -use BitBadger\Documents\SQLite\Definition; -use BitBadger\Documents\StringMapper; +use BitBadger\PDODocument\Configuration; +use BitBadger\PDODocument\Custom; +use BitBadger\PDODocument\Definition; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Mapper\StringMapper; use DateTimeImmutable; use DateTimeInterface; use Exception; -use SQLite3; +use PDO; /** * A centralized place for data access for the application @@ -21,18 +21,18 @@ class Data /** * Create the search index and synchronization triggers for the item table * - * @param SQLite3 $db The database connection on which these will be created + * @param PDO $pdo The database connection on which these will be created * @throws DocumentException If any is encountered */ - public static function createSearchIndex(SQLite3 $db): void + public static function createSearchIndex(PDO $pdo): void { Custom::nonQuery("CREATE VIRTUAL TABLE item_search USING fts5(content, content='item', content_rowid='id')", - [], $db); + [], $pdo); Custom::nonQuery(<<<'SQL' CREATE TRIGGER item_ai AFTER INSERT ON item BEGIN INSERT INTO item_search (rowid, content) VALUES (new.data->>'id', new.data->>'content'); END; - SQL, [], $db); + SQL, [], $pdo); Custom::nonQuery(<<<'SQL' CREATE TRIGGER item_au AFTER UPDATE ON item BEGIN INSERT INTO item_search ( @@ -42,7 +42,7 @@ class Data ); INSERT INTO item_search (rowid, content) VALUES (new.data->>'id', new.data->>'content'); END; - SQL, [], $db); + SQL, [], $pdo); Custom::nonQuery(<<<'SQL' CREATE TRIGGER item_ad AFTER DELETE ON item BEGIN INSERT INTO item_search ( @@ -51,7 +51,7 @@ class Data 'delete', old.data->>'id', old.data->>'content' ); END; - SQL, [], $db); + SQL, [], $pdo); } /** @@ -62,23 +62,22 @@ class Data public static function ensureDb(): void { $tables = Custom::array("SELECT name FROM sqlite_master WHERE type = 'table'", [], new StringMapper('name')); - $db = Configuration::dbConn(); + $pdo = Configuration::dbConn(); if (!in_array(Table::USER, $tables)) { - Definition::ensureTable(Table::USER, $db); - Definition::ensureFieldIndex(Table::USER, 'email', ['email'], $db); + Definition::ensureTable(Table::USER, $pdo); + Definition::ensureFieldIndex(Table::USER, 'email', ['email'], $pdo); } if (!in_array(Table::FEED, $tables)) { - Definition::ensureTable(Table::FEED, $db); - Definition::ensureFieldIndex(Table::FEED, 'user', ['user_id'], $db); + Definition::ensureTable(Table::FEED, $pdo); + Definition::ensureFieldIndex(Table::FEED, 'user', ['user_id'], $pdo); } if (!in_array(Table::ITEM, $tables)) { - Definition::ensureTable(Table::ITEM, $db); - Definition::ensureFieldIndex(Table::ITEM, 'feed', ['feed_id', 'item_link'], $db); - self::createSearchIndex($db); + Definition::ensureTable(Table::ITEM, $pdo); + Definition::ensureFieldIndex(Table::ITEM, 'feed', ['feed_id', 'item_link'], $pdo); + self::createSearchIndex($pdo); } - $journalMode = Custom::scalar("PRAGMA journal_mode", [], fn($it) => $it[0]); + $journalMode = Custom::scalar("PRAGMA journal_mode", [], new StringMapper('journal_mode')); if ($journalMode <> 'wal') Custom::nonQuery("PRAGMA journal_mode = 'wal'", []); - $db->close(); } /** @@ -103,7 +102,7 @@ class Data */ public static function feedField(int $feedId, string $qualifier = ''): Field { - $feedField = Field::EQ(Configuration::idField(), $feedId, '@feed'); + $feedField = Field::EQ(Configuration::$idField, $feedId, '@feed'); $feedField->qualifier = $qualifier; return $feedField; } diff --git a/src/lib/Feed.php b/src/lib/Feed.php index 66d6adf..ea6d887 100644 --- a/src/lib/Feed.php +++ b/src/lib/Feed.php @@ -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 .= ' ' . <<>'$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; } } diff --git a/src/lib/ItemList.php b/src/lib/ItemList.php index 49175e5..116c9fb 100644 --- a/src/lib/ItemList.php +++ b/src/lib/ItemList.php @@ -2,15 +2,14 @@ namespace FeedReaderCentral; -use BitBadger\Documents\Configuration; -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\DocumentList; -use BitBadger\Documents\Field; -use BitBadger\Documents\JsonMapper; -use BitBadger\Documents\Query; -use BitBadger\Documents\SQLite\Custom; -use BitBadger\Documents\SQLite\Parameters; -use Iterator; +use BitBadger\PDODocument\Configuration; +use BitBadger\PDODocument\Custom; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\DocumentList; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Parameters; +use BitBadger\PDODocument\Query; +use BitBadger\PDODocument\Mapper\DocumentMapper; /** * A list of items to be displayed @@ -61,7 +60,7 @@ class ItemList ItemWithFeed::SELECT_WITH_FEED . ' WHERE ' . Query::whereByFields(array_filter($allFields, fn($it) => $it->paramName <> '@search')) . $searchWhere, - Parameters::addFields($allFields, []), new JsonMapper(ItemWithFeed::class)); + Parameters::addFields($allFields, []), new DocumentMapper(ItemWithFeed::class)); } catch (DocumentException $ex) { $this->error = "$ex"; } @@ -141,7 +140,7 @@ class ItemList if ($isBookmarked) $fields[] = Data::bookmarkField(Table::ITEM); $list = new static('Matching' . ($isBookmarked ? ' Bookmarked' : ''), "/search?search=$search&items=" . ($isBookmarked ? 'bookmarked' : 'all'), $fields, - ' AND ' . Table::ITEM . ".data->>'" . Configuration::idField() . "' IN " + ' AND ' . Table::ITEM . ".data->>'" . Configuration::$idField . "' IN " . '(SELECT ROWID FROM item_search WHERE content MATCH @search)'); $list->showIndicators = true; $list->displayFeed = true; diff --git a/src/lib/ItemWithFeed.php b/src/lib/ItemWithFeed.php index 6f3d962..362b860 100644 --- a/src/lib/ItemWithFeed.php +++ b/src/lib/ItemWithFeed.php @@ -2,14 +2,14 @@ namespace FeedReaderCentral; -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\Field; -use BitBadger\Documents\JsonMapper; -use BitBadger\Documents\Query; -use BitBadger\Documents\SQLite\Configuration; -use BitBadger\Documents\SQLite\Custom; -use BitBadger\Documents\SQLite\Parameters; -use BitBadger\Documents\SQLite\Results; +use BitBadger\PDODocument\Configuration; +use BitBadger\PDODocument\Custom; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Parameters; +use BitBadger\PDODocument\Query; +use BitBadger\PDODocument\Mapper\DocumentMapper; +use BitBadger\PDODocument\Mapper\ExistsMapper; /** * A combined item and feed (used for lists) @@ -36,7 +36,7 @@ class ItemWithFeed extends Item */ private static function idAndUserFields(int $id): array { - $idField = Field::EQ(Configuration::idField(), $id, '@id'); + $idField = Field::EQ(Configuration::$idField, $id, '@id'); $idField->qualifier = Table::ITEM; $userField = Field::EQ('user_id', $_SESSION[Key::USER_ID], '@user'); $userField->qualifier = Table::FEED; @@ -54,7 +54,7 @@ class ItemWithFeed extends Item { $fields = self::idAndUserFields($id); return Custom::scalar(Query\Exists::query(self::FROM_WITH_JOIN, Query::whereByFields($fields)), - Parameters::addFields($fields, []), Results::toExists(...)); + Parameters::addFields($fields, []), new ExistsMapper()); } /** @@ -68,6 +68,6 @@ class ItemWithFeed extends Item { $fields = self::idAndUserFields($id); return Custom::single(self::SELECT_WITH_FEED . ' WHERE ' . Query::whereByFields($fields), - Parameters::addFields($fields, []), new JsonMapper(self::class)); + Parameters::addFields($fields, []), new DocumentMapper(self::class)); } } diff --git a/src/lib/Security.php b/src/lib/Security.php index 25bd600..68d9fce 100644 --- a/src/lib/Security.php +++ b/src/lib/Security.php @@ -2,9 +2,9 @@ namespace FeedReaderCentral; -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\Field; -use BitBadger\Documents\SQLite\Patch; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Patch; /** * Security functions diff --git a/src/lib/User.php b/src/lib/User.php index 002d668..57f541b 100644 --- a/src/lib/User.php +++ b/src/lib/User.php @@ -2,14 +2,14 @@ namespace FeedReaderCentral; -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\Field; -use BitBadger\Documents\Query; -use BitBadger\Documents\SQLite\Custom; -use BitBadger\Documents\SQLite\Document; -use BitBadger\Documents\SQLite\Find; -use BitBadger\Documents\SQLite\Parameters; -use BitBadger\Documents\SQLite\Results; +use BitBadger\PDODocument\Custom; +use BitBadger\PDODocument\Document; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Find; +use BitBadger\PDODocument\Mapper\ExistsMapper; +use BitBadger\PDODocument\Parameters; +use BitBadger\PDODocument\Query; /** * A user of Feed Reader Central @@ -59,6 +59,6 @@ class User { $fields = [Data::userIdField(Table::FEED), Data::bookmarkField(Table::ITEM)]; return Custom::scalar(Query\Exists::query(ItemWithFeed::FROM_WITH_JOIN, Query::whereByFields($fields)), - Parameters::addFields($fields, []), Results::toExists(...)); + Parameters::addFields($fields, []), new ExistsMapper()); } } diff --git a/src/public/bookmark.php b/src/public/bookmark.php index cd35b32..44ddc86 100644 --- a/src/public/bookmark.php +++ b/src/public/bookmark.php @@ -6,8 +6,8 @@ * This will display a button which will either add or remove a bookmark for a given item. */ -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\SQLite\Patch; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Patch; use FeedReaderCentral\ItemWithFeed; use FeedReaderCentral\Table; diff --git a/src/public/feed/index.php b/src/public/feed/index.php index b785980..f15776a 100644 --- a/src/public/feed/index.php +++ b/src/public/feed/index.php @@ -6,10 +6,9 @@ * Allows users to add, edit, and delete feeds */ -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\Field; -use BitBadger\Documents\SQLite\Configuration; -use BitBadger\Documents\SQLite\Delete; +use BitBadger\PDODocument\Delete; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Field; use FeedReaderCentral\Feed; use FeedReaderCentral\Security; use FeedReaderCentral\Table; @@ -32,21 +31,19 @@ if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { } } -$db = Configuration::dbConn(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { try { $isNew = $_POST['id'] == 'new'; if ($isNew) { - $result = Feed::add($_POST['url'], $db); + $result = Feed::add($_POST['url']); } else { $toEdit = Feed::retrieveById($_POST['id']); $result = $toEdit - ? Feed::update($toEdit, $_POST['url'], $db) + ? Feed::update($toEdit, $_POST['url']) : ['error' => "Feed {$_POST['id']} not found"]; } if (key_exists('ok', $result)) { add_info('Feed saved successfully'); - $db->close(); frc_redirect('/feeds'); } add_error($result['error']); @@ -83,4 +80,3 @@ page_head($title); ?> close(); diff --git a/src/public/feeds.php b/src/public/feeds.php index d139857..13763a3 100644 --- a/src/public/feeds.php +++ b/src/public/feeds.php @@ -6,11 +6,11 @@ * List feeds and provide links for maintenance actions */ -use BitBadger\Documents\ArrayMapper; -use BitBadger\Documents\Field; -use BitBadger\Documents\JsonMapper; -use BitBadger\Documents\Query; -use BitBadger\Documents\SQLite\Custom; +use BitBadger\PDODocument\Custom; +use BitBadger\PDODocument\Field; +use BitBadger\PDODocument\Mapper\ArrayMapper; +use BitBadger\PDODocument\Mapper\DocumentMapper; +use BitBadger\PDODocument\Query; use FeedReaderCentral\Feed; use FeedReaderCentral\Key; use FeedReaderCentral\Table; @@ -19,10 +19,9 @@ include '../start.php'; FeedReaderCentral\Security::verifyUser(); -// TODO: adapt query when document list is done $field = Field::EQ('user_id', $_SESSION[Key::USER_ID], '@user'); $feeds = Custom::list(Query\Find::byFields(Table::FEED, [$field]) . " ORDER BY lower(data->>'title')", - $field->appendParameter([]), new JsonMapper(Feed::class)); + $field->appendParameter([]), new DocumentMapper(Feed::class)); page_head('Your Feeds'); ?>

Your Feeds

diff --git a/src/public/index.php b/src/public/index.php index 9e400b1..3f9688e 100644 --- a/src/public/index.php +++ b/src/public/index.php @@ -6,7 +6,6 @@ * Displays a list of unread or bookmarked items for the current user */ -use BitBadger\Documents\SQLite\Configuration; use FeedReaderCentral\Feed; use FeedReaderCentral\ItemList; @@ -15,9 +14,7 @@ include '../start.php'; FeedReaderCentral\Security::verifyUser(); if (key_exists('refresh', $_GET)) { - $db = Configuration::dbConn(); - $refreshResult = Feed::refreshAll($db); - $db->close(); + $refreshResult = Feed::refreshAll(); if (key_exists('ok', $refreshResult)) { add_info('All feeds refreshed successfully'); } else { diff --git a/src/public/item.php b/src/public/item.php index 5a6364d..0694fc5 100644 --- a/src/public/item.php +++ b/src/public/item.php @@ -6,9 +6,9 @@ * Retrieves and displays an item from a feed belonging to the current user */ -use BitBadger\Documents\DocumentException; -use BitBadger\Documents\SQLite\Delete; -use BitBadger\Documents\SQLite\Patch; +use BitBadger\PDODocument\DocumentException; +use BitBadger\PDODocument\Delete; +use BitBadger\PDODocument\Patch; use FeedReaderCentral\ItemWithFeed; use FeedReaderCentral\Table; diff --git a/src/util/db-update.php b/src/util/db-update.php index 361e043..3440a40 100644 --- a/src/util/db-update.php +++ b/src/util/db-update.php @@ -1,11 +1,11 @@ query('SELECT * FROM old_user'); + $users = $pdo->query('SELECT * FROM old_user'); if (!$users) throw new DocumentException('Could not retrieve users'); - while ($user = $users->fetchArray(SQLITE3_ASSOC)) { - Document::insert(Table::USER, new User($user['id'], $user['email'], $user['password']), $db); + while ($user = $users->fetch(PDO::FETCH_ASSOC)) { + Document::insert(Table::USER, new User($user['id'], $user['email'], $user['password']), $pdo); } printfn('Migrating feeds...'); - $feeds = $db->query('SELECT * FROM old_feed'); + $feeds = $pdo->query('SELECT * FROM old_feed'); if (!$feeds) throw new DocumentException('Could not retrieve feeds'); - while ($feed = $feeds->fetchArray(SQLITE3_ASSOC)) { + while ($feed = $feeds->fetch(PDO::FETCH_ASSOC)) { Document::insert(Table::FEED, new Feed($feed['id'], $feed['user_id'], $feed['url'], $feed['title'], $feed['updated_on'], - $feed['checked_on']), $db); + $feed['checked_on']), $pdo); } printfn('Migrating items...'); - $items = $db->query('SELECT * FROM old_item'); + $items = $pdo->query('SELECT * FROM old_item'); if (!$items) throw new DocumentException('Could not retrieve items'); - while ($item = $items->fetchArray(SQLITE3_ASSOC)) { + while ($item = $items->fetch(PDO::FETCH_ASSOC)) { Document::insert(Table::ITEM, new Item($item['id'], $item['feed_id'], $item['title'], $item['item_guid'], $item['item_link'], $item['published_on'], $item['updated_on'], $item['content'], $item['is_read'], - $item['is_bookmarked']), $db); + $item['is_bookmarked']), $pdo); } printfn('Dropping old tables...'); - Custom::nonQuery('DROP TABLE old_item', [], $db); - Custom::nonQuery('DROP TABLE old_feed', [], $db); - Custom::nonQuery('DROP TABLE old_user', [], $db); + Custom::nonQuery('DROP TABLE old_item', [], $pdo); + Custom::nonQuery('DROP TABLE old_feed', [], $pdo); + Custom::nonQuery('DROP TABLE old_user', [], $pdo); printfn(PHP_EOL. 'Migration complete!'); } catch (DocumentException $ex) { printfn("ERR $ex"); - } finally { - $db->close(); } } diff --git a/src/util/refresh.php b/src/util/refresh.php index 9bf7ea8..16078d9 100644 --- a/src/util/refresh.php +++ b/src/util/refresh.php @@ -1,8 +1,8 @@ items(), function (Feed $feed) use ($db, &$users) { - $result = Feed::refreshFeed($feed->id, $feed->url, $db); + iterator_apply(Feed::retrieveAll()->items(), function (Feed $feed) use ($pdo, &$users) { + $result = Feed::refreshFeed($feed->id, $feed->url, $pdo); $userKey = "$feed->user_id"; if (!key_exists($userKey, $users)) $users[$userKey] = Find::byId(Table::USER, $feed->user_id, User::class); if (array_key_exists('error', $result)) { @@ -61,7 +61,4 @@ function refresh_all(): void printfn("ERR $ex"); return; } - finally { - $db->close(); - } } diff --git a/src/util/search.php b/src/util/search.php index 048e0f7..526baa8 100644 --- a/src/util/search.php +++ b/src/util/search.php @@ -1,9 +1,9 @@ close(); } } diff --git a/src/util/user.php b/src/util/user.php index a21f5a0..1085cb2 100644 --- a/src/util/user.php +++ b/src/util/user.php @@ -1,14 +1,14 @@