diff --git a/lib/Database.php b/lib/Database.php index 9c4cf7f..f01338a 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -300,24 +300,21 @@ class Database { } public function userPropertiesGet(string $user, bool $includeLarge = true): array { + $basic = $this->db->prepare("SELECT num, admin from arsse_users where id = ?", "str")->run($user)->getRow(); + if (!$basic) { + throw new User\ExceptionConflict("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); + } $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 ($inClause) - union all select 'num', num from arsse_users where id = ? - union all select 'admin', admin from arsse_users where id = ?", - ["str", $inTypes, "str", "str"] - )->run($user, $inValues, $user, $user)->getAll(); - if (!$meta) { - throw new User\ExceptionConflict("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); - } - $meta = array_combine(array_column($meta, "key"), array_column($meta, "value")); + $meta = $this->db->prepare("SELECT \"key\", value from arsse_user_meta where owner = ? and \"key\" not in ($inClause) order by \"key\"", "str", $inTypes)->run($user, $inValues)->getAll(); + $meta = array_merge($basic, array_combine(array_column($meta, "key"), array_column($meta, "value"))); settype($meta['num'], "integer"); + settype($meta['admin'], "integer"); return $meta; - } + } public function userPropertiesSet(string $user, array $data): bool { if (!$this->userExists($user)) { @@ -454,7 +451,7 @@ class Database { /** List tokens associated with a user */ public function tokenList(string $user, string $class): Db\Result { - return $this->db->prepare("SELECT id,created,expires,data from arsse_tokens where class = ? and user = ? and (expires is null or expires > CURRENT_TIMESTAMP)", "str", "str")->run($class, $user); + return $this->db->prepare("SELECT id,created,expires,data from arsse_tokens where class = ? and \"user\" = ? and (expires is null or expires > CURRENT_TIMESTAMP)", "str", "str")->run($class, $user); } /** Deletes expires tokens from the database, returning the number of deleted tokens */ diff --git a/lib/Db/MySQL/Statement.php b/lib/Db/MySQL/Statement.php index 057225a..aba3542 100644 --- a/lib/Db/MySQL/Statement.php +++ b/lib/Db/MySQL/Statement.php @@ -84,7 +84,11 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement { } // create a result-set instance $r = $this->st->get_result(); - $changes = $this->st->affected_rows; + if (preg_match("\d+", mysqli_info($this->db), $m)) { + $changes = (int) $m[0]; + } else { + $changes = 0; + } $lastId = $this->st->insert_id; return new Result($r, [$changes, $lastId], $this); } diff --git a/sql/MySQL/6.sql b/sql/MySQL/6.sql index aeb7c12..23ba5ed 100644 --- a/sql/MySQL/6.sql +++ b/sql/MySQL/6.sql @@ -24,8 +24,8 @@ create table arsse_user_meta( "key" varchar(255) not null, value longtext, foreign key(owner) references arsse_users(id) on delete cascade on update cascade, - primary key(owner,key) -); + primary key(owner,"key") +) character set utf8mb4 collate utf8mb4_unicode_ci; create table arsse_icons( id serial primary key, diff --git a/tests/cases/Database/SeriesUser.php b/tests/cases/Database/SeriesUser.php index bf78cf8..9ca140c 100644 --- a/tests/cases/Database/SeriesUser.php +++ b/tests/cases/Database/SeriesUser.php @@ -125,12 +125,12 @@ trait SeriesUser { public function provideMetadata(): iterable { return [ - ["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']], + ["admin@example.net", true, ['num' => 1, 'admin' => 1, 'lang' => "en", 'sort_asc' => "0", 'tz' => "America/Toronto"]], + ["jane.doe@example.com", true, ['num' => 2, 'admin' => 0, 'lang' => "fr", 'sort_asc' => "1", 'tz' => "Asia/Kuala_Lumpur"]], + ["john.doe@example.com", true, ['num' => 3, 'admin' => 0, 'stylesheet' => "body {background:lightgray}"]], + ["admin@example.net", false, ['num' => 1, 'admin' => 1, 'lang' => "en", 'sort_asc' => "0", 'tz' => "America/Toronto"]], + ["jane.doe@example.com", false, ['num' => 2, 'admin' => 0, 'lang' => "fr", 'sort_asc' => "1", 'tz' => "Asia/Kuala_Lumpur"]], + ["john.doe@example.com", false, ['num' => 3, 'admin' => 0]], ]; }