beta4 changes (#26)
These changes are mostly in underlying libraries; however, this now uses the [inspired by F#](https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp) library to handle the feed parsing pipeline and optional return values Reviewed-on: #26
This commit was merged in pull request #26.
This commit is contained in:
+18
-7
@@ -1,4 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
/**
|
||||
* Alpha 7 -> Beta 1 Database Update Utility
|
||||
*
|
||||
* Between these two versions, the data format changed; this utility migrates existing data to its new format.
|
||||
*
|
||||
* _It will be removed in v1.1._
|
||||
*
|
||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use BitBadger\PDODocument\{Custom, Document, DocumentException};
|
||||
use BitBadger\PDODocument\Mapper\{ArrayMapper, ExistsMapper};
|
||||
@@ -8,8 +20,6 @@ require __DIR__ . '/../cli-start.php';
|
||||
|
||||
cli_title('DATABASE UPDATE');
|
||||
|
||||
//const PDO_DOC_DEBUG_SQL = true;
|
||||
|
||||
if ($argc < 2) display_help();
|
||||
|
||||
switch ($argv[1]) {
|
||||
@@ -41,7 +51,8 @@ function display_help(): never
|
||||
function json_column_exists(): bool
|
||||
{
|
||||
try {
|
||||
$table = Custom::single("SELECT sql FROM sqlite_master WHERE tbl_name='frc_user'", [], new ArrayMapper());
|
||||
$table = Custom::single("SELECT sql FROM sqlite_master WHERE tbl_name='frc_user'", [], new ArrayMapper())
|
||||
->getOrDefault(['sql' => '']);
|
||||
return $table && substr_compare(strtolower($table['sql']), 'data text not null', 0) >= 0;
|
||||
} catch (DocumentException $ex) {
|
||||
printfn("ERR $ex");
|
||||
@@ -80,13 +91,13 @@ function run_update(): void
|
||||
$users = Custom::list('SELECT * FROM old_user', [], new ArrayMapper());
|
||||
if (!$users->hasItems()) throw new DocumentException('Could not retrieve users');
|
||||
foreach ($users->items() as $user) {
|
||||
Document::insert(Table::USER, new User($user['id'], $user['email'], $user['password']));
|
||||
Document::insert(Table::User, new User($user['id'], $user['email'], $user['password']));
|
||||
}
|
||||
printfn('Migrating feeds...');
|
||||
$feeds = Custom::list('SELECT * FROM old_feed', [], new ArrayMapper());
|
||||
if (!$feeds->hasItems()) throw new DocumentException('Could not retrieve feeds');
|
||||
foreach ($feeds->items() as $feed) {
|
||||
Document::insert(Table::FEED,
|
||||
Document::insert(Table::Feed,
|
||||
new Feed($feed['id'], $feed['user_id'], $feed['url'], $feed['title'], $feed['updated_on'],
|
||||
$feed['checked_on']));
|
||||
}
|
||||
@@ -94,7 +105,7 @@ function run_update(): void
|
||||
$items = Custom::list('SELECT * FROM old_item', [], new ArrayMapper());
|
||||
if (!$items->hasItems()) throw new DocumentException('Could not retrieve items');
|
||||
foreach ($items->items() as $item) {
|
||||
Document::insert(Table::ITEM,
|
||||
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']));
|
||||
|
||||
+20
-6
@@ -1,5 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
/**
|
||||
* Feed Refresh Utility
|
||||
*
|
||||
* This will refresh all known feeds in the database; it is suitable for executing via cron or as a scheduled task
|
||||
*
|
||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use BitBadger\InspiredByFSharp\Result;
|
||||
use BitBadger\PDODocument\{DocumentException, Find};
|
||||
use FeedReaderCentral\{Feed, Table, User};
|
||||
|
||||
@@ -34,17 +45,20 @@ function refresh_all(): void
|
||||
{
|
||||
try {
|
||||
$users = [];
|
||||
foreach (Feed::retrieveAll()->items() as /** @var Feed $feed */ $feed) {
|
||||
Feed::retrieveAll()->iter(function (Feed $feed) use (&$users) {
|
||||
$result = Feed::refreshFeed($feed->id, $feed->url);
|
||||
$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)) {
|
||||
if (!key_exists($userKey, $users)) {
|
||||
$users[$userKey] = Find::byId(Table::User, $feed->user_id, User::class)
|
||||
->getOrDefault(new User(email: 'user-not-found'));
|
||||
}
|
||||
if ($result->isError()) {
|
||||
printfn('ERR (%s) %s', $users[$userKey]->email, $feed->url);
|
||||
printfn(' %s', $result['error']);
|
||||
printfn(' %s', $result->getError());
|
||||
} else {
|
||||
printfn('OK (%s) %s', $users[$userKey]->email, $feed->url);
|
||||
}
|
||||
}
|
||||
});
|
||||
printfn(PHP_EOL . 'All feeds refreshed');
|
||||
} catch (DocumentException $ex) {
|
||||
printfn("ERR $ex");
|
||||
|
||||
+11
-1
@@ -1,4 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
/**
|
||||
* Search Maintenance Utility
|
||||
*
|
||||
* This allows on-demand refreshing of the search index (should be unnecessary in normal use)
|
||||
*
|
||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use BitBadger\PDODocument\{Custom, DocumentException};
|
||||
use BitBadger\PDODocument\Mapper\ExistsMapper;
|
||||
|
||||
+31
-17
@@ -1,5 +1,17 @@
|
||||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
/**
|
||||
* User Maintenance Utility
|
||||
*
|
||||
* This provides several user maintenance functions for Feed Reader Central; none of these are available through the web
|
||||
* interface
|
||||
*
|
||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use BitBadger\InspiredByFSharp\Option;
|
||||
use BitBadger\PDODocument\{Count, Custom, Delete, DocumentException, Field, Parameters, Patch, Query};
|
||||
use FeedReaderCentral\{Security, Table, User};
|
||||
|
||||
@@ -36,10 +48,10 @@ switch ($argv[1]) {
|
||||
printfn('Missing parameters: set-single-password requires a new password');
|
||||
exit(-1);
|
||||
}
|
||||
set_password(Security::SINGLE_USER_EMAIL, $argv[2]);
|
||||
set_password(Security::SingleUserEmail, $argv[2]);
|
||||
break;
|
||||
case 'reset-single-password':
|
||||
set_password(Security::SINGLE_USER_EMAIL, Security::SINGLE_USER_PASSWORD);
|
||||
set_password(Security::SingleUserEmail, Security::SingleUserPassword);
|
||||
break;
|
||||
case 'migrate-single-user':
|
||||
if ($argc < 4) {
|
||||
@@ -49,7 +61,7 @@ switch ($argv[1]) {
|
||||
migrate_single_user();
|
||||
break;
|
||||
case 'remove-single-user':
|
||||
delete_user(Security::SINGLE_USER_EMAIL);
|
||||
delete_user(Security::SingleUserEmail);
|
||||
break;
|
||||
default:
|
||||
printfn('Unrecognized option "%s"', $argv[1]);
|
||||
@@ -92,7 +104,7 @@ function add_user(): void
|
||||
try {
|
||||
// Ensure there is not already a user with this e-mail address
|
||||
$user = User::findByEmail($argv[2]);
|
||||
if ($user) {
|
||||
if ($user->isSome()) {
|
||||
printfn('A user with e-mail address "%s" already exists', $argv[2]);
|
||||
return;
|
||||
}
|
||||
@@ -113,7 +125,7 @@ function add_user(): void
|
||||
*/
|
||||
function display_user(string $email): string
|
||||
{
|
||||
return $email == Security::SINGLE_USER_EMAIL ? 'single-user mode user' : "user \"$email\"";
|
||||
return $email === Security::SingleUserEmail ? 'single-user mode user' : "user \"$email\"";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,14 +138,14 @@ function set_password(string $email, string $password): void
|
||||
|
||||
// Ensure this user exists
|
||||
$user = User::findByEmail($email);
|
||||
if (!$user) {
|
||||
if ($user->isNone()) {
|
||||
printfn('No %s exists', $displayUser);
|
||||
return;
|
||||
}
|
||||
|
||||
Security::updatePassword($email, $password);
|
||||
|
||||
$msg = $email == Security::SINGLE_USER_EMAIL && $password == Security::SINGLE_USER_PASSWORD
|
||||
$msg = $email === Security::SingleUserEmail && $password === Security::SingleUserPassword
|
||||
? 'reset' : sprintf('set to "%s"', $password);
|
||||
printfn('%s password %s successfully', init_cap($displayUser), $msg);
|
||||
} catch (DocumentException $ex) {
|
||||
@@ -152,14 +164,15 @@ function delete_user(string $email): void
|
||||
$displayUser = display_user($email);
|
||||
|
||||
// Get the user for the provided e-mail address
|
||||
$user = User::findByEmail($email);
|
||||
if (!$user) {
|
||||
$tryUser = User::findByEmail($email);
|
||||
if ($tryUser->isNone()) {
|
||||
printfn('No %s exists', $displayUser);
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $tryUser->get();
|
||||
try {
|
||||
$feedCount = Count::byFields(Table::FEED, [Field::EQ('user_id', $user->id)]);
|
||||
$feedCount = Count::byFields(Table::Feed, [Field::EQ('user_id', $user->id)]);
|
||||
} catch (DocumentException $ex) {
|
||||
printfn("$ex");
|
||||
return;
|
||||
@@ -174,10 +187,10 @@ function delete_user(string $email): void
|
||||
try {
|
||||
$fields = [Field::EQ('user_id', $user->id, ':user')];
|
||||
Custom::nonQuery(
|
||||
'DELETE FROM ' . Table::ITEM . " WHERE data->>'feed_id' IN (SELECT data->>'id' FROM " . Table::FEED
|
||||
'DELETE FROM ' . Table::Item . " WHERE data->>'feed_id' IN (SELECT data->>'id' FROM " . Table::Feed
|
||||
. ' WHERE ' . Query::whereByFields($fields) . ')', Parameters::addFields($fields, []));
|
||||
Delete::byFields(Table::FEED, $fields);
|
||||
Delete::byId(Table::USER, $user->id);
|
||||
Delete::byFields(Table::Feed, $fields);
|
||||
Delete::byId(Table::User, $user->id);
|
||||
|
||||
printfn('%s deleted successfully', init_cap($displayUser));
|
||||
} catch (DocumentException $ex) {
|
||||
@@ -196,13 +209,14 @@ function migrate_single_user(): void
|
||||
global $argv;
|
||||
|
||||
try {
|
||||
if (!$single = User::findByEmail(Security::SINGLE_USER_EMAIL)) {
|
||||
$single = User::findByEmail(Security::SingleUserEmail);
|
||||
if ($single->isNone()) {
|
||||
printfn('There is no single-user mode user to be migrated');
|
||||
return;
|
||||
}
|
||||
|
||||
Patch::byId(Table::USER, $single->id,
|
||||
['email' => $argv[2], 'password' => password_hash($argv[3], Security::PW_ALGORITHM)]);
|
||||
Patch::byId(Table::User, $single->get()->id,
|
||||
['email' => $argv[2], 'password' => password_hash($argv[3], Security::PasswordAlgorithm)]);
|
||||
|
||||
printfn('The single user has been moved to "%s", with password "%s"', $argv[2], $argv[3]);
|
||||
} catch (DocumentException $ex) {
|
||||
|
||||
Reference in New Issue
Block a user