From bfa2df2f167435b9cb0f60524431cba0db716081 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Mon, 20 Jun 2022 09:48:42 -0100 Subject: [PATCH] enable multiple table/fields comparaison when using queryHelper Signed-off-by: Maxence Lange --- lib/CirclesQueryHelper.php | 24 ++++----- lib/Db/CoreQueryBuilder.php | 102 +++++++++++++++++++++++------------- 2 files changed, 77 insertions(+), 49 deletions(-) diff --git a/lib/CirclesQueryHelper.php b/lib/CirclesQueryHelper.php index 5dbf0cd43..2220d8409 100644 --- a/lib/CirclesQueryHelper.php +++ b/lib/CirclesQueryHelper.php @@ -86,17 +86,15 @@ public function getQueryBuilder(): IQueryBuilder { /** - * @param string $alias - * @param string $field + * @param array $fields * @param bool $fullDetails * * @return ICompositeExpression - * @throws RequestBuilderException * @throws FederatedUserNotFoundException + * @throws RequestBuilderException */ public function limitToSession( - string $alias, - string $field, + array $fields, bool $fullDetails = false ): ICompositeExpression { $session = $this->federatedUserService->getCurrentUser(); @@ -104,7 +102,7 @@ public function limitToSession( throw new FederatedUserNotFoundException('session not initiated'); } - $this->queryBuilder->setDefaultSelectAlias($alias); +// $this->queryBuilder->setDefaultSelectAlias($alias); $this->queryBuilder->setOptions( [CoreQueryBuilder::HELPER], [ @@ -116,8 +114,8 @@ public function limitToSession( return $this->queryBuilder->limitToInitiator( CoreQueryBuilder::HELPER, $session, - $field, - $alias + '', + $fields ); } @@ -127,17 +125,18 @@ public function limitToSession( * @param string $field * @param IFederatedUser $federatedUser * @param bool $fullDetails + * @param array $extraFields * * @return ICompositeExpression * @throws RequestBuilderException */ public function limitToInheritedMembers( - string $alias, string $field, + string $alias, IFederatedUser $federatedUser, - bool $fullDetails = false + bool $fullDetails = false, + array $extraFields = [] ): ICompositeExpression { - $this->queryBuilder->setDefaultSelectAlias($alias); $this->queryBuilder->setOptions( [CoreQueryBuilder::HELPER], [ @@ -150,7 +149,8 @@ public function limitToInheritedMembers( CoreQueryBuilder::HELPER, $federatedUser, $field, - $alias + $alias, + $extraFields ); } diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php index 01268ea0d..e093c93af 100644 --- a/lib/Db/CoreQueryBuilder.php +++ b/lib/Db/CoreQueryBuilder.php @@ -56,29 +56,33 @@ class CoreQueryBuilder extends ExtendedQueryBuilder { use TArrayTools; - public const SINGLE = 'cs'; - public const CIRCLE = 'cc'; - public const MEMBER = 'mm'; - public const OWNER = 'wn'; - public const FEDERATED_EVENT = 'ev'; - public const REMOTE = 'rm'; - public const BASED_ON = 'on'; - public const INITIATOR = 'in'; - public const DIRECT_INITIATOR = 'di'; - public const MEMBERSHIPS = 'ms'; - public const CONFIG = 'cf'; - public const UPSTREAM_MEMBERSHIPS = 'up'; - public const INHERITANCE_FROM = 'ih'; - public const INHERITED_BY = 'by'; - public const INVITED_BY = 'nv'; - public const MOUNT = 'mo'; - public const MOUNTPOINT = 'mp'; - public const SHARE = 'sh'; - public const FILE_CACHE = 'fc'; - public const STORAGES = 'st'; - public const TOKEN = 'tk'; - public const OPTIONS = 'pt'; - public const HELPER = 'hp'; + public const SINGLE = 'ca'; + public const CIRCLE = 'cb'; + public const MEMBER = 'cc'; + public const OWNER = 'cd'; + public const FEDERATED_EVENT = 'ce'; + public const REMOTE = 'cf'; + public const BASED_ON = 'cg'; + public const INITIATOR = 'ch'; + public const DIRECT_INITIATOR = 'ci'; + public const MEMBERSHIPS = 'cj'; + public const CONFIG = 'ck'; + public const UPSTREAM_MEMBERSHIPS = 'cl'; + public const INHERITANCE_FROM = 'cm'; + public const INHERITED_BY = 'cn'; + public const INVITED_BY = 'co'; + public const MOUNT = 'cp'; + public const MOUNTPOINT = 'cq'; + public const SHARE = 'cr'; + public const FILE_CACHE = 'cs'; + public const STORAGES = 'ct'; + public const TOKEN = 'cu'; + public const OPTIONS = 'cv'; + public const HELPER = 'cw'; + public const SYNC_ITEM = 'cx'; + public const SYNC_SHARE = 'cy'; + public const SYNC_LOCK = 'cz'; + public const DEBUG = 'c0'; public static $SQL_PATH = [ @@ -1106,7 +1110,8 @@ public function leftJoinShareToken(string $alias, string $field = ''): void { * @param string $alias * @param IFederatedUser $user * @param string $field - * @param string $helperAlias + * @param string $helperAlias - must only be filled when called from CirclesQueryHelper + * @param array $helperMoreFields - must only be filled when called from CirclesQueryHelper * * @return ICompositeExpression * @throws RequestBuilderException @@ -1115,9 +1120,10 @@ public function limitToInitiator( string $alias, IFederatedUser $user, string $field = '', - string $helperAlias = '' + string $helperAlias = '', + array $helperMoreFields = [] ): ICompositeExpression { - $this->leftJoinInitiator($alias, $user, $field, $helperAlias); + $this->leftJoinInitiator($alias, $user, $field, $helperAlias, $helperMoreFields); $where = $this->limitInitiatorVisibility($alias); $aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options); @@ -1156,8 +1162,9 @@ public function leftJoinCircleConfig(string $alias): void { * * @param string $alias * @param IFederatedUser $initiator - * @param string $field - * @param string $helperAlias + * @param string $coreField + * @param string $helperAlias - must only be filled when called from CirclesQueryHelper + * @param array $helperMoreFields - must only be filled when called from CirclesQueryHelper * * @throws RequestBuilderException */ @@ -1165,24 +1172,37 @@ public function leftJoinInitiator( string $alias, IFederatedUser $initiator, string $field = '', - string $helperAlias = '' + string $helperAlias = '', + array $helperMoreFields = [] ): void { if ($this->getType() !== QueryBuilder::SELECT) { return; } + if (!empty($helperMoreFields)) { + $helperMoreFields[] = $helperAlias . '.' . $field; + } + $expr = $this->expr(); $field = ($field === '') ? 'unique_id' : $field; $helperAlias = ($helperAlias !== '') ? $helperAlias : $alias; + $aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options); + $orXMembershipFields = $expr->orX(); + foreach ($helperMoreFields as $f) { + $orXMembershipFields->add($expr->eq($aliasMembership . '.circle_id', $f)); + } + $this->leftJoin( $helperAlias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership, $expr->andX( $this->exprLimit('single_id', $initiator->getSingleId(), $aliasMembership), - $expr->eq($aliasMembership . '.circle_id', $helperAlias . '.' . $field) + (empty($helperMoreFields)) ? + $expr->eq($aliasMembership . '.circle_id', $helperAlias . '.' . $field) : + $orXMembershipFields ) ); @@ -1190,8 +1210,8 @@ public function leftJoinInitiator( $listMembershipCircleAlias = [$aliasMembership]; if ($this->getBool('initiatorDirectMember', $options, false)) { try { - $aliasDirectInitiator = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options); - $listMembershipCircleAlias[] = $aliasDirectInitiator; + $aliasDirect = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options); + $listMembershipCircleAlias[] = $aliasDirect; } catch (RequestBuilderException $e) { // meaning that this path does not require DIRECT_INITIATOR; can be safely ignored } @@ -1229,15 +1249,23 @@ function (string $alias) use ($orXMembershipCircle, $aliasMembershipCircle) { // bypass memberships if ($this->getBool('initiatorDirectMember', $options, false)) { try { - $aliasDirectInitiator = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options); - $this->generateMemberSelectAlias($aliasDirectInitiator) + $aliasDirect = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options); + + $orXDirectFields = $expr->orX(); + foreach ($helperMoreFields as $f) { + $orXDirectFields->add($expr->eq($aliasMembership . '.circle_id', $f)); + } + + $this->generateMemberSelectAlias($aliasDirect) ->leftJoin( $helperAlias, CoreRequestBuilder::TABLE_MEMBER, - $aliasDirectInitiator, + $aliasDirect, $expr->andX( - $this->exprLimit('single_id', $initiator->getSingleId(), $aliasDirectInitiator), - $expr->eq($aliasDirectInitiator . '.circle_id', $helperAlias . '.' . $field) + $this->exprLimit('single_id', $initiator->getSingleId(), $aliasDirect), + (empty($helperMoreFields)) ? + $expr->eq($aliasDirect . '.circle_id', $helperAlias . '.' . $field) : + $orXDirectFields ) ); } catch (RequestBuilderException $e) {