[DB] Change foreign key specification to new format
This commit is contained in:
parent
ea0aca4b00
commit
1712782cc5
|
@ -144,11 +144,11 @@ class Activity extends Entity
|
|||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'verb' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'object_type' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'object_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'is_local' => ['type' => 'bool', 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'source' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'verb' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'internal activity verb, influenced by activity pub verbs'],
|
||||
'object_type' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'the name of the table this object refers to'],
|
||||
'object_id' => ['type' => 'int', 'not null' => true, 'description' => 'id in the referenced table'],
|
||||
'is_local' => ['type' => 'bool', 'not null' => true, 'description' => 'whether this was a locally generated or an imported activity'],
|
||||
'source' => ['type' => 'varchar', 'length' => 32, 'description' => 'the source of this activity'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
|
|
|
@ -143,17 +143,13 @@ class Avatar extends Entity
|
|||
return [
|
||||
'name' => 'avatar',
|
||||
'fields' => [
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'file_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'file_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to file table'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created', 'default' => 'CURRENT_TIMESTAMP'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified', 'default' => 'CURRENT_TIMESTAMP'],
|
||||
],
|
||||
'primary key' => ['gsactor_id'],
|
||||
'foreign keys' => [
|
||||
'avatar_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
'avatar_file_id_fkey' => ['file', ['file_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['gsactor_id'],
|
||||
'indexes' => [
|
||||
'avatar_file_id_idx' => ['file_id'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -144,7 +144,7 @@ class ConfirmAddress extends Entity
|
|||
'name' => 'confirm_address',
|
||||
'fields' => [
|
||||
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'],
|
||||
'user_id' => ['type' => 'int', 'default' => 0, 'description' => 'user who requested confirmation'],
|
||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'name' => 'confirm_address_user_id_fkey', 'multiplicity' => 'one to one', 'default' => 0, 'description' => 'user who requested confirmation'],
|
||||
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'address (email, xmpp, SMS, etc.)'],
|
||||
'address_extra' => ['type' => 'varchar', 'length' => 191, 'description' => 'carrier ID, for SMS'],
|
||||
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
|
||||
|
@ -152,10 +152,7 @@ class ConfirmAddress extends Entity
|
|||
'sent' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this was sent for queueing'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['code'],
|
||||
'foreign keys' => [
|
||||
'confirm_address_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
],
|
||||
'primary key' => ['code'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ use DateTimeInterface;
|
|||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2010 StatusNet Inc.
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Hugo Sales <hugo@hsal.es>
|
||||
* @copyright 2021 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class Conversation extends Entity
|
||||
|
@ -94,12 +96,11 @@ class Conversation extends Entity
|
|||
'name' => 'conversation',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true, 'description' => 'Unique identifier'],
|
||||
'note_id' => ['type' => 'int', 'not null' => true, 'description' => 'Root of note for this conversation'],
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'Root of note for this conversation'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'foreign keys' => ['conversation_note_id_fkey' => ['note', ['note_id' => 'id']]],
|
||||
'primary key' => ['id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,17 +81,13 @@ class Favourite extends Entity
|
|||
return [
|
||||
'name' => 'favourite',
|
||||
'fields' => [
|
||||
'note_id' => ['type' => 'int', 'not null' => true, 'description' => 'note that is the favorite of'],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'actor who favourited this note'],
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'note that is the favorite of'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'actor who favourited this note'], // note: formerly referenced notice.id, but we can now record remote users' favorites
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['note_id', 'gsactor_id'],
|
||||
'foreign keys' => [
|
||||
'fave_note_id_fkey' => ['note', ['note_id' => 'id']],
|
||||
'fave_actor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']], // note: formerly referenced notice.id, but we can now record remote users' favorites
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['note_id', 'gsactor_id'],
|
||||
'indexes' => [
|
||||
'fave_note_id_idx' => ['note_id'],
|
||||
'fave_actor_id_idx' => ['gsactor_id', 'modified'],
|
||||
'fave_modified_idx' => ['modified'],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
// {{{ License
|
||||
|
||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||
//
|
||||
// GNU social is free software: you can redistribute it and/or modify
|
||||
|
@ -15,6 +16,7 @@
|
|||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// }}}
|
||||
|
||||
namespace App\Entity;
|
||||
|
@ -40,6 +42,7 @@ use DateTimeInterface;
|
|||
class File extends Entity
|
||||
{
|
||||
// {{{ Autocode
|
||||
|
||||
private int $id;
|
||||
private ?string $url;
|
||||
private ?string $url_hash;
|
||||
|
@ -224,16 +227,17 @@ class File extends Entity
|
|||
return [
|
||||
'name' => 'file',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'url' => ['type' => 'text', 'description' => 'URL after following possible redirections'],
|
||||
'url_hash' => ['type' => 'varchar', 'length' => 64, 'description' => 'sha256 of destination URL (url field)'],
|
||||
'file_hash' => ['type' => 'varchar', 'length' => 64, 'description' => 'sha256 of the file contents, if the file is stored locally'],
|
||||
'actor_id' => ['type' => 'int', 'description' => 'If set, used so each actor can have a version of this file (for avatars, for instance)'],
|
||||
'mimetype' => ['type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'],
|
||||
'title' => ['type' => 'text', 'description' => 'title of resource when available'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'whether the file is stored locally'],
|
||||
'is_nsfw' => ['type' => 'bool', 'default' => false, 'description' => 'whether the file is NSFW'],
|
||||
'is_url_protected' => ['type' => 'bool', 'default' => false, 'description' => 'true when URL is private (needs login)'],
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'url' => ['type' => 'text', 'description' => 'URL after following possible redirections'],
|
||||
'url_hash' => ['type' => 'varchar', 'length' => 64, 'description' => 'sha256 of destination URL (url field)'],
|
||||
'file_hash' => ['type' => 'varchar', 'length' => 64, 'description' => 'sha256 of the file contents, if the file is stored locally'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'description' => 'If set, used so each actor can have a version of this file (for avatars, for instance)'],
|
||||
'mimetype' => ['type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'],
|
||||
'title' => ['type' => 'text', 'description' => 'title of resource when available'],
|
||||
'filename' => ['type' => 'varchar', 'length' => 191, 'description' => 'title of resource when available'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'whether the file is stored locally'],
|
||||
'is_nsfw' => ['type' => 'bool', 'default' => false, 'description' => 'whether the file is NSFW'],
|
||||
'is_url_protected' => ['type' => 'bool', 'default' => false, 'description' => 'true when URL is private (needs login)'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
|
|
|
@ -104,16 +104,13 @@ class FileThumbnail extends Entity
|
|||
return [
|
||||
'name' => 'file_thumbnail',
|
||||
'fields' => [
|
||||
'file_id' => ['type' => 'int', 'not null' => true, 'description' => 'thumbnail for what file'],
|
||||
'file_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'thumbnail for what file'],
|
||||
'width' => ['type' => 'int', 'not null' => true, 'description' => 'width of thumbnail'],
|
||||
'height' => ['type' => 'int', 'not null' => true, 'description' => 'height of thumbnail'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['file_id', 'width', 'height'],
|
||||
'foreign keys' => [
|
||||
'file_thumbnail_file_id_fkey' => ['file', ['file_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['file_id', 'width', 'height'],
|
||||
'indexes' => [
|
||||
'file_thumbnail_file_id_idx' => ['file_id'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -83,16 +83,12 @@ class FileToNote extends Entity
|
|||
return [
|
||||
'name' => 'file_to_note',
|
||||
'fields' => [
|
||||
'file_id' => ['type' => 'int', 'not null' => true, 'description' => 'id of file'],
|
||||
'note_id' => ['type' => 'int', 'not null' => true, 'description' => 'id of the note it belongs to'],
|
||||
'file_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'File.id', 'mutiplicity' => 'one to one', 'name' => 'file_to_note_file_id_fkey', 'not null' => true, 'description' => 'id of file'],
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'name' => 'file_to_note_note_id_fkey', 'not null' => true, 'description' => 'id of the note it belongs to'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['file_id', 'note_id'],
|
||||
'foreign keys' => [
|
||||
'file_to_note_file_id_fkey' => ['file', ['file_id' => 'id']],
|
||||
'file_to_note_note_id_fkey' => ['note', ['note_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['file_id', 'note_id'],
|
||||
'indexes' => [
|
||||
'file_id_idx' => ['file_id'],
|
||||
'note_id_idx' => ['note_id'],
|
||||
],
|
||||
|
|
|
@ -96,8 +96,8 @@ class Follow extends Entity
|
|||
return [
|
||||
'name' => 'follow',
|
||||
'fields' => [
|
||||
'follower' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor listening'],
|
||||
'followed' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor being listened to'],
|
||||
'follower' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'name' => 'follow_follower_fkey', 'not null' => true, 'description' => 'gsactor listening'],
|
||||
'followed' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'name' => 'follow_followed_fkey', 'not null' => true, 'description' => 'gsactor being listened to'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
|
|
|
@ -84,19 +84,15 @@ class FollowQueue extends Entity
|
|||
'name' => 'follow_queue',
|
||||
'description' => 'Holder for Follow requests awaiting moderation.',
|
||||
'fields' => [
|
||||
'follower' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor making the request'],
|
||||
'followed' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor being followed'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'follower' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to many', 'name' => 'Follow_queue_follower_fkey', 'not null' => true, 'description' => 'gsactor making the request'],
|
||||
'followed' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to many', 'name' => 'Follow_queue_followed_fkey', 'not null' => true, 'description' => 'gsactor being followed'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
],
|
||||
'primary key' => ['follower', 'followed'],
|
||||
'indexes' => [
|
||||
'Follow_queue_follower_created_idx' => ['follower', 'created'],
|
||||
'Follow_queue_followed_created_idx' => ['followed', 'created'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'Follow_queue_follower_fkey' => ['gsactor', ['follower' => 'id']],
|
||||
'Follow_queue_followed_fkey' => ['gsactor', ['followed' => 'id']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,15 +83,11 @@ class GSActorBlock extends Entity
|
|||
return [
|
||||
'name' => 'gsactor_block',
|
||||
'fields' => [
|
||||
'blocker' => ['type' => 'int', 'not null' => true, 'description' => 'user making the block'],
|
||||
'blocked' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor that is blocked'],
|
||||
'blocker' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to many', 'name' => 'gsactor_block_blocker_fkey', 'not null' => true, 'description' => 'user making the block'],
|
||||
'blocked' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to many', 'name' => 'gsactor_block_blocked_fkey', 'not null' => true, 'description' => 'gsactor that is blocked'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['blocker', 'blocked'],
|
||||
'foreign keys' => [
|
||||
'gsactor_block_blocker_fkey' => ['local_user', ['blocker' => 'id']],
|
||||
'gsactor_block_blocked_fkey' => ['gsactor', ['blocked' => 'id']],
|
||||
],
|
||||
'primary key' => ['blocker', 'blocked'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,11 +132,11 @@ class GSActorCircle extends Entity
|
|||
'name' => 'gsactor_list',
|
||||
'description' => 'a gsactor can have lists of gsactors, to separate their timeline',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'int', 'not null' => true, 'description' => 'unique identifier'],
|
||||
'tagger' => ['type' => 'int', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'gsactor tag'], // Join with GSActorTag
|
||||
'description' => ['type' => 'text', 'description' => 'description of the people tag'],
|
||||
'private' => ['type' => 'bool', 'default' => false, 'description' => 'is this tag private'],
|
||||
'id' => ['type' => 'int', 'not null' => true, 'description' => 'unique identifier'],
|
||||
'tagger' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to one', 'name' => 'gsactor_list_tagger_fkey', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tag' => ['type' => 'varchar', 'foreign key' => true, 'length' => 64, 'target' => 'GSActorTag.tag', 'mutiplicity' => 'many to many', 'not null' => true, 'description' => 'gsactor tag'], // Join with GSActorTag
|
||||
'description' => ['type' => 'text', 'description' => 'description of the people tag'],
|
||||
'private' => ['type' => 'bool', 'default' => false, 'description' => 'is this tag private'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
|
@ -144,9 +144,6 @@ class GSActorCircle extends Entity
|
|||
'unique keys' => [
|
||||
'gsactor_list_id_key' => ['id'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'gsactor_list_tagger_fkey' => ['gsactor', ['tagger' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'gsactor_list_modified_idx' => ['modified'],
|
||||
'gsactor_list_tag_idx' => ['tag'],
|
||||
|
|
|
@ -95,17 +95,13 @@ class GSActorTag extends Entity
|
|||
return [
|
||||
'name' => 'gsactor_tag',
|
||||
'fields' => [
|
||||
'tagger' => ['type' => 'int', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tagged' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor tagged'],
|
||||
'tagger' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'nmae' => 'gsactor_tag_tagger_fkey', 'not null' => true, 'description' => 'user making the tag'],
|
||||
'tagged' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'name' => 'gsactor_tag_tagged_fkey', 'not null' => true, 'description' => 'gsactor tagged'],
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['tagger', 'tagged', 'tag'],
|
||||
'foreign keys' => [
|
||||
'gsactor_tag_tagger_fkey' => ['gsactor', ['tagger' => 'id']],
|
||||
'gsactor_tag_tagged_fkey' => ['gsactor', ['tagged' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['tagger', 'tagged', 'tag'],
|
||||
'indexes' => [
|
||||
'gsactor_tag_modified_idx' => ['modified'],
|
||||
'gsactor_tag_tagger_tag_idx' => ['tagger', 'tag'], // For Circles
|
||||
'gsactor_tag_tagged_idx' => ['tagged'],
|
||||
|
|
|
@ -95,17 +95,13 @@ class GSActorTagFollow extends Entity
|
|||
return [
|
||||
'name' => 'gsactor_tag_follow',
|
||||
'fields' => [
|
||||
'gsactor_tag_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor_tag'],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
'gsactor_tag' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActorTag.tag', 'mutiplicity' => 'one to one', 'name' => 'gsactor_tag_follow_gsactor_tag_fkey', 'not null' => true, 'description' => 'foreign key to gsactor_tag'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'name' => 'gsactor_tag_follow_gsactor_id_fkey', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['gsactor_tag_id', 'gsactor_id'],
|
||||
'foreign keys' => [
|
||||
'gsactor_tag_follow_gsactor_list_id_fkey' => ['gsactor_list', ['gsactor_tag_id' => 'id']],
|
||||
'gsactor_tag_follow_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['gsactor_tag_id', 'gsactor_id'],
|
||||
'indexes' => [
|
||||
'gsactor_tag_follow_gsactor_id_idx' => ['gsactor_id'],
|
||||
'gsactor_tag_follow_created_idx' => ['created'],
|
||||
],
|
||||
|
|
|
@ -263,22 +263,22 @@ class Group extends Entity
|
|||
return [
|
||||
'name' => '`group`',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'],
|
||||
'fullname' => ['type' => 'varchar', 'length' => 191, 'description' => 'display name'],
|
||||
'homepage' => ['type' => 'varchar', 'length' => 191, 'description' => 'URL, cached so we dont regenerate'],
|
||||
'description' => ['type' => 'text', 'description' => 'group description'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'whether this group was created in this instance'],
|
||||
'location' => ['type' => 'varchar', 'length' => 191, 'description' => 'related physical location, if any'],
|
||||
'original_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'original size logo'],
|
||||
'homepage_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'homepage (gsactor) size logo'],
|
||||
'stream_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'stream-sized logo'],
|
||||
'mini_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'mini logo'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
|
||||
'mainpage' => ['type' => 'varchar', 'length' => 191, 'description' => 'page for group info to link to'],
|
||||
'join_policy' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'],
|
||||
'force_scope' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'],
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to one', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'],
|
||||
'fullname' => ['type' => 'varchar', 'length' => 191, 'description' => 'display name'],
|
||||
'homepage' => ['type' => 'varchar', 'length' => 191, 'description' => 'URL, cached so we dont regenerate'],
|
||||
'description' => ['type' => 'text', 'description' => 'group description'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'whether this group was created in this instance'],
|
||||
'location' => ['type' => 'varchar', 'length' => 191, 'description' => 'related physical location, if any'],
|
||||
'original_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'original size logo'],
|
||||
'homepage_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'homepage (gsactor) size logo'],
|
||||
'stream_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'stream-sized logo'],
|
||||
'mini_logo' => ['type' => 'varchar', 'length' => 191, 'description' => 'mini logo'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
|
||||
'mainpage' => ['type' => 'varchar', 'length' => 191, 'description' => 'page for group info to link to'],
|
||||
'join_policy' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'],
|
||||
'force_scope' => ['type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
|
@ -287,9 +287,6 @@ class Group extends Entity
|
|||
'user_group_uri_key' => ['uri'],
|
||||
'user_gsactor_id_key' => ['gsactor_id'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'user_group_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'user_group_nickname_idx' => ['nickname'],
|
||||
'user_group_gsactor_id_idx' => ['gsactor_id'],
|
||||
|
|
|
@ -83,15 +83,12 @@ class GroupAlias extends Entity
|
|||
return [
|
||||
'name' => 'group_alias',
|
||||
'fields' => [
|
||||
'alias' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'],
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group id which this is an alias of'],
|
||||
'alias' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'many to one', 'not null' => true, 'description' => 'group id which this is an alias of'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['alias'],
|
||||
'foreign keys' => [
|
||||
'group_alias_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['alias'],
|
||||
'indexes' => [
|
||||
'group_alias_group_id_idx' => ['group_id'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -95,17 +95,12 @@ class GroupBlock extends Entity
|
|||
return [
|
||||
'name' => 'group_block',
|
||||
'fields' => [
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group gsactor is blocked from'],
|
||||
'blocked_gsactor' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor that is blocked'],
|
||||
'blocker_user' => ['type' => 'int', 'not null' => true, 'description' => 'user making the block'],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'many to one', 'not null' => true, 'description' => 'group gsactor is blocked from'],
|
||||
'blocked_gsactor' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'gsactor that is blocked'],
|
||||
'blocker_user' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'user making the block'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['group_id', 'blocked_gsactor'],
|
||||
'foreign keys' => [
|
||||
'group_block_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
'group_block_blocked_fkey' => ['gsactor', ['blocked_gsactor' => 'id']],
|
||||
'group_block_blocker_fkey' => ['user', ['blocker_user' => 'id']],
|
||||
],
|
||||
'primary key' => ['group_id', 'blocked_gsactor'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,16 +84,12 @@ class GroupInbox extends Entity
|
|||
'name' => 'group_inbox',
|
||||
'description' => 'Many-many table listing activities posted to a given group, or which groups a given activity was posted to',
|
||||
'fields' => [
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group receiving the message'],
|
||||
'activity_id' => ['type' => 'int', 'not null' => true, 'description' => 'activity received'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'name' => 'group_inbox_group_id_fkey', 'not null' => true, 'description' => 'group receiving the activity'],
|
||||
'activity_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Activity.id', 'mutiplicity' => 'many to one', 'name' => 'group_inbox_activity_id_fkey', 'not null' => true, 'description' => 'activity received'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
],
|
||||
'primary key' => ['group_id', 'activity_id'],
|
||||
'foreign keys' => [
|
||||
'group_inbox_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
'group_inbox_activity_id_fkey' => ['activity', ['activity_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['group_id', 'activity_id'],
|
||||
'indexes' => [
|
||||
'group_inbox_activity_id_idx' => ['activity_id'],
|
||||
'group_inbox_group_id_created_activity_id_idx' => ['group_id', 'created', 'activity_id'],
|
||||
'group_inbox_created_idx' => ['created'],
|
||||
|
|
|
@ -84,19 +84,14 @@ class GroupJoinQueue extends Entity
|
|||
'name' => 'group_join_queue',
|
||||
'description' => 'Holder for group join requests awaiting moderation.',
|
||||
'fields' => [
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local gsactor making the request'],
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'remote or local group to join, if any'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'many to many', 'name' => 'group_join_queue_gsactor_id_fkey', 'not null' => true, 'description' => 'remote or local gsactor making the request'],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'name' => 'group_join_queue_group_id_fkey', 'not null' => true, 'description' => 'remote or local group to join, if any'],
|
||||
],
|
||||
'primary key' => ['gsactor_id', 'group_id'],
|
||||
'indexes' => [
|
||||
'group_join_queue_gsactor_id_created_idx' => ['gsactor_id', 'created'],
|
||||
'group_join_queue_group_id_created_idx' => ['group_id', 'created'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'group_join_queue_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
'group_join_queue_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,21 +119,17 @@ class GroupMember extends Entity
|
|||
return [
|
||||
'name' => 'group_member',
|
||||
'fields' => [
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to group table'],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'is_admin' => ['type' => 'bool', 'default' => false, 'description' => 'is this user an admin?'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'name' => 'group_member_group_id_fkey', 'not null' => true, 'description' => 'foreign key to group table'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'name' => 'group_member_gsactor_id_fkey', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'is_admin' => ['type' => 'bool', 'default' => false, 'description' => 'is this actor an admin?'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['group_id', 'gsactor_id'],
|
||||
'unique keys' => [
|
||||
'group_member_uri_key' => ['uri'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'group_member_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
'group_member_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'group_member_gsactor_id_idx' => ['gsactor_id'],
|
||||
'group_member_created_idx' => ['created'],
|
||||
|
|
|
@ -119,19 +119,15 @@ class Invitation extends Entity
|
|||
return [
|
||||
'name' => 'invitation',
|
||||
'fields' => [
|
||||
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'random code for an invitation'],
|
||||
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'who sent the invitation'],
|
||||
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'invitation sent to'],
|
||||
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
|
||||
'registered_user_id' => ['type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'random code for an invitation'],
|
||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'mutiplicity' => 'many to one', 'name' => 'invitation_user_id_fkey', 'not null' => true, 'description' => 'who sent the invitation'],
|
||||
'address' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'invitation sent to'],
|
||||
'address_type' => ['type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'],
|
||||
'registered_user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'mutiplicity' => 'one to one', 'name' => 'invitation_registered_user_id_fkey', 'type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
],
|
||||
'primary key' => ['code'],
|
||||
'foreign keys' => [
|
||||
'invitation_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
'invitation_registered_user_id_fkey' => ['user', ['registered_user_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['code'],
|
||||
'indexes' => [
|
||||
'invitation_address_idx' => ['address', 'address_type'],
|
||||
'invitation_user_id_idx' => ['user_id'],
|
||||
'invitation_registered_user_id_idx' => ['registered_user_id'],
|
||||
|
|
|
@ -96,15 +96,12 @@ class LocalGroup extends Entity
|
|||
'name' => 'local_group',
|
||||
'description' => 'Record for a user group on the local site, with some additional info not in user_group',
|
||||
'fields' => [
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'group represented'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'group represented'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['group_id'],
|
||||
'foreign keys' => [
|
||||
'local_group_group_id_fkey' => ['user_group', ['group_id' => 'id']],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'name' => 'local_group_group_id_fkey', 'not null' => true, 'description' => 'group represented'],
|
||||
'nickname' => ['type' => 'varchar', 'length' => 64, 'description' => 'group represented'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['group_id'],
|
||||
'unique keys' => [
|
||||
'local_group_nickname_key' => ['nickname'],
|
||||
],
|
||||
|
|
|
@ -357,23 +357,23 @@ class LocalUser extends Entity implements UserInterface
|
|||
'name' => 'local_user',
|
||||
'description' => 'local users, bots, etc',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'nickname' => ['type' => 'varchar', 'not null' => true, 'length' => 64, 'description' => 'nickname or username, foreign key to gsactor'],
|
||||
'password' => ['type' => 'varchar', 'length' => 191, 'description' => 'salted password, can be null for users with federated authentication'],
|
||||
'outgoing_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for password recovery, notifications, etc.'],
|
||||
'incoming_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for post-by-email'],
|
||||
'is_email_verified' => ['type' => 'bool', 'default' => false, 'description' => 'Whether the user opened the comfirmation email'],
|
||||
'language' => ['type' => 'varchar', 'length' => 50, 'description' => 'preferred language'],
|
||||
'timezone' => ['type' => 'varchar', 'length' => 50, 'description' => 'timezone'],
|
||||
'id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to gsactor table'],
|
||||
'nickname' => ['type' => 'varchar', 'foreign key' => true, 'not null' => true, 'length' => 64, 'description' => 'nickname or username, foreign key to gsactor'],
|
||||
'password' => ['type' => 'varchar', 'length' => 191, 'description' => 'salted password, can be null for users with federated authentication'],
|
||||
'outgoing_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for password recovery, notifications, etc.'],
|
||||
'incoming_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'email address for post-by-email'],
|
||||
'is_email_verified' => ['type' => 'bool', 'default' => false, 'description' => 'Whether the user opened the comfirmation email'],
|
||||
'language' => ['type' => 'varchar', 'length' => 50, 'description' => 'preferred language'],
|
||||
'timezone' => ['type' => 'varchar', 'length' => 50, 'description' => 'timezone'],
|
||||
'phone_number' => ['type' => 'phone_number', 'description' => 'phone number'],
|
||||
'sms_carrier' => ['type' => 'int', 'description' => 'foreign key to sms_carrier'],
|
||||
'sms_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'built from sms and carrier (see sms_carrier)'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier, usually a tag URI'],
|
||||
'auto_follow_back' => ['type' => 'bool', 'default' => false, 'description' => 'automatically follow users who follow us'],
|
||||
'follow_policy' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can follow; 1 = require approval'],
|
||||
'is_stream_private' => ['type' => 'bool', 'default' => false, 'description' => 'whether to limit all notices to followers only'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
'sms_carrier' => ['type' => 'int', 'foreign key' => true, 'target' => 'SmsCarrier.id', 'mutiplicity' => 'one to one', 'description' => 'foreign key to sms_carrier'],
|
||||
'sms_email' => ['type' => 'varchar', 'length' => 191, 'description' => 'built from sms and carrier (see sms_carrier)'],
|
||||
'uri' => ['type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier, usually a tag URI'],
|
||||
'auto_follow_back' => ['type' => 'bool', 'default' => false, 'description' => 'automatically follow users who follow us'],
|
||||
'follow_policy' => ['type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can follow; 1 = require approval'],
|
||||
'is_stream_private' => ['type' => 'bool', 'default' => false, 'description' => 'whether to limit all notices to followers only'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'unique keys' => [
|
||||
|
@ -383,10 +383,6 @@ class LocalUser extends Entity implements UserInterface
|
|||
'user_phone_number_key' => ['phone_number'],
|
||||
'user_uri_key' => ['uri'],
|
||||
],
|
||||
'foreign keys' => [
|
||||
'user_id_fkey' => ['gsactor', ['id' => 'id']],
|
||||
'user_carrier_fkey' => ['sms_carrier', ['sms_carrier' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'user_nickname_idx' => ['nickname'],
|
||||
'user_created_idx' => ['created'],
|
||||
|
|
|
@ -95,8 +95,8 @@ class LocationService extends Entity
|
|||
return [
|
||||
'name' => 'location_service',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'description' => 'identifier for the location service'],
|
||||
'description' => ['type' => 'varchar', 'length' => 191, 'description' => 'description of the service'],
|
||||
'id' => ['type' => 'int', 'size' => 'tiny', 'not null' => true, 'description' => 'identifier for the location service'],
|
||||
'description' => ['type' => 'varchar', 'length' => 191, 'description' => 'description of the service'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
|
|
|
@ -256,28 +256,21 @@ class Note extends Entity
|
|||
return [
|
||||
'name' => 'note',
|
||||
'fields' => [
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'who made the note'],
|
||||
'content' => ['type' => 'text', 'description' => 'note content'],
|
||||
'rendered' => ['type' => 'text', 'description' => 'rendered note content if not local, so we can keep the microtags'],
|
||||
'reply_to' => ['type' => 'int', 'description' => 'note replied to, null if root of a conversation'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'was this note generated by a local actor'],
|
||||
'source' => ['type' => 'varchar', 'length' => 32, 'description' => 'source of note, like "web", "im", or "clientname"'],
|
||||
'conversation' => ['type' => 'int', 'description' => 'the local conversation id'],
|
||||
'repeat_of' => ['type' => 'int', 'description' => 'note this is a repeat of'],
|
||||
'scope' => ['type' => 'int', 'not null' => true, 'default' => NoteScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = followers; 16 = messages; null = default'],
|
||||
'id' => ['type' => 'serial', 'not null' => true],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'who made the note'],
|
||||
'content' => ['type' => 'text', 'description' => 'note content'],
|
||||
'rendered' => ['type' => 'text', 'description' => 'rendered note content, so we can keep the microtags (if not local)'],
|
||||
'reply_to' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'description' => 'note replied to, null if root of a conversation'],
|
||||
'is_local' => ['type' => 'bool', 'description' => 'was this note generated by a local actor'],
|
||||
'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.source', 'mutiplicity' => 'one to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'],
|
||||
'conversation' => ['type' => 'int', 'foreign key' => true, 'target' => 'Conversation.id', 'mutiplicity' => 'one to one', 'description' => 'the local conversation id'],
|
||||
'repeat_of' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'description' => 'note this is a repeat of'],
|
||||
'scope' => ['type' => 'int', 'not null' => true, 'default' => NoteScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = followers; 16 = messages; null = default'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'foreign keys' => [
|
||||
'note_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
'note_reply_to_fkey' => ['note', ['reply_to' => 'id']],
|
||||
'note_note_source_fkey' => ['note_source', ['source' => 'code']],
|
||||
'note_conversation_fkey' => ['conversation', ['conversation' => 'id']],
|
||||
'note_repeat_of_fkey' => ['note', ['repeat_of' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['id'],
|
||||
'indexes' => [
|
||||
'note_created_id_is_local_idx' => ['created', 'is_local'],
|
||||
'note_gsactor_created_idx' => ['gsactor_id', 'created'],
|
||||
'note_is_local_created_gsactor_idx' => ['is_local', 'created', 'gsactor_id'],
|
||||
|
|
|
@ -119,18 +119,15 @@ class NoteLocation extends Entity
|
|||
return [
|
||||
'name' => 'activity_location',
|
||||
'fields' => [
|
||||
'note_id' => ['type' => 'int', 'not null' => true, 'description' => 'activity this refers to'],
|
||||
'lat' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'],
|
||||
'lon' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'],
|
||||
'location_id' => ['type' => 'int', 'description' => 'location id if possible'],
|
||||
'location_service' => ['type' => 'int', 'size' => 'tiny', 'description' => 'service used to retrieve location information'],
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'name' => 'note_location_note_id_fkey', 'not null' => true, 'description' => 'activity this refers to'],
|
||||
'lat' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'],
|
||||
'lon' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'],
|
||||
'location_id' => ['type' => 'int', 'description' => 'location id if possible'],
|
||||
'location_service' => ['type' => 'int', 'size' => 'tiny', 'description' => 'service used to retrieve location information'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['note_id'],
|
||||
'foreign keys' => [
|
||||
'note_location_note_id_fkey' => ['note', ['note_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['note_id'],
|
||||
'indexes' => [
|
||||
'note_location_location_id_idx' => ['location_id'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -95,9 +95,9 @@ class NoteSource extends Entity
|
|||
return [
|
||||
'name' => 'note_source',
|
||||
'fields' => [
|
||||
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'code identifier'],
|
||||
'name' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the source'],
|
||||
'url' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'url to link to'],
|
||||
'code' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'code identifier'],
|
||||
'name' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'name of the source'],
|
||||
'url' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'url to link to'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['code'],
|
||||
|
|
|
@ -36,7 +36,7 @@ use DateTimeInterface;
|
|||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class NoteHashtag extends Entity
|
||||
class NoteTag extends Entity
|
||||
{
|
||||
// {{{ Autocode
|
||||
private string $tag;
|
||||
|
@ -81,18 +81,15 @@ class NoteHashtag extends Entity
|
|||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'note_hashtag',
|
||||
'name' => 'note_tag',
|
||||
'description' => 'Hash tags on notes',
|
||||
'fields' => [
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this note'],
|
||||
'note_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to tagged note'],
|
||||
'tag' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this note'],
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to tagged note'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['tag', 'note_id'],
|
||||
'foreign keys' => [
|
||||
'note_hashtag_note_id_fkey' => ['note', ['note_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['tag', 'note_id'],
|
||||
'indexes' => [
|
||||
'note_tag_created_idx' => ['created'],
|
||||
'note_tag_note_id_idx' => ['note_id'],
|
||||
'note_tag_tag_created_note_id_idx' => ['tag', 'created', 'note_id'],
|
|
@ -108,18 +108,14 @@ class Notification extends Entity
|
|||
'name' => 'notification',
|
||||
'description' => 'Activity notification for gsactors (that are not a mention and not result of a subscription)',
|
||||
'fields' => [
|
||||
'activity_id' => ['type' => 'int', 'not null' => true, 'description' => 'activity_id to give attention'],
|
||||
'gsactor_id' => ['type' => 'int', 'not null' => true, 'description' => 'gsactor_id for feed receiver'],
|
||||
'reason' => ['type' => 'varchar', 'length' => 191, 'description' => 'Optional reason why this was brought to the attention of gsactor_id'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
'activity_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Activity.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'activity_id to give attention'],
|
||||
'gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'gsactor_id for feed receiver'],
|
||||
'reason' => ['type' => 'varchar', 'length' => 191, 'description' => 'Optional reason why this was brought to the attention of gsactor_id'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['activity_id', 'gsactor_id'],
|
||||
'foreign keys' => [
|
||||
'attention_activity_id_fkey' => ['activity', ['activity_id' => 'id']],
|
||||
'attention_gsactor_id_fkey' => ['gsactor', ['gsactor_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['activity_id', 'gsactor_id'],
|
||||
'indexes' => [
|
||||
'attention_activity_id_idx' => ['activity_id'],
|
||||
'attention_gsactor_id_idx' => ['gsactor_id'],
|
||||
],
|
||||
|
|
|
@ -84,15 +84,11 @@ class RelatedGroup extends Entity
|
|||
'name' => 'related_group',
|
||||
// @fixme description for related_group?
|
||||
'fields' => [
|
||||
'group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'],
|
||||
'related_group_id' => ['type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
],
|
||||
'primary key' => ['group_id', 'related_group_id'],
|
||||
'foreign keys' => [
|
||||
'related_group_group_id_fkey' => ['group', ['group_id' => 'id']],
|
||||
'related_group_related_group_id_fkey' => ['group', ['related_group_id' => 'id']],
|
||||
'group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to group'],
|
||||
'related_group_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Group.id', 'mutiplicity' => 'one to one', 'type' => 'int', 'not null' => true, 'description' => 'foreign key to group'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
],
|
||||
'primary key' => ['group_id', 'related_group_id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,15 +93,12 @@ class UserLocationPrefs extends Entity
|
|||
return [
|
||||
'name' => 'user_location_prefs',
|
||||
'fields' => [
|
||||
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user who has the preference'],
|
||||
'share_location' => ['type' => 'bool', 'default' => true, 'description' => 'Whether to share location data'],
|
||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'user who has the preference'],
|
||||
'share_location' => ['type' => 'bool', 'default' => true, 'description' => 'Whether to share location data'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['user_id'],
|
||||
'foreign keys' => [
|
||||
'user_location_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
],
|
||||
'primary key' => ['user_id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,27 +211,23 @@ class UserNotificationPrefs extends Entity
|
|||
return [
|
||||
'name' => 'user_notification_prefs',
|
||||
'fields' => [
|
||||
'user_id' => ['type' => 'int', 'not null' => true],
|
||||
'transport' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex email. xmpp, aim)'],
|
||||
'target_gsactor_id' => ['type' => 'int', 'default' => null, 'description' => 'If not null, settings are specific only to a given gsactors'],
|
||||
'activity_by_followed' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when a new activity by someone we follow is made'],
|
||||
'mention' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when mentioned by someone we do not follow'],
|
||||
'reply' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when someone replies to a notice made by us'],
|
||||
'follow' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone follows us'],
|
||||
'favorite' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone favorites a notice by us'],
|
||||
'nudge' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Notify someone nudges us'],
|
||||
'dm' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone sends us a direct message'],
|
||||
'post_on_status_change' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Post a notice when our status in service changes'],
|
||||
'enable_posting' => ['type' => 'bool', 'default' => true, 'description' => 'Enable posting from this service'],
|
||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'mutiplicity' => 'one to one', 'not null' => true],
|
||||
'transport' => ['type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex email. xmpp, aim)'],
|
||||
'target_gsactor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'GSActor.id', 'mutiplicity' => 'one to one', 'default' => null, 'description' => 'If not null, settings are specific only to a given gsactors'],
|
||||
'activity_by_followed' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when a new activity by someone we follow is made'],
|
||||
'mention' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when mentioned by someone we do not follow'],
|
||||
'reply' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify when someone replies to a notice made by us'],
|
||||
'follow' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone follows us'],
|
||||
'favorite' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone favorites a notice by us'],
|
||||
'nudge' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Notify someone nudges us'],
|
||||
'dm' => ['type' => 'bool', 'not null' => true, 'default' => true, 'description' => 'Notify someone sends us a direct message'],
|
||||
'post_on_status_change' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description' => 'Post a notice when our status in service changes'],
|
||||
'enable_posting' => ['type' => 'bool', 'default' => true, 'description' => 'Enable posting from this service'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['user_id', 'transport'],
|
||||
'foreign keys' => [
|
||||
'user_notification_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
'user_notification_prefs_target_gsactor' => ['gsactor', ['target_gsactor_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'primary key' => ['user_id', 'transport'],
|
||||
'indexes' => [
|
||||
'user_notification_prefs_user_target_gsactor_idx' => ['user_id', 'target_gsactor_id'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -119,17 +119,14 @@ class UserUrlShortenerPrefs extends Entity
|
|||
return [
|
||||
'name' => 'user_url_shortener_prefs',
|
||||
'fields' => [
|
||||
'user_id' => ['type' => 'int', 'not null' => true, 'description' => 'user'],
|
||||
'url_shortening_service' => ['type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'],
|
||||
'max_url_length' => ['type' => 'int', 'not null' => true, 'description' => 'urls greater than this length will be shortened, 0 = always, -1 = never'],
|
||||
'max_notice_length' => ['type' => 'int', 'not null' => true, 'description' => 'notices with content greater than this value will have all urls shortened, 0 = always, -1 = only if notice text is longer than max allowed'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['user_id'],
|
||||
'foreign keys' => [
|
||||
'user_urlshortener_prefs_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'LocalUser.id', 'name' => 'user_urlshortener_prefs_user_id_fkey', 'mutiplicity' => 'one to one', 'not null' => true, 'description' => 'user'],
|
||||
'url_shortening_service' => ['type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'],
|
||||
'max_url_length' => ['type' => 'int', 'not null' => true, 'description' => 'urls greater than this length will be shortened, 0 = always, -1 = never'],
|
||||
'max_notice_length' => ['type' => 'int', 'not null' => true, 'description' => 'notices with content greater than this value will have all urls shortened, 0 = always, -1 = only if notice text is longer than max allowed'],
|
||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['user_id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user