Browse Source

Avoid use of reserved SQL word "user"

microsub
J. King 5 years ago
parent
commit
dd4f22e04e
  1. 34
      lib/Database.php
  2. 2
      tests/cases/Db/PostgreSQL/TestDatabase.php

34
lib/Database.php

@ -182,7 +182,7 @@ class Database {
$id = UUID::mint()->hex; $id = UUID::mint()->hex;
$expires = Date::add(Arsse::$conf->userSessionTimeout); $expires = Date::add(Arsse::$conf->userSessionTimeout);
// save the session to the database // save the session to the database
$this->db->prepare("INSERT INTO arsse_sessions(id,expires,user) values(?,?,?)", "str", "datetime", "str")->run($id, $expires, $user); $this->db->prepare("INSERT INTO arsse_sessions(id,expires,\"user\") values(?,?,?)", "str", "datetime", "str")->run($id, $expires, $user);
// return the ID // return the ID
return $id; return $id;
} }
@ -193,12 +193,12 @@ class Database {
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
} }
// delete the session and report success. // delete the session and report success.
return (bool) $this->db->prepare("DELETE FROM arsse_sessions where id = ? and user = ?", "str", "str")->run($id, $user)->changes(); return (bool) $this->db->prepare("DELETE FROM arsse_sessions where id = ? and \"user\" = ?", "str", "str")->run($id, $user)->changes();
} }
public function sessionResume(string $id): array { public function sessionResume(string $id): array {
$maxAge = Date::sub(Arsse::$conf->userSessionLifetime); $maxAge = Date::sub(Arsse::$conf->userSessionLifetime);
$out = $this->db->prepare("SELECT id,created,expires,user from arsse_sessions where id = ? and expires > CURRENT_TIMESTAMP and created > ?", "str", "datetime")->run($id, $maxAge)->getRow(); $out = $this->db->prepare("SELECT id,created,expires,\"user\" from arsse_sessions where id = ? and expires > CURRENT_TIMESTAMP and created > ?", "str", "datetime")->run($id, $maxAge)->getRow();
// if the session does not exist or is expired, throw an exception // if the session does not exist or is expired, throw an exception
if (!$out) { if (!$out) {
throw new User\ExceptionSession("invalid", $id); throw new User\ExceptionSession("invalid", $id);
@ -371,11 +371,11 @@ class Database {
// SQL will happily accept duplicates (null is not unique), so we must do this check ourselves // SQL will happily accept duplicates (null is not unique), so we must do this check ourselves
$p = $this->db->prepare( $p = $this->db->prepare(
"WITH RECURSIVE "WITH RECURSIVE
target as (select ? as user, ? as source, ? as dest, ? as rename), target as (select ? as userid, ? as source, ? as dest, ? as rename),
folders as (SELECT id from arsse_folders join target on owner = user and coalesce(parent,0) = source union select arsse_folders.id as id from arsse_folders join folders on arsse_folders.parent=folders.id) folders as (SELECT id from arsse_folders join target on owner = userid and coalesce(parent,0) = source union select arsse_folders.id as id from arsse_folders join folders on arsse_folders.parent=folders.id)
". ".
"SELECT "SELECT
((select dest from target) is null or exists(select id from arsse_folders join target on owner = user and coalesce(id,0) = coalesce(dest,0))) as extant, ((select dest from target) is null or exists(select id from arsse_folders join target on owner = userid and coalesce(id,0) = coalesce(dest,0))) as extant,
not exists(select id from folders where id = coalesce((select dest from target),0)) as valid, not exists(select id from folders where id = coalesce((select dest from target),0)) as valid,
not exists(select id from arsse_folders join target on coalesce(parent,0) = coalesce(dest,0) and name = coalesce((select rename from target),(select name from arsse_folders join target on id = source))) as available not exists(select id from arsse_folders join target on coalesce(parent,0) = coalesce(dest,0) and name = coalesce((select rename from target),(select name from arsse_folders join target on id = source))) as available
", ",
@ -462,15 +462,15 @@ class Database {
coalesce(arsse_subscriptions.title, arsse_feeds.title) as title, coalesce(arsse_subscriptions.title, arsse_feeds.title) as title,
(SELECT count(*) from arsse_articles where feed = arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks where subscription = arsse_subscriptions.id and read = 1) as unread (SELECT count(*) from arsse_articles where feed = arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks where subscription = arsse_subscriptions.id and read = 1) as unread
from arsse_subscriptions from arsse_subscriptions
join user on user = owner join userdata on userid = owner
join arsse_feeds on feed = arsse_feeds.id join arsse_feeds on feed = arsse_feeds.id
left join topmost on folder=f_id" left join topmost on folder=f_id"
); );
$q->setOrder("pinned desc, title collate nocase"); $q->setOrder("pinned desc, title collate nocase");
// define common table expressions // define common table expressions
$q->setCTE("user(user)", "SELECT ?", "str", $user); // the subject user; this way we only have to pass it to prepare() once $q->setCTE("userdata(userid)", "SELECT ?", "str", $user); // the subject user; this way we only have to pass it to prepare() once
// topmost folders belonging to the user // topmost folders belonging to the user
$q->setCTE("topmost(f_id,top)", "SELECT id,id from arsse_folders join user on owner = user where parent is null union select id,top from arsse_folders join topmost on parent=f_id"); $q->setCTE("topmost(f_id,top)", "SELECT id,id from arsse_folders join userdata on owner = userid where parent is null union select id,top from arsse_folders join topmost on parent=f_id");
if ($id) { if ($id) {
// this condition facilitates the implementation of subscriptionPropertiesGet, which would otherwise have to duplicate the complex query; it takes precedence over a specified folder // this condition facilitates the implementation of subscriptionPropertiesGet, which would otherwise have to duplicate the complex query; it takes precedence over a specified folder
// if an ID is specified, add a suitable WHERE condition and bindings // if an ID is specified, add a suitable WHERE condition and bindings
@ -818,7 +818,7 @@ class Database {
FROM arsse_articles" FROM arsse_articles"
); );
$q->setLimit($context->limit, $context->offset); $q->setLimit($context->limit, $context->offset);
$q->setCTE("user(user)", "SELECT ?", "str", $user); $q->setCTE("userdata(userid)", "SELECT ?", "str", $user);
if ($context->subscription()) { if ($context->subscription()) {
// if a subscription is specified, make sure it exists // if a subscription is specified, make sure it exists
$id = $this->subscriptionValidateId($user, $context->subscription)['feed']; $id = $this->subscriptionValidateId($user, $context->subscription)['feed'];
@ -830,15 +830,15 @@ class Database {
// if it does exist, add a common table expression to list it and its children so that we select from the entire subtree // if it does exist, add a common table expression to list it and its children so that we select from the entire subtree
$q->setCTE("folders(folder)", "SELECT ? union select id from arsse_folders join folders on parent = folder", "int", $context->folder); $q->setCTE("folders(folder)", "SELECT ? union select id from arsse_folders join folders on parent = folder", "int", $context->folder);
// add another CTE for the subscriptions within the folder // add another CTE for the subscriptions within the folder
$q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join user on user = owner join folders on arsse_subscriptions.folder = folders.folder", [], [], "join subscribed_feeds on feed = subscribed_feeds.id"); $q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join userdata on userid = owner join folders on arsse_subscriptions.folder = folders.folder", [], [], "join subscribed_feeds on feed = subscribed_feeds.id");
} elseif ($context->folderShallow()) { } elseif ($context->folderShallow()) {
// if a shallow folder is specified, make sure it exists // if a shallow folder is specified, make sure it exists
$this->folderValidateId($user, $context->folderShallow); $this->folderValidateId($user, $context->folderShallow);
// if it does exist, add a CTE with only its subscriptions (and not those of its descendents) // if it does exist, add a CTE with only its subscriptions (and not those of its descendents)
$q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join user on user = owner and coalesce(folder,0) = ?", "strict int", $context->folderShallow, "join subscribed_feeds on feed = subscribed_feeds.id"); $q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join userdata on userid = owner and coalesce(folder,0) = ?", "strict int", $context->folderShallow, "join subscribed_feeds on feed = subscribed_feeds.id");
} else { } else {
// otherwise add a CTE for all the user's subscriptions // otherwise add a CTE for all the user's subscriptions
$q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join user on user = owner", [], [], "join subscribed_feeds on feed = subscribed_feeds.id"); $q->setCTE("subscribed_feeds(id,sub)", "SELECT feed,id from arsse_subscriptions join userdata on userid = owner", [], [], "join subscribed_feeds on feed = subscribed_feeds.id");
} }
if ($context->edition()) { if ($context->edition()) {
// if an edition is specified, filter for its previously identified article // if an edition is specified, filter for its previously identified article
@ -1075,7 +1075,7 @@ class Database {
and article in (select id from target_articles where to_insert = 0 and (honour_read = 1 or honour_star = 1 or (select note from target_values) is not null))", and article in (select id from target_articles where to_insert = 0 and (honour_read = 1 or honour_star = 1 or (select note from target_values) is not null))",
"INSERT INTO arsse_marks(subscription,article,read,starred,note) "INSERT INTO arsse_marks(subscription,article,read,starred,note)
select select
(select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed), (select id from arsse_subscriptions join userdata on userid = owner where arsse_subscriptions.feed = target_articles.feed),
id, id,
coalesce((select read from target_values) * honour_read,0), coalesce((select read from target_values) * honour_read,0),
coalesce((select starred from target_values),0), coalesce((select starred from target_values),0),
@ -1262,8 +1262,8 @@ class Database {
// a simple WHERE clause is required here // a simple WHERE clause is required here
$q->setWhere("arsse_feeds.id = ?", "int", $id); $q->setWhere("arsse_feeds.id = ?", "int", $id);
} else { } else {
$q->setCTE("user(user)", "SELECT ?", "str", $user); $q->setCTE("userdata(userid)", "SELECT ?", "str", $user);
$q->setCTE("feeds(feed)", "SELECT feed from arsse_subscriptions join user on user = owner", [], [], "join feeds on arsse_articles.feed = feeds.feed"); $q->setCTE("feeds(feed)", "SELECT feed from arsse_subscriptions join userdata on userid = owner", [], [], "join feeds on arsse_articles.feed = feeds.feed");
} }
return (int) $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue(); return (int) $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue();
} }
@ -1415,7 +1415,7 @@ class Database {
arsse_label_members(label,article,subscription) arsse_label_members(label,article,subscription)
SELECT SELECT
?,id, ?,id,
(select id from arsse_subscriptions join user on user = owner where arsse_subscriptions.feed = target_articles.feed) (select id from arsse_subscriptions join userdata on userid = owner where arsse_subscriptions.feed = target_articles.feed)
FROM target_articles", FROM target_articles",
"int", "int",
$id $id

2
tests/cases/Db/PostgreSQL/TestDatabase.php

@ -14,6 +14,6 @@ class TestDatabase extends \JKingWeb\Arsse\TestCase\Database\Base {
protected static $implementation = "PDO PostgreSQL"; protected static $implementation = "PDO PostgreSQL";
protected function nextID(string $table): int { protected function nextID(string $table): int {
return static::$drv->query("SELECT select cast(last_value as bigint) + 1 from pg_sequences where sequencename = '{$table}_id_seq'")->getValue(); return (int) static::$drv->query("SELECT cast(last_value as bigint) + 1 from pg_sequences where sequencename = '{$table}_id_seq'")->getValue();
} }
} }

Loading…
Cancel
Save