From fcf1260dab61336c7e0a2316e913cf418048997f Mon Sep 17 00:00:00 2001 From: "J. King" Date: Sat, 5 Dec 2020 22:13:48 -0500 Subject: [PATCH] Adjust database portion of user property manager --- lib/Database.php | 13 ++++++++---- lib/User.php | 1 + lib/User/Internal/Driver.php | 2 +- sql/SQLite3/6.sql | 2 +- tests/cases/Database/SeriesUser.php | 31 ++++++++++++++++++----------- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/Database.php b/lib/Database.php index 9135b20..9c4cf7f 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -300,12 +300,17 @@ class Database { } public function userPropertiesGet(string $user, bool $includeLarge = true): array { + $exclude = ["num", "admin"]; + if (!$includeLarge) { + $exclude = array_merge($exclude, User::PROPERTIES_LARGE); + } + [$inClause, $inTypes, $inValues] = $this->generateIn($exclude, "str"); $meta = $this->db->prepareArray( - "SELECT \"key\", value from arsse_user_meta where owner = ? and \"key\" not in ('num', 'admin') + "SELECT \"key\", value from arsse_user_meta where owner = ? and \"key\" not in ($inClause) union all select 'num', num from arsse_users where id = ? union all select 'admin', admin from arsse_users where id = ?", - ["str", "str", "str"] - )->run($user)->getRow(); + ["str", $inTypes, "str", "str"] + )->run($user, $inValues, $user, $user)->getAll(); if (!$meta) { throw new User\ExceptionConflict("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); } @@ -322,7 +327,7 @@ class Database { $insert = ["INSERT INTO arsse_user_meta values(?, ?, ?)", "str", "strict str", "str"]; foreach ($data as $k => $v) { if ($k === "admin") { - $this->db->prepare("UPDATE arsse_users SET admin = ? where user = ?", "bool", "str")->run($v, $user); + $this->db->prepare("UPDATE arsse_users SET admin = ? where id = ?", "bool", "str")->run($v, $user); } elseif ($k === "num") { continue; } else { diff --git a/lib/User.php b/lib/User.php index 48d7c27..124fd23 100644 --- a/lib/User.php +++ b/lib/User.php @@ -26,6 +26,7 @@ class User { 'stylesheet' => V::T_STRING, 'reading_time' => V::T_BOOL, ]; + public const PROPERTIES_LARGE = ["stylesheet"]; public $id = null; diff --git a/lib/User/Internal/Driver.php b/lib/User/Internal/Driver.php index c6d0a98..27486fb 100644 --- a/lib/User/Internal/Driver.php +++ b/lib/User/Internal/Driver.php @@ -71,7 +71,7 @@ class Driver implements \JKingWeb\Arsse\User\Driver { return Arsse::$db->userExists($user); } - public function userPropertiesGet(string $user): array { + public function userPropertiesGet(string $user, bool $includeLarge = true): array { // do nothing: the internal database will retrieve everything for us if (!$this->userExists($user)) { throw new ExceptionConflict("doesNotExist", ['action' => "userPasswordUnset", 'user' => $user]); diff --git a/sql/SQLite3/6.sql b/sql/SQLite3/6.sql index 5f06722..9e86182 100644 --- a/sql/SQLite3/6.sql +++ b/sql/SQLite3/6.sql @@ -13,7 +13,7 @@ create table arsse_users_new( id text primary key not null collate nocase, -- user id password text, -- password, salted and hashed; if using external authentication this would be blank num integer unique not null, -- numeric identfier used by Miniflux - admin boolean not null default 0, -- Whether the user is an administrator + admin boolean not null default 0 -- Whether the user is an administrator ) without rowid; create temp table arsse_users_existing( id text not null, diff --git a/tests/cases/Database/SeriesUser.php b/tests/cases/Database/SeriesUser.php index a3d5507..bf78cf8 100644 --- a/tests/cases/Database/SeriesUser.php +++ b/tests/cases/Database/SeriesUser.php @@ -33,10 +33,11 @@ trait SeriesUser { 'rows' => [ ["admin@example.net", "lang", "en"], ["admin@example.net", "tz", "America/Toronto"], - ["admin@example.net", "sort", "desc"], + ["admin@example.net", "sort_asc", "0"], ["jane.doe@example.com", "lang", "fr"], ["jane.doe@example.com", "tz", "Asia/Kuala_Lumpur"], - ["jane.doe@example.com", "sort", "asc"], + ["jane.doe@example.com", "sort_asc", "1"], + ["john.doe@example.com", "stylesheet", "body {background:lightgray}"], ], ], ]; @@ -118,15 +119,18 @@ trait SeriesUser { } /** @dataProvider provideMetaData */ - public function testGetMetadata(string $user, array $exp): void { - $this->assertSame($exp, Arsse::$db->userPropertiesGet($user)); + public function testGetMetadata(string $user, bool $includeLarge, array $exp): void { + $this->assertSame($exp, Arsse::$db->userPropertiesGet($user, $includeLarge)); } public function provideMetadata(): iterable { return [ - ["admin@example.net", ['num' => 1, 'admin' => true, 'lang' => "en", 'tz' => "America/Toronto", 'sort_asc' => false]], - ["jane.doe@example.com", ['num' => 2, 'admin' => false, 'lang' => "fr", 'tz' => "Asia/Kuala_Lumpur", 'sort_asc' => true]], - ["john.doe@example.com", ['num' => 3, 'admin' => false, 'lang' => null, 'tz' => "Etc/UTC", 'sort_asc' => false]], + ["admin@example.net", true, ['lang' => "en", 'sort_asc' => "0", 'tz' => "America/Toronto", 'num' => 1, 'admin' => '1']], + ["jane.doe@example.com", true, ['lang' => "fr", 'sort_asc' => "1", 'tz' => "Asia/Kuala_Lumpur", 'num' => 2, 'admin' => '0']], + ["john.doe@example.com", true, ['stylesheet' => "body {background:lightgray}", 'num' => 3, 'admin' => '0']], + ["admin@example.net", false, ['lang' => "en", 'sort_asc' => "0", 'tz' => "America/Toronto", 'num' => 1, 'admin' => '1']], + ["jane.doe@example.com", false, ['lang' => "fr", 'sort_asc' => "1", 'tz' => "Asia/Kuala_Lumpur", 'num' => 2, 'admin' => '0']], + ["john.doe@example.com", false, ['num' => 3, 'admin' => '0']], ]; } @@ -143,18 +147,21 @@ trait SeriesUser { 'sort_asc' => true, ]; $this->assertTrue(Arsse::$db->userPropertiesSet("john.doe@example.com", $in)); - $state = $this->primeExpectations($this->data, ['arsse_users' => ['id', 'num', 'admin', 'lang', 'tz', 'sort_asc']]); - $state['arsse_users']['rows'][2] = ["john.doe@example.com", 3, 1, "en-ca", "Atlantic/Reykjavik", 1]; + $state = $this->primeExpectations($this->data, ['arsse_users' => ['id', 'num', 'admin'], 'arsse_user_meta' => ["owner", "key", "value"]]); + $state['arsse_users']['rows'][2][2] = 1; + $state['arsse_user_meta']['rows'][] = ["john.doe@example.com", "lang", "en-ca"]; + $state['arsse_user_meta']['rows'][] = ["john.doe@example.com", "tz", "Atlantic/Reykjavik"]; + $state['arsse_user_meta']['rows'][] = ["john.doe@example.com", "sort_asc", "1"]; $this->compareExpectations(static::$drv, $state); } public function testSetNoMetadata(): void { $in = [ 'num' => 2112, - 'blah' => "bloo", + 'stylesheet' => "body {background:lightgray}", ]; - $this->assertFalse(Arsse::$db->userPropertiesSet("john.doe@example.com", $in)); - $state = $this->primeExpectations($this->data, ['arsse_users' => ['id', 'num', 'admin', 'lang', 'tz', 'sort_asc']]); + $this->assertTrue(Arsse::$db->userPropertiesSet("john.doe@example.com", $in)); + $state = $this->primeExpectations($this->data, ['arsse_users' => ['id', 'num', 'admin'], 'arsse_user_meta' => ["owner", "key", "value"]]); $this->compareExpectations(static::$drv, $state); }