-- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1525
+-- DB_UPDATE_VERSION 1526
-- ------------------------------------------
FOREIGN KEY (`parent-uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users';
+--
+-- TABLE user-gserver
+--
+CREATE TABLE IF NOT EXISTS `user-gserver` (
+ `uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
+ `gsid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Gserver id',
+ `ignored` boolean NOT NULL DEFAULT '0' COMMENT 'server accounts are ignored for the user',
+ PRIMARY KEY(`uid`,`gsid`),
+ FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
+ FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User settings about remote servers';
+
--
-- TABLE item-uri
--
| [tag](help/database/db_tag) | tags and mentions |
| [user](help/database/db_user) | The local users |
| [user-contact](help/database/db_user-contact) | User specific public contact data |
+| [user-gserver](help/database/db_user-gserver) | User settings about remote servers |
| [userd](help/database/db_userd) | Deleted usernames |
| [verb](help/database/db_verb) | Activity Verbs |
| [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker |
--- /dev/null
+Table user-gserver
+===========
+
+User settings about remote servers
+
+Fields
+------
+
+| Field | Description | Type | Null | Key | Default | Extra |
+| ------- | ---------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
+| uid | Owner User id | mediumint unsigned | NO | | 0 | |
+| gsid | Gserver id | int unsigned | NO | | 0 | |
+| ignored | server accounts are ignored for the user | boolean | NO | | 0 | |
+
+Indexes
+------------
+
+| Name | Fields |
+| ------- | --------- |
+| PRIMARY | uid, gsid |
+
+Foreign Keys
+------------
+
+| Field | Target Table | Target Field |
+|-------|--------------|--------------|
+| uid | [user](help/database/db_user) | uid |
+| gsid | [gserver](help/database/db_gserver) | id |
+
+Return to [database documentation](help/database)
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\User\Settings\Collection;
+
+class UserGServers extends \Friendica\BaseCollection
+{
+ public function current(): \Friendica\User\Settings\Entity\UserGServer
+ {
+ return parent::current();
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\User\Settings\Entity;
+
+use Friendica\Federation\Entity\GServer;
+
+/**
+ * @property-read int $uid
+ * @property-read int $gsid
+ * @property-read bool $ignored
+ * @property-read ?GServer $gserver
+ */
+class UserGServer extends \Friendica\BaseEntity
+{
+ /** @var int User id */
+ protected $uid;
+ /** @var int GServer id */
+ protected $gsid;
+ /** @var bool Whether the user ignored this server */
+ protected $ignored;
+ /** @var ?GServer */
+ protected $gserver;
+
+ public function __construct(int $uid, int $gsid, bool $ignored = false, ?GServer $gserver = null)
+ {
+ $this->uid = $uid;
+ $this->gsid = $gsid;
+ $this->ignored = $ignored;
+ $this->gserver = $gserver;
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\User\Settings\Factory;
+
+use Friendica\Capabilities\ICanCreateFromTableRow;
+use Friendica\Federation\Entity\GServer;
+use Friendica\User\Settings\Entity;
+
+class UserGServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
+{
+ /**
+ * @param array $row `user-gserver` table row
+ * @param GServer|null $server Corresponding GServer entity
+ * @return Entity\UserGServer
+ */
+ public function createFromTableRow(array $row, GServer $server = null): Entity\UserGServer
+ {
+ return new Entity\UserGServer(
+ $row['uid'],
+ $row['gsid'],
+ $row['ignored'],
+ $server,
+ );
+ }
+
+ /**
+ * @param int $uid
+ * @param int $gsid
+ * @param GServer|null $gserver Corresponding GServer entity
+ * @return Entity\UserGServer
+ */
+ public function createFromUserAndServer(int $uid, int $gsid, GServer $gserver = null): Entity\UserGServer
+ {
+ return new Entity\UserGServer(
+ $uid,
+ $gsid,
+ false,
+ $gserver,
+ );
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\User\Settings\Repository;
+
+use Exception;
+use Friendica\BaseCollection;
+use Friendica\BaseEntity;
+use Friendica\Content\Pager;
+use Friendica\Database\Database;
+use Friendica\Federation\Repository\GServer;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Network\HTTPException\NotFoundException;
+use Friendica\User\Settings\Collection;
+use Friendica\User\Settings\Entity;
+use Friendica\User\Settings\Factory;
+use Psr\Log\LoggerInterface;
+
+class UserGServer extends \Friendica\BaseRepository
+{
+ protected static $table_name = 'user-gserver';
+
+ /** @var Factory\UserGServer */
+ protected $factory;
+ /** @var GServer */
+ protected $gserverRepository;
+
+ public function __construct(GServer $gserverRepository, Database $database, LoggerInterface $logger, Factory\UserGServer $factory)
+ {
+ parent::__construct($database, $logger, $factory);
+
+ $this->gserverRepository = $gserverRepository;
+ }
+
+ /**
+ * Returns an existing UserGServer entity or create one on the fly
+ *
+ * @param int $uid
+ * @param int $gsid
+ * @param bool $hydrate Populate the related GServer entity
+ * @return Entity\UserGServer
+ */
+ public function getOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
+ {
+ try {
+ return $this->selectOneByUserAndServer($uid, $gsid, $hydrate);
+ } catch (NotFoundException $e) {
+ return $this->factory->createFromUserAndServer($uid, $gsid, $hydrate ? $this->gserverRepository->selectOneById($gsid) : null);
+ }
+ }
+
+ /**
+ * @param int $uid
+ * @param int $gsid
+ * @param bool $hydrate Populate the related GServer entity
+ * @return Entity\UserGServer
+ * @throws NotFoundException
+ */
+ public function selectOneByUserAndServer(int $uid, int $gsid, bool $hydrate = true): Entity\UserGServer
+ {
+ return $this->_selectOne(['uid' => $uid, 'gsid' => $gsid], [], $hydrate);
+ }
+
+ public function save(Entity\UserGServer $userGServer): Entity\UserGServer
+ {
+ $fields = [
+ 'uid' => $userGServer->uid,
+ 'gsid' => $userGServer->gsid,
+ 'ignored' => $userGServer->ignored,
+ ];
+
+ $this->db->insert(static::$table_name, $fields, Database::INSERT_UPDATE);
+
+ return $userGServer;
+ }
+
+ public function selectByUserWithPagination(int $uid, Pager $pager): Collection\UserGServers
+ {
+ return $this->_select(['uid' => $uid], ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
+ }
+
+ public function countByUser(int $uid): int
+ {
+ return $this->count(['uid' => $uid]);
+ }
+
+ /**
+ * @param Entity\UserGServer $userGServer
+ * @return bool
+ * @throws InternalServerErrorException in case the underlying storage cannot delete the record
+ */
+ public function delete(Entity\UserGServer $userGServer): bool
+ {
+ try {
+ return $this->db->delete(self::$table_name, ['uid' => $userGServer->uid, 'gsid' => $userGServer->gsid]);
+ } catch (\Exception $exception) {
+ throw new InternalServerErrorException('Cannot delete the UserGServer', $exception);
+ }
+ }
+
+ protected function _selectOne(array $condition, array $params = [], bool $hydrate = true): BaseEntity
+ {
+ $fields = $this->db->selectFirst(static::$table_name, [], $condition, $params);
+ if (!$this->db->isResult($fields)) {
+ throw new NotFoundException();
+ }
+
+ return $this->factory->createFromTableRow($fields, $hydrate ? $this->gserverRepository->selectOneById($fields['gsid']) : null);
+ }
+
+ /**
+ * @param array $condition
+ * @param array $params
+ * @return Collection\UserGServers
+ * @throws Exception
+ */
+ protected function _select(array $condition, array $params = []): BaseCollection
+ {
+ $rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
+
+ $Entities = new Collection\UserGServers();
+ foreach ($rows as $fields) {
+ $Entities[] = $this->factory->createFromTableRow($fields, $this->gserverRepository->selectOneById($fields['gsid']));
+ }
+
+ return $Entities;
+ }
+}
// This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1525);
+ define('DB_UPDATE_VERSION', 1526);
}
return [
"email" => ["email(64)"],
]
],
+ "user-gserver" => [
+ "comment" => "User settings about remote servers",
+ "fields" => [
+ "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
+ "gsid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["gserver" => "id"], "comment" => "Gserver id"],
+ "ignored" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "server accounts are ignored for the user"],
+ ],
+ "indexes" => [
+ "PRIMARY" => ["uid", "gsid"],
+ ],
+ ],
"item-uri" => [
"comment" => "URI and GUID for items",
"fields" => [