-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #462 from eikek/alias-member
Alias member
- Loading branch information
Showing
38 changed files
with
1,482 additions
and
236 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 61 additions & 18 deletions
79
modules/backend/src/main/scala/sharry/backend/alias/OAlias.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,103 @@ | ||
package sharry.backend.alias | ||
|
||
import cats.data.OptionT | ||
import cats.effect._ | ||
import cats.implicits._ | ||
import fs2.Stream | ||
|
||
import sharry.backend.alias.OAlias.{AliasDetail, AliasInput} | ||
import sharry.common._ | ||
import sharry.common.syntax.all._ | ||
import sharry.store.AddResult | ||
import sharry.store.Store | ||
import sharry.store.records.RAlias | ||
import sharry.store.records.RAliasMember | ||
|
||
import doobie._ | ||
import org.log4s._ | ||
|
||
trait OAlias[F[_]] { | ||
|
||
def create(alias: RAlias): F[AddResult] | ||
def create(alias: AliasInput): F[AddResult] | ||
|
||
def createF(alias: F[RAlias]): F[AddResult] | ||
def createF(alias: F[AliasInput]): F[AddResult] | ||
|
||
def modify(aliasId: Ident, accId: Ident, alias: RAlias): F[AddResult] | ||
def modify(aliasId: Ident, accId: Ident, alias: AliasInput): F[AddResult] | ||
|
||
def findAll(accId: Ident, nameQuery: String): Stream[F, RAlias] | ||
def findAll(accId: Ident, nameQuery: String): Stream[F, AliasDetail] | ||
|
||
def findById(id: Ident, accId: Ident): F[Option[RAlias]] | ||
def findById(id: Ident, accId: Ident): F[Option[AliasDetail]] | ||
|
||
def delete(id: Ident, accId: Ident): F[Boolean] | ||
} | ||
|
||
object OAlias { | ||
private[this] val logger = getLogger | ||
|
||
/** Details about an alias including a list of user-ids that make up its members. */ | ||
case class AliasInput(alias: RAlias, members: List[Ident]) | ||
|
||
case class AliasDetail(alias: RAlias, ownerLogin: Ident, members: List[AliasMember]) | ||
|
||
case class AliasMember(accountId: Ident, login: Ident) | ||
|
||
def apply[F[_]: Effect](store: Store[F]): Resource[F, OAlias[F]] = | ||
Resource.pure[F, OAlias[F]](new OAlias[F] { | ||
def create(alias: RAlias): F[AddResult] = | ||
store.add(RAlias.insert(alias), RAlias.existsById(alias.id)) | ||
|
||
def createF(alias: F[RAlias]): F[AddResult] = | ||
def create(detail: AliasInput): F[AddResult] = | ||
store.add( | ||
for { | ||
n <- RAlias.insert(detail.alias) | ||
k <- | ||
if (n > 0) | ||
RAliasMember.insertForAlias(detail.alias.id, detail.members) | ||
else 0.pure[ConnectionIO] | ||
} yield n + k, | ||
RAlias.existsById(detail.alias.id) | ||
) | ||
|
||
def createF(alias: F[AliasInput]): F[AddResult] = | ||
alias.flatMap(create) | ||
|
||
def modify(aliasId: Ident, accId: Ident, alias: RAlias): F[AddResult] = { | ||
val exists = RAlias.existsById(alias.id) | ||
val modify = RAlias.update(aliasId, accId, alias) | ||
def modify( | ||
aliasId: Ident, | ||
accId: Ident, | ||
detail: AliasInput | ||
): F[AddResult] = { | ||
val doUpdate = for { | ||
n <- RAlias.update(aliasId, accId, detail.alias) | ||
k <- | ||
if (n > 0) RAliasMember.updateForAlias(aliasId, detail.members) | ||
else 0.pure[ConnectionIO] | ||
} yield n + k | ||
|
||
for { | ||
_ <- logger.fdebug(s"Modify alias '${aliasId.id}' to $alias") | ||
res <- store.add(modify, exists) | ||
_ <- logger.fdebug(s"Modify alias '${aliasId.id}' to ${detail.alias}") | ||
n <- store.transact(doUpdate) | ||
res = | ||
if (n > 0) AddResult.Success | ||
else AddResult.Failure(new Exception("No rows modified!")) | ||
} yield res | ||
} | ||
|
||
def findAll(accId: Ident, nameQuery: String): Stream[F, RAlias] = | ||
store.transact(RAlias.findAll(accId, nameQuery)) | ||
def findAll( | ||
accId: Ident, | ||
nameQuery: String | ||
): Stream[F, AliasDetail] = | ||
store | ||
.transact(RAlias.findAll(accId, nameQuery).evalMap(loadMembers)) | ||
|
||
def findById(id: Ident, accId: Ident): F[Option[RAlias]] = | ||
store.transact(RAlias.findById(id, accId)) | ||
def findById(id: Ident, accId: Ident): F[Option[AliasDetail]] = | ||
store.transact(OptionT(RAlias.findById(id, accId)).semiflatMap(loadMembers).value) | ||
|
||
def delete(id: Ident, accId: Ident): F[Boolean] = | ||
store.transact(RAlias.delete(id, accId)).map(_ > 0) | ||
|
||
private def loadMembers(alias: (RAlias, Ident)): ConnectionIO[AliasDetail] = | ||
for { | ||
members <- RAliasMember.findForAlias(alias._1.id) | ||
conv = members.map(t => AliasMember(t._1.accountId, t._2)) | ||
} yield AliasDetail(alias._1, alias._2, conv) | ||
|
||
}) | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
modules/backend/src/main/scala/sharry/backend/mail/NotifyData.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package sharry.backend.mail | ||
|
||
import sharry.backend.mail.NotifyData.AccountInfo | ||
import sharry.common._ | ||
|
||
final case class NotifyData( | ||
aliasId: Ident, | ||
aliasName: String, | ||
users: List[AccountInfo] | ||
) | ||
|
||
object NotifyData { | ||
|
||
final case class AccountInfo(login: Ident, email: String) | ||
} |
39 changes: 28 additions & 11 deletions
39
modules/backend/src/main/scala/sharry/backend/mail/NotifyResult.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,36 @@ | ||
package sharry.backend.mail | ||
|
||
sealed trait NotifyResult {} | ||
import emil.MailAddress | ||
|
||
object NotifyResult { | ||
def missingEmail: NotifyResult = MissingEmail | ||
def featureDisabled: NotifyResult = FeatureDisabled | ||
|
||
case object InvalidAlias extends NotifyResult | ||
|
||
case object FeatureDisabled extends NotifyResult | ||
sealed trait NotifyResult { | ||
def isSuccess: Boolean | ||
def isError: Boolean = | ||
!isSuccess | ||
|
||
case object MissingEmail extends NotifyResult | ||
def receiver: Option[MailAddress] | ||
} | ||
|
||
case class SendFailed(err: String) extends NotifyResult | ||
object NotifyResult { | ||
def featureDisabled: NotifyResult = FeatureDisabled | ||
|
||
case object SendSuccessful extends NotifyResult | ||
case object InvalidAlias extends NotifyResult { | ||
val isSuccess = false | ||
def receiver: Option[MailAddress] = None | ||
} | ||
|
||
case object FeatureDisabled extends NotifyResult { | ||
val isSuccess = false | ||
def receiver: Option[MailAddress] = None | ||
} | ||
|
||
case class SendFailed(mail: MailAddress, err: String) extends NotifyResult { | ||
val isSuccess = false | ||
def receiver: Option[MailAddress] = Some(mail) | ||
} | ||
|
||
case class SendSuccessful(mail: MailAddress) extends NotifyResult { | ||
val isSuccess = true | ||
def receiver: Option[MailAddress] = Some(mail) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.