Merge pull request #25 from nextcloud-gmbh/leftjoin-cacheactor

left join cache, and returns data in timeline
pull/26/head
Maxence Lange 2018-11-14 11:05:14 -01:00 zatwierdzone przez GitHub
commit 334ad6c7f0
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
8 zmienionych plików z 115 dodań i 65 usunięć

Wyświetl plik

@ -32,7 +32,7 @@ return [
['name' => 'Local#newPost', 'url' => '/api/v1/post', 'verb' => 'POST'],
['name' => 'Local#timeline', 'url' => '/api/v1/timeline', 'verb' => 'GET'],
['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT']
['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT'],
['name' => 'Local#accountSearch', 'url' => '/api/v1/accounts/search', 'verb' => 'GET'],
['name' => 'Local#actorInfo', 'url' => '/api/v1/actor/info', 'verb' => 'GET']

Wyświetl plik

@ -31,6 +31,8 @@ namespace OCA\Social\Db;
use Doctrine\DBAL\Query\QueryBuilder;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Model\ActivityPub\Person;
use OCA\Social\Service\ConfigService;
use OCA\Social\Service\MiscService;
use OCP\DB\QueryBuilder\IQueryBuilder;
@ -224,7 +226,8 @@ class CoreRequestBuilder {
/**
* @param IQueryBuilder $qb
* @param string $recipient
* @param int $since
* @param int $limit
*/
protected function limitPaginate(IQueryBuilder &$qb, int $since = 0, int $limit = 5) {
if ($since > 0) {
@ -232,7 +235,12 @@ class CoreRequestBuilder {
$dt = new \DateTime();
$dt->setTimestamp($since);
// TODO: Pagination should use published date, once we can properly query the db for that
$qb->andWhere($expr->lt('creation', $qb->createNamedParameter($dt, IQueryBuilder::PARAM_DATE), IQueryBuilder::PARAM_DATE));
$qb->andWhere(
$expr->lt(
'creation', $qb->createNamedParameter($dt, IQueryBuilder::PARAM_DATE),
IQueryBuilder::PARAM_DATE
)
);
}
$qb->setMaxResults($limit);
$qb->orderBy('creation', 'desc');
@ -273,30 +281,66 @@ class CoreRequestBuilder {
$qb->andWhere($expr->like($field, $qb->createNamedParameter($value)));
}
// /**
// * Left Join service to get info about the serviceId
// *
// * @param IQueryBuilder $qb
// */
// public function leftJoinService(IQueryBuilder &$qb) {
//
// if ($qb->getType() !== QueryBuilder::SELECT) {
// return;
// }
//
// $expr = $qb->expr();
// $pf = $this->defaultSelectAlias;
//
/**
* @param IQueryBuilder $qb
* @param string $fieldActorId
*/
protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId) {
if ($qb->getType() !== QueryBuilder::SELECT) {
return;
}
$expr = $qb->expr();
$pf = $this->defaultSelectAlias;
// /** @noinspection PhpMethodParametersCountMismatchInspection */
// $qb->selectAlias('s.address', 'service_address')
// ->selectAlias('s.status', 'service_status')
// ->selectAlias('s.config', 'service_config')
// ->selectAlias('s.type', 'service_type')
// ->leftJoin(
// $this->defaultSelectAlias, CoreRequestBuilder::TABLE_SERVICES, 's',
// $expr->eq($pf . '.service_id', 's.id')
// );
// }
$qb->selectAlias('ca.id', 'cacheactor_id')
->selectAlias('ca.account', 'cacheactor_account')
->selectAlias('ca.following', 'cacheactor_following')
->selectAlias('ca.followers', 'cacheactor_followers')
->selectAlias('ca.inbox', 'cacheactor_inbox')
->selectAlias('ca.shared_inbox', 'cacheactor_shared_inbox')
->selectAlias('ca.outbox', 'cacheactor_outbox')
->selectAlias('ca.featured', 'cacheactor_featured')
->selectAlias('ca.url', 'cacheactor_url')
->selectAlias('ca.preferred_username', 'cacheactor_preferred_username')
->selectAlias('ca.name', 'cacheactor_name')
->selectAlias('ca.summary', 'cacheactor_summary')
->selectAlias('ca.public_key', 'cacheactor_public_key')
->selectAlias('ca.creation', 'cacheactor_creation')
->leftJoin(
$this->defaultSelectAlias, CoreRequestBuilder::TABLE_CACHE_ACTORS, 'ca',
$expr->eq($pf . '.' . $fieldActorId, 'ca.id')
);
}
/**
* @param array $data
*
* @return Person
* @throws InvalidResourceException
*/
protected function parseCacheActorsLeftJoin(array $data): Person {
$new = [];
foreach ($data as $k => $v) {
if (substr($k, 0, 11) === 'cacheactor_') {
$new[substr($k, 11)] = $v;
}
}
$actor = new Person();
$actor->import($new);
if ($actor->getType() !== 'Person') {
throw new InvalidResourceException();
}
return $actor;
}
}

Wyświetl plik

@ -99,14 +99,16 @@ class NotesRequest extends NotesRequestBuilder {
/**
* @param string $actorId
* @param int $since
* @param int $limit
*
* @return array
*/
public function getPublicNotes($since = 0, $limit = 5): array {
public function getPublicNotes(int $since = 0, int $limit = 5): array {
$qb = $this->getNotesSelectSql();
$this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
$this->limitPaginate($qb, $since, $limit);
$this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
$cursor = $qb->execute();
@ -126,6 +128,7 @@ class NotesRequest extends NotesRequestBuilder {
public function getNotesForActorId(string $actorId): array {
$qb = $this->getNotesSelectSql();
$this->limitToRecipient($qb, $actorId);
$this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
$cursor = $qb->execute();

Wyświetl plik

@ -31,8 +31,8 @@ namespace OCA\Social\Db;
use daita\MySmallPhpTools\Traits\TArrayTools;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Model\ActivityPub\Note;
use OCA\Social\Model\Post;
use OCP\DB\QueryBuilder\IQueryBuilder;
class NotesRequestBuilder extends CoreRequestBuilder {
@ -118,32 +118,15 @@ class NotesRequestBuilder extends CoreRequestBuilder {
->setAttributedTo($data['attributed_to'])
->setInReplyTo($data['in_reply_to']);
try {
$actor = $this->parseCacheActorsLeftJoin($data);
$note->setCompleteDetails(true);
$note->setActor($actor);
} catch (InvalidResourceException $e) {
}
return $note;
}
/**
* @param array $data
*
* @return Post
*/
protected function parsePostsSelectSql($userId, $data): Note {
$post = new Post($userId);
$post->setContent($data['content']);
// $note->setId($data['id'])
// ->setTo($data['to'])
// ->setToArray(json_decode($data['to_array'], true))
// ->setCc(json_decode($data['cc'], true))
// ->setBcc(json_decode($data['bcc']));
// $note->setContent($data['content'])
// ->setPublished($data['published'])
// ->setAttributedTo($data['attributed_to'])
// ->setInReplyTo($data['in_reply_to']);
return $post;
}
}

Wyświetl plik

@ -109,6 +109,8 @@ abstract class ACore implements JsonSerializable {
/** @var ICoreService */
private $saveAs;
/** @var bool */
private $completeDetails = false;
/**
* Core constructor.
@ -685,6 +687,25 @@ abstract class ACore implements JsonSerializable {
}
/**
* @return bool
*/
public function isCompleteDetails(): bool {
return $this->completeDetails;
}
/**
* @param bool $completeDetails
*
* @return ACore
*/
public function setCompleteDetails(bool $completeDetails): ACore {
$this->completeDetails = $completeDetails;
return $this;
}
/**
* @param array $data
*/
@ -727,6 +748,9 @@ abstract class ACore implements JsonSerializable {
'actor', $this->getActor()
->getId()
);
if ($this->isCompleteDetails()) {
$this->addEntryItem('actor_info', $this->getActor());
}
} else {
$this->addEntry('actor', $this->getActorId());
}

Wyświetl plik

@ -353,6 +353,10 @@ class Person extends ACore implements JsonSerializable {
->setSharedInbox($this->get('shared_inbox', $data, ''))
->setFeatured($this->get('featured', $data, ''))
->setCreation($this->getInt('creation', $data, 0));
if ($this->getPreferredUsername() === '') {
$this->setType('Invalid');
}
}
@ -371,6 +375,7 @@ class Person extends ACore implements JsonSerializable {
'name' => $this->getName(),
'inbox' => $this->getInbox(),
'outbox' => $this->getOutbox(),
'account' => $this->getAccount(),
'following' => $this->getFollowing(),
'followers' => $this->getFollowers(),
'endpoints' =>

Wyświetl plik

@ -236,17 +236,9 @@ class NoteService implements ICoreService {
*
* @return Note[]
*/
public function getTimeline($since = 0, $limit = 5): array {
$notes = $this->notesRequest->getPublicNotes($since, $limit);
$result = [];
/** @var Note $note */
foreach ($notes as $note) {
$actor = $this->actorService->getActorById($note->getAttributedTo());
$noteEnhanced = $note->jsonSerialize();
$noteEnhanced['actor'] = $actor->jsonSerialize();
$result[] = $noteEnhanced;
}
return $result;
public function getTimeline(int $since = 0, int $limit = 5): array {
return $this->notesRequest->getPublicNotes($since, $limit);
// return $result;
}

Wyświetl plik

@ -175,6 +175,5 @@ class PersonService implements ICoreService {
$this->cacheActorsRequest->save($person);
}
}