From f9430175c6b35c4fc3d932d07f933d0570a16c65 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Jan 2021 07:10:04 +0000 Subject: [PATCH] Avoid multiple lines in post-view, added thread view --- database.sql | 168 +++++++++++++++++++++++++++++++++- src/Model/Item.php | 2 +- src/Model/Post.php | 98 +++++++++++++++++--- static/dbstructure.config.php | 2 +- static/dbview.config.php | 165 ++++++++++++++++++++++++++++++++- 5 files changed, 415 insertions(+), 20 deletions(-) diff --git a/database.sql b/database.sql index 985a642110..a0cc74d591 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2021.03-dev (Red Hot Poker) --- DB_UPDATE_VERSION 1389 +-- DB_UPDATE_VERSION 1390 -- ------------------------------------------ @@ -1646,7 +1646,171 @@ CREATE VIEW `post-view` AS SELECT LEFT JOIN `item-content` ON `item-content`.`uri-id` = `item`.`uri-id` LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `item`.`uri-id` AND `item`.`origin` LEFT JOIN `permissionset` ON `permissionset`.`id` = `item`.`psid` - STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` + STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` AND `parent-item`.`uid` = `item`.`uid` + STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`; + +-- +-- VIEW post-thread-view +-- +DROP VIEW IF EXISTS `post-thread-view`; +CREATE VIEW `post-thread-view` AS SELECT + `item`.`id` AS `id`, + `thread`.`iid` AS `iid`, + `item`.`id` AS `item_id`, + `thread`.`uid` AS `uid`, + `item`.`uid` AS `internal-uid`, + `item`.`parent` AS `parent`, + `item`.`uri` AS `uri`, + `item`.`uri-id` AS `uri-id`, + `item`.`uri-id` AS `internal-uri-id`, + `item`.`parent-uri` AS `parent-uri`, + `item`.`parent-uri-id` AS `parent-uri-id`, + `item`.`thr-parent` AS `thr-parent`, + `item`.`thr-parent-id` AS `thr-parent-id`, + `item`.`guid` AS `guid`, + `item`.`type` AS `type`, + `thread`.`wall` AS `wall`, + `item`.`gravity` AS `gravity`, + `item`.`extid` AS `extid`, + `thread`.`created` AS `created`, + `thread`.`edited` AS `edited`, + `thread`.`commented` AS `commented`, + `thread`.`received` AS `received`, + `thread`.`changed` AS `changed`, + `item`.`resource-id` AS `resource-id`, + `thread`.`post-type` AS `post-type`, + `thread`.`private` AS `private`, + `thread`.`pubmail` AS `pubmail`, + `thread`.`moderated` AS `moderated`, + `thread`.`ignored` AS `ignored`, + `thread`.`visible` AS `visible`, + `thread`.`starred` AS `starred`, + `item`.`bookmark` AS `bookmark`, + `item`.`unseen` AS `unseen`, + `thread`.`deleted` AS `deleted`, + `thread`.`origin` AS `origin`, + `thread`.`forum_mode` AS `forum_mode`, + `thread`.`mention` AS `mention`, + `item`.`global` AS `global`, + `thread`.`network` AS `network`, + `item`.`icid` AS `icid`, + `item`.`vid` AS `vid`, + `item`.`psid` AS `psid`, + `item`.`attach` AS `attach`, + (SELECT COUNT(*) FROM `post-category` WHERE `post-category`.`uri-id` = `item`.`uri-id`) AS `internal-file-count`, + NULL AS `file`, + IF (`item`.`vid` IS NULL, '', `verb`.`name`) AS `verb`, + `item-content`.`title` AS `title`, + `item-content`.`content-warning` AS `content-warning`, + `item-content`.`raw-body` AS `raw-body`, + `item-content`.`body` AS `body`, + `item-content`.`rendered-hash` AS `rendered-hash`, + `item-content`.`rendered-html` AS `rendered-html`, + `item-content`.`language` AS `language`, + `item-content`.`plink` AS `plink`, + `item-content`.`location` AS `location`, + `item-content`.`coord` AS `coord`, + `item-content`.`app` AS `app`, + `item-content`.`object-type` AS `object-type`, + `item-content`.`object` AS `object`, + `item-content`.`target-type` AS `target-type`, + `item-content`.`target` AS `target`, + `thread`.`contact-id` AS `contact-id`, + `contact`.`url` AS `contact-link`, + `contact`.`addr` AS `contact-addr`, + `contact`.`name` AS `contact-name`, + `contact`.`nick` AS `contact-nick`, + `contact`.`thumb` AS `contact-avatar`, + `contact`.`network` AS `contact-network`, + `contact`.`blocked` AS `contact-blocked`, + `contact`.`hidden` AS `contact-hidden`, + `contact`.`readonly` AS `contact-readonly`, + `contact`.`archive` AS `contact-archive`, + `contact`.`pending` AS `contact-pending`, + `contact`.`rel` AS `contact-rel`, + `contact`.`uid` AS `contact-uid`, + `contact`.`contact-type` AS `contact-contact-type`, + IF (`item`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`, + `contact`.`self` AS `self`, + `contact`.`id` AS `cid`, + `contact`.`alias` AS `alias`, + `contact`.`photo` AS `photo`, + `contact`.`name-date` AS `name-date`, + `contact`.`uri-date` AS `uri-date`, + `contact`.`avatar-date` AS `avatar-date`, + `contact`.`thumb` AS `thumb`, + `contact`.`dfrn-id` AS `dfrn-id`, + `group_member`.`gid` AS `group-id`, + `thread`.`author-id` AS `author-id`, + `author`.`url` AS `author-link`, + `author`.`addr` AS `author-addr`, + IF (`contact`.`url` = `author`.`url`, `contact`.`name`, `author`.`name`) AS `author-name`, + `author`.`nick` AS `author-nick`, + IF (`contact`.`url` = `author`.`url`, `contact`.`thumb`, `author`.`thumb`) AS `author-avatar`, + `author`.`network` AS `author-network`, + `author`.`blocked` AS `author-blocked`, + `author`.`hidden` AS `author-hidden`, + `thread`.`owner-id` AS `owner-id`, + `owner`.`url` AS `owner-link`, + `owner`.`addr` AS `owner-addr`, + IF (`contact`.`url` = `owner`.`url`, `contact`.`name`, `owner`.`name`) AS `owner-name`, + `owner`.`nick` AS `owner-nick`, + IF (`contact`.`url` = `owner`.`url`, `contact`.`thumb`, `owner`.`thumb`) AS `owner-avatar`, + `owner`.`network` AS `owner-network`, + `owner`.`blocked` AS `owner-blocked`, + `owner`.`hidden` AS `owner-hidden`, + `item`.`causer-id` AS `causer-id`, + `causer`.`url` AS `causer-link`, + `causer`.`addr` AS `causer-addr`, + `causer`.`name` AS `causer-name`, + `causer`.`nick` AS `causer-nick`, + `causer`.`thumb` AS `causer-avatar`, + `causer`.`network` AS `causer-network`, + `causer`.`blocked` AS `causer-blocked`, + `causer`.`hidden` AS `causer-hidden`, + `causer`.`contact-type` AS `causer-contact-type`, + `post-delivery-data`.`postopts` AS `postopts`, + `post-delivery-data`.`inform` AS `inform`, + `post-delivery-data`.`queue_count` AS `delivery_queue_count`, + `post-delivery-data`.`queue_done` AS `delivery_queue_done`, + `post-delivery-data`.`queue_failed` AS `delivery_queue_failed`, + IF (`item`.`psid` IS NULL, '', `permissionset`.`allow_cid`) AS `allow_cid`, + IF (`item`.`psid` IS NULL, '', `permissionset`.`allow_gid`) AS `allow_gid`, + IF (`item`.`psid` IS NULL, '', `permissionset`.`deny_cid`) AS `deny_cid`, + IF (`item`.`psid` IS NULL, '', `permissionset`.`deny_gid`) AS `deny_gid`, + `item`.`event-id` AS `event-id`, + `event`.`created` AS `event-created`, + `event`.`edited` AS `event-edited`, + `event`.`start` AS `event-start`, + `event`.`finish` AS `event-finish`, + `event`.`summary` AS `event-summary`, + `event`.`desc` AS `event-desc`, + `event`.`location` AS `event-location`, + `event`.`type` AS `event-type`, + `event`.`nofinish` AS `event-nofinish`, + `event`.`adjust` AS `event-adjust`, + `event`.`ignore` AS `event-ignore`, + `diaspora-interaction`.`interaction` AS `signed_text`, + `parent-item`.`guid` AS `parent-guid`, + `parent-item`.`network` AS `parent-network`, + `parent-item`.`author-id` AS `parent-author-id`, + `parent-item-author`.`url` AS `parent-author-link`, + `parent-item-author`.`name` AS `parent-author-name`, + `parent-item-author`.`network` AS `parent-author-network` + FROM `thread` + STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id` + STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `thread`.`author-id` + STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `thread`.`owner-id` + STRAIGHT_JOIN `contact` AS `causer` ON `causer`.`id` = `item`.`causer-id` + LEFT JOIN `group_member` ON `group_member`.`contact-id` = `thread`.`contact-id` + LEFT JOIN `verb` ON `verb`.`id` = `item`.`vid` + LEFT JOIN `event` ON `event`.`id` = `item`.`event-id` + LEFT JOIN `diaspora-interaction` ON `diaspora-interaction`.`uri-id` = `thread`.`uri-id` + LEFT JOIN `item-content` ON `item-content`.`uri-id` = `thread`.`uri-id` + LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `thread`.`uri-id` AND `thread`.`origin` + LEFT JOIN `permissionset` ON `permissionset`.`id` = `item`.`psid` + STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` AND `parent-item`.`uid` = `item`.`uid` STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`; -- diff --git a/src/Model/Item.php b/src/Model/Item.php index c8677d8425..888a81831a 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -217,7 +217,7 @@ class Item * @return array|false current row or false * @throws \Exception */ - private static function fetch($stmt) + public static function fetch($stmt) { $row = DBA::fetch($stmt); diff --git a/src/Model/Post.php b/src/Model/Post.php index 52b801de3c..9efdbfe14f 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -189,6 +189,36 @@ class Post return $data; } + /** + * Select rows from the given view + * + * @param string $view View (post-view or post-thread-view) + * @param array $selected Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * + * @return boolean|object + * @throws \Exception + */ + private static function selectView(string $view, array $selected = [], array $condition = [], $params = []) + { + if (empty($selected)) { + $selected = array_merge(['author-addr', 'author-nick', 'owner-addr', 'owner-nick', 'causer-addr', 'causer-nick', + 'causer-network', 'photo', 'name-date', 'uri-date', 'avatar-date', 'thumb', 'dfrn-id', + 'parent-guid', 'parent-network', 'parent-author-id', 'parent-author-link', 'parent-author-name', + 'parent-author-network', 'signed_text'], Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST, Item::CONTENT_FIELDLIST); + + if ($view == 'post-thread-view') { + $selected = array_merge($selected, ['ignored', 'iid']); + } + } + + $selected = array_merge($selected, ['internal-uri-id', 'internal-uid', 'internal-file-count']); + $selected = array_unique($selected); + + return DBA::select($view, $selected, $condition, $params); + } + /** * Select rows from the post table * @@ -201,22 +231,28 @@ class Post */ public static function select(array $selected = [], array $condition = [], $params = []) { - if (empty($selected)) { - $selected = array_merge(['author-addr', 'author-nick', 'owner-addr', 'owner-nick', 'causer-addr', 'causer-nick', - 'causer-network', 'photo', 'name-date', 'uri-date', 'avatar-date', 'thumb', 'dfrn-id', - 'parent-guid', 'parent-network', 'parent-author-id', 'parent-author-link', 'parent-author-name', - 'parent-author-network', 'signed_text'], Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST, Item::CONTENT_FIELDLIST); - } - - $selected = array_merge($selected, ['internal-uri-id', 'internal-uid', 'internal-file-count']); - $selected = array_unique($selected); - - return DBA::select('post-view', $selected, $condition, $params); + return self::selectView('post-view', $selected, $condition, $params); } /** - * Select rows from the post view for a given user + * Select rows from the post table * + * @param array $selected Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * + * @return boolean|object + * @throws \Exception + */ + public static function selectThread(array $selected = [], array $condition = [], $params = []) + { + return self::selectView('post-thread-view', $selected, $condition, $params); + } + + /** + * Select rows from the given view for a given user + * + * @param string $view View (post-view or post-thread-view) * @param integer $uid User ID * @param array $selected Array of selected fields, empty for all * @param array $condition Array of fields for condition @@ -225,7 +261,7 @@ class Post * @return boolean|object * @throws \Exception */ - public static function selectForUser($uid, array $selected = [], array $condition = [], $params = []) + private static function selectViewForUser(string $view, $uid, array $selected = [], array $condition = [], $params = []) { if (empty($selected)) { $selected = Item::DISPLAY_FIELDLIST; @@ -253,7 +289,7 @@ class Post unset($selected['pinned']); $selected = array_flip($selected); - $select_string = '(SELECT `pinned` FROM `user-item` WHERE `iid` = `post-view`.`id` AND uid=`post-view`.`uid`) AS `pinned`, '; + $select_string = "(SELECT `pinned` FROM `user-item` WHERE `iid` = `" . $view . "`.`id` AND uid=`" . $view . "`.`uid`) AS `pinned`, "; } $select_string .= implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected)); @@ -261,12 +297,44 @@ class Post $condition_string = DBA::buildCondition($condition); $param_string = DBA::buildParameter($params); - $sql = "SELECT " . $select_string . " FROM `post-view` " . $condition_string . $param_string; + $sql = "SELECT " . $select_string . " FROM `" . $view . "` " . $condition_string . $param_string; $sql = DBA::cleanQuery($sql); return DBA::p($sql, $condition); } + /** + * Select rows from the post view for a given user + * + * @param integer $uid User ID + * @param array $selected Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * + * @return boolean|object + * @throws \Exception + */ + public static function selectForUser($uid, array $selected = [], array $condition = [], $params = []) + { + return self::selectViewForUser('post-view', $uid, $selected, $condition, $params); + } + + /** + * Select rows from the post view for a given user + * + * @param integer $uid User ID + * @param array $selected Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * + * @return boolean|object + * @throws \Exception + */ + public static function selectThreadForUser($uid, array $selected = [], array $condition = [], $params = []) + { + return self::selectViewForUser('post-thread-view', $uid, $selected, $condition, $params); + } + /** * Retrieve a single record from the post view for a given user and returns it in an associative array * diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 8012c36075..77b57bfb95 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1389); + define('DB_UPDATE_VERSION', 1390); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 5f9c1d34cf..7ef0807803 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -193,7 +193,170 @@ LEFT JOIN `item-content` ON `item-content`.`uri-id` = `item`.`uri-id` LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `item`.`uri-id` AND `item`.`origin` LEFT JOIN `permissionset` ON `permissionset`.`id` = `item`.`psid` - STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` + STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` AND `parent-item`.`uid` = `item`.`uid` + STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`" + ], + "post-thread-view" => [ + "fields" => [ + "id" => ["item", "id"], + "iid" => ["thread", "iid"], + "item_id" => ["item", "id"], + "uid" => ["thread", "uid"], + "internal-uid" => ["item", "uid"], + "parent" => ["item", "parent"], + "uri" => ["item", "uri"], + "uri-id" => ["item", "uri-id"], + "internal-uri-id" => ["item", "uri-id"], + "parent-uri" => ["item", "parent-uri"], + "parent-uri-id" => ["item", "parent-uri-id"], + "thr-parent" => ["item", "thr-parent"], + "thr-parent-id" => ["item", "thr-parent-id"], + "guid" => ["item", "guid"], + "type" => ["item", "type"], + "wall" => ["thread", "wall"], + "gravity" => ["item", "gravity"], + "extid" => ["item", "extid"], + "created" => ["thread", "created"], + "edited" => ["item", "edited"], + "commented" => ["thread", "commented"], + "received" => ["thread", "received"], + "changed" => ["thread", "changed"], + "edited" => ["thread", "edited"], + "resource-id" => ["item", "resource-id"], + "post-type" => ["thread", "post-type"], + "private" => ["thread", "private"], + "pubmail" => ["thread", "pubmail"], + "moderated" => ["thread", "moderated"], + "ignored" => ["thread", "ignored"], + "visible" => ["thread", "visible"], + "starred" => ["thread", "starred"], + "bookmark" => ["item", "bookmark"], + "unseen" => ["item", "unseen"], + "deleted" => ["thread", "deleted"], + "origin" => ["thread", "origin"], + "forum_mode" => ["thread", "forum_mode"], + "mention" => ["thread", "mention"], + "global" => ["item", "global"], + "network" => ["thread", "network"], + "icid" => ["item", "icid"], + "vid" => ["item", "vid"], + "psid" => ["item", "psid"], + "attach" => ["item", "attach"], + "internal-file-count" => "(SELECT COUNT(*) FROM `post-category` WHERE `post-category`.`uri-id` = `item`.`uri-id`)", + "file" => "NULL", + "verb" => "IF (`item`.`vid` IS NULL, '', `verb`.`name`)", + "title" => ["item-content", "title"], + "content-warning" => ["item-content", "content-warning"], + "raw-body" => ["item-content", "raw-body"], + "body" => ["item-content", "body"], + "rendered-hash" => ["item-content", "rendered-hash"], + "rendered-html" => ["item-content", "rendered-html"], + "language" => ["item-content", "language"], + "plink" => ["item-content", "plink"], + "location" => ["item-content", "location"], + "coord" => ["item-content", "coord"], + "app" => ["item-content", "app"], + "object-type" => ["item-content", "object-type"], + "object" => ["item-content", "object"], + "target-type" => ["item-content", "target-type"], + "target" => ["item-content", "target"], + "contact-id" => ["thread", "contact-id"], + "contact-link" => ["contact", "url"], + "contact-addr" => ["contact", "addr"], + "contact-name" => ["contact", "name"], + "contact-nick" => ["contact", "nick"], + "contact-avatar" => ["contact", "thumb"], + "contact-network" => ["contact", "network"], + "contact-blocked" => ["contact", "blocked"], + "contact-hidden" => ["contact", "hidden"], + "contact-readonly" => ["contact", "readonly"], + "contact-archive" => ["contact", "archive"], + "contact-pending" => ["contact", "pending"], + "contact-rel" => ["contact", "rel"], + "contact-uid" => ["contact", "uid"], + "contact-contact-type" => ["contact", "contact-type"], + "writable" => "IF (`item`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`)", + "self" => ["contact", "self"], + "cid" => ["contact", "id"], + "alias" => ["contact", "alias"], + "photo" => ["contact", "photo"], + "name-date" => ["contact", "name-date"], + "uri-date" => ["contact", "uri-date"], + "avatar-date" => ["contact", "avatar-date"], + "thumb" => ["contact", "thumb"], + "dfrn-id" => ["contact", "dfrn-id"], + "group-id" => ["group_member", "gid"], + "author-id" => ["thread", "author-id"], + "author-link" => ["author", "url"], + "author-addr" => ["author", "addr"], + "author-name" => "IF (`contact`.`url` = `author`.`url`, `contact`.`name`, `author`.`name`)", + "author-nick" => ["author", "nick"], + "author-avatar" => "IF (`contact`.`url` = `author`.`url`, `contact`.`thumb`, `author`.`thumb`)", + "author-network" => ["author", "network"], + "author-blocked" => ["author", "blocked"], + "author-hidden" => ["author", "hidden"], + "owner-id" => ["thread", "owner-id"], + "owner-link" => ["owner", "url"], + "owner-addr" => ["owner", "addr"], + "owner-name" => "IF (`contact`.`url` = `owner`.`url`, `contact`.`name`, `owner`.`name`)", + "owner-nick" => ["owner", "nick"], + "owner-avatar" => "IF (`contact`.`url` = `owner`.`url`, `contact`.`thumb`, `owner`.`thumb`)", + "owner-network" => ["owner", "network"], + "owner-blocked" => ["owner", "blocked"], + "owner-hidden" => ["owner", "hidden"], + "causer-id" => ["item", "causer-id"], + "causer-link" => ["causer", "url"], + "causer-addr" => ["causer", "addr"], + "causer-name" => ["causer", "name"], + "causer-nick" => ["causer", "nick"], + "causer-avatar" => ["causer", "thumb"], + "causer-network" => ["causer", "network"], + "causer-blocked" => ["causer", "blocked"], + "causer-hidden" => ["causer", "hidden"], + "causer-contact-type" => ["causer", "contact-type"], + "postopts" => ["post-delivery-data", "postopts"], + "inform" => ["post-delivery-data", "inform"], + "delivery_queue_count" => ["post-delivery-data", "queue_count"], + "delivery_queue_done" => ["post-delivery-data", "queue_done"], + "delivery_queue_failed" => ["post-delivery-data", "queue_failed"], + "allow_cid" => "IF (`item`.`psid` IS NULL, '', `permissionset`.`allow_cid`)", + "allow_gid" => "IF (`item`.`psid` IS NULL, '', `permissionset`.`allow_gid`)", + "deny_cid" => "IF (`item`.`psid` IS NULL, '', `permissionset`.`deny_cid`)", + "deny_gid" => "IF (`item`.`psid` IS NULL, '', `permissionset`.`deny_gid`)", + "event-id" => ["item", "event-id"], + "event-created" => ["event", "created"], + "event-edited" => ["event", "edited"], + "event-start" => ["event", "start"], + "event-finish" => ["event", "finish"], + "event-summary" => ["event", "summary"], + "event-desc" => ["event", "desc"], + "event-location" => ["event", "location"], + "event-type" => ["event", "type"], + "event-nofinish" => ["event", "nofinish"], + "event-adjust" => ["event", "adjust"], + "event-ignore" => ["event", "ignore"], + "signed_text" => ["diaspora-interaction", "interaction"], + "parent-guid" => ["parent-item", "guid"], + "parent-network" => ["parent-item", "network"], + "parent-author-id" => ["parent-item", "author-id"], + "parent-author-link" => ["parent-item-author", "url"], + "parent-author-name" => ["parent-item-author", "name"], + "parent-author-network" => ["parent-item-author", "network"], + ], + "query" => "FROM `thread` + STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` + STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id` + STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `thread`.`author-id` + STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `thread`.`owner-id` + STRAIGHT_JOIN `contact` AS `causer` ON `causer`.`id` = `item`.`causer-id` + LEFT JOIN `group_member` ON `group_member`.`contact-id` = `thread`.`contact-id` + LEFT JOIN `verb` ON `verb`.`id` = `item`.`vid` + LEFT JOIN `event` ON `event`.`id` = `item`.`event-id` + LEFT JOIN `diaspora-interaction` ON `diaspora-interaction`.`uri-id` = `thread`.`uri-id` + LEFT JOIN `item-content` ON `item-content`.`uri-id` = `thread`.`uri-id` + LEFT JOIN `post-delivery-data` ON `post-delivery-data`.`uri-id` = `thread`.`uri-id` AND `thread`.`origin` + LEFT JOIN `permissionset` ON `permissionset`.`id` = `item`.`psid` + STRAIGHT_JOIN `item` AS `parent-item` ON `parent-item`.`uri-id` = `item`.`parent-uri-id` AND `parent-item`.`uid` = `item`.`uid` STRAIGHT_JOIN `contact` AS `parent-item-author` ON `parent-item-author`.`id` = `parent-item`.`author-id`" ], "category-view" => [