From e387b5513f85f26c291365482d51ead21ff1c8af Mon Sep 17 00:00:00 2001 From: Eike Kettner <eike.kettner@posteo.de> Date: Sat, 11 Jul 2020 22:16:09 +0200 Subject: [PATCH] Remove items in non-member folders from sql search results --- .../joex/notify/NotifyDueItemsTask.scala | 2 +- .../docspell/store/queries/QFolder.scala | 26 +++++++++++++++++++ .../scala/docspell/store/queries/QItem.scala | 23 ++++++++++------ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala b/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala index 218b4d0d..1eb24a75 100644 --- a/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/notify/NotifyDueItemsTask.scala @@ -71,7 +71,7 @@ object NotifyDueItemsTask { now <- Timestamp.current[F] q = QItem.Query - .empty(ctx.args.account.collective) + .empty(ctx.args.account) .copy( states = ItemState.validStates.toList, tagsInclude = ctx.args.tagsInclude, diff --git a/modules/store/src/main/scala/docspell/store/queries/QFolder.scala b/modules/store/src/main/scala/docspell/store/queries/QFolder.scala index 1495d1b0..8f8b50a8 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QFolder.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QFolder.scala @@ -244,6 +244,32 @@ object QFolder { .to[Vector] } + /** Select all folder_id where the given account is member or owner. */ + def findMemberFolderIds(account: AccountId): Fragment = { + val fId = RFolder.Columns.id.prefix("f") + val fOwner = RFolder.Columns.owner.prefix("f") + val fColl = RFolder.Columns.collective.prefix("f") + val uId = RUser.Columns.uid.prefix("u") + val uLogin = RUser.Columns.login.prefix("u") + val mFolder = RFolderMember.Columns.folder.prefix("m") + val mUser = RFolderMember.Columns.user.prefix("m") + + selectSimple( + Seq(fId), + RFolder.table ++ fr"f INNER JOIN" ++ RUser.table ++ fr"u ON" ++ fOwner.is(uId), + and(fColl.is(account.collective), uLogin.is(account.user)) + ) ++ + fr"UNION ALL" ++ + selectSimple( + Seq(mFolder), + RFolderMember.table ++ fr"m INNER JOIN" ++ RFolder.table ++ fr"f ON" ++ fId.is( + mFolder + ) ++ + fr"INNER JOIN" ++ RUser.table ++ fr"u ON" ++ uId.is(mUser), + and(fColl.is(account.collective), uLogin.is(account.user)) + ) + } + private def findUserId(account: AccountId): ConnectionIO[Option[Ident]] = RUser.findByAccount(account).map(_.map(_.uid)) } diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala index e4618772..99415125 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala @@ -273,17 +273,20 @@ object QItem { ) ++ moreCols ) - val withItem = selectSimple(itemCols, RItem.table, IC.cid.is(q.account.collective)) - val withPerson = selectSimple(personCols, RPerson.table, PC.cid.is(q.account.collective)) - val withOrgs = selectSimple(orgCols, ROrganization.table, OC.cid.is(q.account.collective)) - val withEquips = selectSimple(equipCols, REquipment.table, EC.cid.is(q.account.collective)) + val withItem = selectSimple(itemCols, RItem.table, IC.cid.is(q.account.collective)) + val withPerson = + selectSimple(personCols, RPerson.table, PC.cid.is(q.account.collective)) + val withOrgs = + selectSimple(orgCols, ROrganization.table, OC.cid.is(q.account.collective)) + val withEquips = + selectSimple(equipCols, REquipment.table, EC.cid.is(q.account.collective)) val withFolder = selectSimple(folderCols, RFolder.table, FC.collective.is(q.account.collective)) val withAttach = fr"SELECT COUNT(" ++ AC.id.f ++ fr") as num, " ++ AC.itemId.f ++ fr"from" ++ RAttachment.table ++ fr"GROUP BY (" ++ AC.itemId.f ++ fr")" val selectKW = if (distinct) fr"SELECT DISTINCT" else fr"SELECT" - val query = withCTE( + withCTE( (Seq( "items" -> withItem, "persons" -> withPerson, @@ -302,7 +305,6 @@ object QItem { .prefix("i") .is(EC.eid.prefix("e1")) ++ fr"LEFT JOIN folders f1 ON" ++ IC.folder.prefix("i").is(FC.id.prefix("f1")) - query } def findItems(q: Query, batch: Batch): Stream[ConnectionIO, ListItem] = { @@ -334,6 +336,7 @@ object QItem { RTagItem.Columns.tagId.isOneOf(q.tagsExclude) ) + val iFolder = IC.folder.prefix("i") val name = q.name.map(_.toLowerCase).map(queryWildcard) val allNames = q.allNames.map(_.toLowerCase).map(queryWildcard) val cond = and( @@ -385,7 +388,8 @@ object QItem { .map(nel => IC.id.prefix("i").isIn(nel)) .getOrElse(IC.id.prefix("i").is("")) ) - .getOrElse(Fragment.empty) + .getOrElse(Fragment.empty), + or(iFolder.isNull, iFolder.isIn(QFolder.findMemberFolderIds(q.account))) ) val order = q.orderAsc match { @@ -476,7 +480,10 @@ object QItem { n <- store.transact(RItem.deleteByIdAndCollective(itemId, collective)) } yield tn + rn + n + mn - private def findByFileIdsQuery(fileMetaIds: NonEmptyList[Ident], limit: Option[Int]): Fragment = { + private def findByFileIdsQuery( + fileMetaIds: NonEmptyList[Ident], + limit: Option[Int] + ): Fragment = { val IC = RItem.Columns.all.map(_.prefix("i")) val aItem = RAttachment.Columns.itemId.prefix("a") val aId = RAttachment.Columns.id.prefix("a")