[DB][CONTROLLER][Network][ENTITY][Note] Fix Note::getAllNotes

This commit is contained in:
Hugo Sales 2021-11-09 23:37:46 +00:00
parent c3705112ba
commit 7d8819a3da
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 41 additions and 30 deletions

View File

@ -43,6 +43,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Exception;
use Functional as F; use Functional as F;
/** /**
@ -114,10 +115,12 @@ class DB
* from table aliases to class names. Replaces '{select}' in * from table aliases to class names. Replaces '{select}' in
* $query with the appropriate select list * $query with the appropriate select list
*/ */
public static function sql(string $query// , array $entities public static function sql(string $query, array $params = [])
, array $params = [], )
{ {
$rsm = new ResultSetMappingBuilder(self::$em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT); if ($_ENV['APP_ENV'] === 'dev' && str_starts_with($query, 'select *')) {
throw new Exception('Cannot use `select *`, use `select {select}` (see ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT)');
}
$rsmb = new ResultSetMappingBuilder(self::$em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
$matches = []; $matches = [];
preg_match_all(self::$table_entity_pattern, $query, $matches); preg_match_all(self::$table_entity_pattern, $query, $matches);
$entities = []; $entities = [];
@ -125,10 +128,10 @@ class DB
$entities[$alias] = self::$table_map[$table]; $entities[$alias] = self::$table_map[$table];
} }
foreach ($entities as $alias => $entity) { foreach ($entities as $alias => $entity) {
$rsm->addRootEntityFromClassMetadata($entity, $alias); $rsmb->addRootEntityFromClassMetadata($entity, $alias);
} }
$query = preg_replace('/{select}/', $rsm->generateSelectClause(), $query); $query = preg_replace('/{select}/', $rsmb->generateSelectClause(), $query);
$q = self::$em->createNativeQuery($query, $rsm); $q = self::$em->createNativeQuery($query, $rsmb);
foreach ($params as $k => $v) { foreach ($params as $k => $v) {
$q->setParameter($k, $v); $q->setParameter($k, $v);
} }

View File

@ -255,11 +255,11 @@ class Note extends Entity
{ {
return DB::sql( return DB::sql(
<<<'EOF' <<<'EOF'
select * from note n select {select} from note n
where (n.scope & :notescope) <> 0 where (n.scope & :scope) <> 0
order by n.created DESC order by n.created DESC
EOF, EOF,
['notescope' => $note_scope], ['scope' => $note_scope],
); );
} }
@ -267,9 +267,11 @@ class Note extends Entity
{ {
return Cache::get('note-attachments-' . $this->id, function () { return Cache::get('note-attachments-' . $this->id, function () {
return DB::dql( return DB::dql(
'select att from App\Entity\Attachment att ' <<<'EOF'
. 'join App\Entity\AttachmentToNote atn with atn.attachment_id = att.id ' select att from attachment att
. 'where atn.note_id = :note_id', join attachment_to_note atn with atn.attachment_id = att.id
where atn.note_id = :note_id
EOF,
['note_id' => $this->id], ['note_id' => $this->id],
); );
}); });
@ -279,9 +281,11 @@ class Note extends Entity
{ {
return Cache::get('note-links-' . $this->id, function () { return Cache::get('note-links-' . $this->id, function () {
return DB::dql( return DB::dql(
'select l from App\Entity\Link l ' <<<'EOF'
. 'join App\Entity\NoteToLink ntl with ntl.link_id = l.id ' select l from link l
. 'where ntl.note_id = :note_id', join note_to_link ntl with ntl.link_id = l.id
where ntl.note_id = :note_id
EOF,
['note_id' => $this->id], ['note_id' => $this->id],
); );
}); });
@ -297,8 +301,10 @@ class Note extends Entity
if (!empty($this->reply_to)) { if (!empty($this->reply_to)) {
return Cache::get('note-reply-to-' . $this->id, function () { return Cache::get('note-reply-to-' . $this->id, function () {
return DB::dql( return DB::dql(
'select g from App\Entity\Note n join ' <<<'EOF'
. 'App\Entity\Actor g with n.actor_id = g.id where n.reply_to = :reply', select g from note n join
actor g with n.actor_id = g.id where n.reply_to = :reply
EOF,
['reply' => $this->reply_to], ['reply' => $this->reply_to],
)[0]->getNickname(); )[0]->getNickname();
}); });
@ -318,10 +324,12 @@ class Note extends Entity
($scope->subscriber && 0 != DB::count('subscription', ['subscriber' => $a->getId(), 'subscribed' => $this->actor_id])) ($scope->subscriber && 0 != DB::count('subscription', ['subscriber' => $a->getId(), 'subscribed' => $this->actor_id]))
|| ($scope->addressee && 0 != DB::count('notification', ['activity_id' => $this->id, 'actor_id' => $a->getId()])) || ($scope->addressee && 0 != DB::count('notification', ['activity_id' => $this->id, 'actor_id' => $a->getId()]))
|| ($scope->group && [] != DB::dql( || ($scope->group && [] != DB::dql(
'select m from group_member m ' <<<'EOF'
. 'join group_inbox i with m.group_id = i.group_id ' select m from group_member m
. 'join note n with i.activity_id = n.id ' join group_inbox i with m.group_id = i.group_id
. 'where n.id = :note_id and m.actor_id = :actor_id', join note n with i.activity_id = n.id
where n.id = :note_id and m.actor_id = :actor_id
EOF,
['note_id' => $this->id, 'actor_id' => $a->getId()], ['note_id' => $this->id, 'actor_id' => $a->getId()],
)) ))
)); ));
@ -350,21 +358,21 @@ class Note extends Entity
'is_local' => ['type' => 'bool', 'description' => 'was this note generated by a local actor'], 'is_local' => ['type' => 'bool', 'description' => 'was this note generated by a local actor'],
'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.code', 'multiplicity' => 'many to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'], 'source' => ['type' => 'varchar', 'foreign key' => true, 'length' => 32, 'target' => 'NoteSource.code', 'multiplicity' => 'many to one', 'description' => 'fkey to source of note, like "web", "im", or "clientname"'],
'conversation' => ['type' => 'int', 'foreign key' => true, 'target' => 'Conversation.id', 'multiplicity' => 'one to one', 'description' => 'the local conversation id'], 'conversation' => ['type' => 'int', 'foreign key' => true, 'target' => 'Conversation.id', 'multiplicity' => 'one to one', 'description' => 'the local conversation id'],
// 'repeat_of' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'description' => 'note this is a repeat of'], // 'repeat_of' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'description' => 'note this is a repeat of'],
'scope' => ['type' => 'int', 'not null' => true, 'default' => VisibilityScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = subscribers; 16 = messages; null = default'], 'scope' => ['type' => 'int', 'not null' => true, 'default' => VisibilityScope::PUBLIC, 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = groups; 8 = subscribers; 16 = messages; null = default'],
'url' => ['type' => 'text', 'description' => 'Permalink to Note'], 'url' => ['type' => 'text', 'description' => 'Permalink to Note'],
'language' => ['type' => 'int', 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'one to many', 'description' => 'The language for this note'], 'language' => ['type' => 'int', 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'one to many', 'description' => 'The language for this note'],
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], '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'], 'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
], ],
'primary key' => ['id'], 'primary key' => ['id'],
'indexes' => [ 'indexes' => [
'note_created_id_is_local_idx' => ['created', 'is_local'], 'note_created_id_is_local_idx' => ['created', 'is_local'],
'note_actor_created_idx' => ['actor_id', 'created'], 'note_actor_created_idx' => ['actor_id', 'created'],
'note_is_local_created_actor_idx' => ['is_local', 'created', 'actor_id'], 'note_is_local_created_actor_idx' => ['is_local', 'created', 'actor_id'],
'note_repeat_of_created_idx' => ['repeat_of', 'created'], // 'note_repeat_of_created_idx' => ['repeat_of', 'created'],
'note_conversation_created_idx' => ['conversation', 'created'], 'note_conversation_created_idx' => ['conversation', 'created'],
'note_reply_to_idx' => ['reply_to'], 'note_reply_to_idx' => ['reply_to'],
], ],
'fulltext indexes' => ['notice_fulltext_idx' => ['content']], // TODO make this configurable 'fulltext indexes' => ['notice_fulltext_idx' => ['content']], // TODO make this configurable
]; ];