diff --git a/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala b/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala index 39faa985..d9613312 100644 --- a/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala +++ b/modules/backend/src/main/scala/docspell/backend/ops/OItem.scala @@ -72,15 +72,18 @@ object OItem { def data: Stream[F, Byte] def name: Option[String] def meta: FileMeta + def fileId: Ident } case class AttachmentData[F[_]](ra: RAttachment, meta: FileMeta, data: Stream[F, Byte]) extends BinaryData[F] { val name = ra.name + val fileId = ra.fileId } case class AttachmentSourceData[F[_]](rs: RAttachmentSource, meta: FileMeta, data: Stream[F, Byte]) extends BinaryData[F] { val name = rs.name + val fileId = rs.fileId } def apply[F[_]: Effect](store: Store[F]): Resource[F, OItem[F]] = @@ -97,26 +100,40 @@ object OItem { .transact(RAttachment.findByIdAndCollective(id, collective)) .flatMap({ case Some(ra) => - store.bitpeace - .get(ra.fileId.id) - .unNoneTerminate - .compile - .last - .map( - _.map(m => - AttachmentData[F]( - ra, - m, - store.bitpeace.fetchData2(RangeDef.all)(Stream.emit(m)) - ) - ) + makeBinaryData(ra.fileId) { m => + AttachmentData[F]( + ra, + m, + store.bitpeace.fetchData2(RangeDef.all)(Stream.emit(m)) ) + } + case None => (None: Option[AttachmentData[F]]).pure[F] }) def findAttachmentSource(id: Ident, collective: Ident): F[Option[AttachmentSourceData[F]]] = - ??? + store + .transact(RAttachmentSource.findByIdAndCollective(id, collective)) + .flatMap({ + case Some(ra) => + makeBinaryData(ra.fileId) { m => + AttachmentSourceData[F]( + ra, + m, + store.bitpeace.fetchData2(RangeDef.all)(Stream.emit(m)) + ) + } + + case None => + (None: Option[AttachmentSourceData[F]]).pure[F] + }) + + private def makeBinaryData[A](fileId: Ident)(f: FileMeta => A): F[Option[A]] = + store.bitpeace + .get(fileId.id).unNoneTerminate.compile.last.map( + _.map(m => f(m)) + ) def setTags(item: Ident, tagIds: List[Ident], collective: Ident): F[AddResult] = { val db = for { diff --git a/modules/store/src/main/scala/docspell/store/records/RAttachmentSource.scala b/modules/store/src/main/scala/docspell/store/records/RAttachmentSource.scala index 052be661..91d70e44 100644 --- a/modules/store/src/main/scala/docspell/store/records/RAttachmentSource.scala +++ b/modules/store/src/main/scala/docspell/store/records/RAttachmentSource.scala @@ -43,4 +43,20 @@ object RAttachmentSource { def delete(attachId: Ident): ConnectionIO[Int] = deleteFrom(table, id.is(attachId)).update.run + + def findByIdAndCollective(attachId: Ident, collective: Ident): ConnectionIO[Option[RAttachmentSource]] = { + val bId = RAttachment.Columns.id.prefix("b") + val aId = Columns.id.prefix("a") + val bItem = RAttachment.Columns.itemId.prefix("b") + val iId = RItem.Columns.id.prefix("i") + val iColl = RItem.Columns.cid.prefix("i") + + val from = table ++ fr"a INNER JOIN" ++ + RAttachment.table ++ fr"b ON" ++ aId.is(bId) ++ + fr"INNER JOIN" ++ RItem.table ++ fr"i ON" ++ bItem.is(iId) + + val where = and(aId.is(attachId), bId.is(attachId), iColl.is(collective)) + + selectSimple(all.map(_.prefix("a")), from, where).query[RAttachmentSource].option + } }