1 /*
2  *  Make.org Core API
3  *  Copyright (C) 2018 Make.org
4  *
5  * This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 package org.make.api.feature
21 
22 import cats.data.NonEmptyList
23 import cats.implicits._
24 import grizzled.slf4j.Logging
25 import org.make.api.extensions.MakeDBExecutionContextComponent
26 import org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature
27 import org.make.api.technical.DatabaseTransactions._
28 import org.make.api.technical.PersistentServiceUtils.sortOrderQuery
29 import org.make.api.technical.ScalikeSupport._
30 import org.make.api.technical.{PersistentCompanion, ShortenedNames}
31 import org.make.core.technical.Pagination
32 import org.make.core.feature.{Feature, FeatureId, FeatureSlug}
33 import org.make.core.Order
34 import scalikejdbc._
35 
36 import scala.concurrent.Future
37 
38 trait DefaultPersistentFeatureServiceComponent extends PersistentFeatureServiceComponent {
39   this: MakeDBExecutionContextComponent =>
40 
41   override lazy val persistentFeatureService: PersistentFeatureService = new DefaultPersistentFeatureService
42 
43   class DefaultPersistentFeatureService extends PersistentFeatureService with ShortenedNames with Logging {
44 
45     private val featureAlias = PersistentFeature.alias
46 
47     private val column = PersistentFeature.column
48 
49     override def get(featureId: FeatureId): Future[Option[Feature]] = {
50       implicit val context: EC = readExecutionContext
51       val futurePersistentFeature = Future(NamedDB("READ").retryableTx { implicit session =>
52         withSQL {
53           select
54             .from(PersistentFeature.as(featureAlias))
55             .where(sqls.eq(featureAlias.id, featureId.value))
56         }.map(PersistentFeature.apply()).single()
57       })
58 
59       futurePersistentFeature.map(_.map(_.toFeature))
60     }
61 
62     def findBySlug(slug: FeatureSlug): Future[Seq[Feature]] = {
63       implicit val context: EC = readExecutionContext
64       val futurePersistentFeatures: Future[List[PersistentFeature]] = Future(NamedDB("READ").retryableTx {
65         implicit session =>
66           withSQL {
67             select
68               .from(PersistentFeature.as(featureAlias))
69               .where(sqls.eq(featureAlias.slug, slug))
70           }.map(PersistentFeature.apply()).list()
71       })
72 
73       futurePersistentFeatures.map(_.map(_.toFeature))
74     }
75 
76     override def persist(feature: Feature): Future[Feature] = {
77       implicit val context: EC = writeExecutionContext
78       Future(NamedDB("WRITE").retryableTx { implicit session =>
79         withSQL {
80           insert
81             .into(PersistentFeature)
82             .namedValues(column.id -> feature.featureId.value, column.slug -> feature.slug, column.name -> feature.name)
83         }.execute()
84       }).map(_ => feature)
85     }
86 
87     override def update(feature: Feature): Future[Option[Feature]] = {
88       implicit val ctx: EC = writeExecutionContext
89       Future(NamedDB("WRITE").retryableTx { implicit session =>
90         withSQL {
91           scalikejdbc
92             .update(PersistentFeature)
93             .set(column.slug -> feature.slug, column.name -> feature.name)
94             .where(sqls.eq(column.id, feature.featureId.value))
95         }.executeUpdate()
96       }).map {
97         case 1 => Some(feature)
98         case 0 => None
99       }
100     }
101 
102     override def remove(featureId: FeatureId): Future[Unit] = {
103       implicit val context: EC = writeExecutionContext
104       Future(NamedDB("WRITE").retryableTx { implicit session =>
105         withSQL {
106           delete
107             .from(PersistentFeature.as(featureAlias))
108             .where(sqls.eq(featureAlias.id, featureId.value))
109         }.update()
110       }).void
111     }
112 
113     override def findAll(): Future[Seq[Feature]] = {
114       implicit val context: EC = readExecutionContext
115       val futurePersistentFeatures: Future[List[PersistentFeature]] = Future(NamedDB("READ").retryableTx {
116         implicit session =>
117           withSQL {
118             select
119               .from(PersistentFeature.as(featureAlias))
120               .orderBy(featureAlias.slug)
121           }.map(PersistentFeature.apply()).list()
122       })
123 
124       futurePersistentFeatures.map(_.map(_.toFeature))
125     }
126 
127     override def findByFeatureIds(featureIds: Seq[FeatureId]): Future[Seq[Feature]] = {
128       implicit val context: EC = readExecutionContext
129       val futurePersistentFeatures: Future[List[PersistentFeature]] = Future(NamedDB("READ").retryableTx {
130         implicit session =>
131           withSQL {
132             select
133               .from(PersistentFeature.as(featureAlias))
134               .where(sqls.in(featureAlias.id, featureIds.map(_.value)))
135               .orderBy(featureAlias.slug)
136           }.map(PersistentFeature.apply()).list()
137       })
138 
139       futurePersistentFeatures.map(_.map(_.toFeature))
140     }
141 
142     override def find(
143       offset: Pagination.Offset,
144       end: Option[Pagination.End],
145       sort: Option[String],
146       order: Option[Order],
147       maybeSlug: Option[String]
148     ): Future[Seq[Feature]] = {
149       implicit val context: EC = readExecutionContext
150 
151       val futurePersistentFeatures: Future[List[PersistentFeature]] = Future(NamedDB("READ").retryableTx {
152         implicit session =>
153           withSQL {
154 
155             val query: scalikejdbc.PagingSQLBuilder[PersistentFeature] =
156               select
157                 .from(PersistentFeature.as(featureAlias))
158                 .where(sqls.toAndConditionOpt(maybeSlug.map(slug => sqls.like(featureAlias.slug, s"%$slug%"))))
159 
160             sortOrderQuery(offset, end, sort, order, query)
161           }.map(PersistentFeature.apply()).list()
162       })
163 
164       futurePersistentFeatures.map(_.map(_.toFeature))
165     }
166 
167     override def count(maybeSlug: Option[String]): Future[Int] = {
168       implicit val context: EC = readExecutionContext
169 
170       Future(NamedDB("READ").retryableTx { implicit session =>
171         withSQL {
172 
173           select(sqls.count)
174             .from(PersistentFeature.as(featureAlias))
175             .where(sqls.toAndConditionOpt(maybeSlug.map(slug => sqls.like(featureAlias.slug, s"%$slug%"))))
176         }.map(_.int(1)).single().getOrElse(0)
177       })
178     }
179   }
180 }
181 
182 object DefaultPersistentFeatureServiceComponent {
183 
184   final case class PersistentFeature(id: String, slug: String, name: String) {
185     def toFeature: Feature =
186       Feature(featureId = FeatureId(id), slug = FeatureSlug(slug), name = name)
187   }
188 
189   implicit object PersistentFeature
190       extends PersistentCompanion[PersistentFeature, Feature]
191       with ShortenedNames
192       with Logging {
193 
194     override val columnNames: Seq[String] = Seq("id", "slug", "name")
195     final val swaggerAllowableValues = "id,slug,name"
196 
197     override val tableName: String = "feature"
198 
199     override lazy val alias: SyntaxProvider[PersistentFeature] = syntax("feature")
200 
201     override lazy val defaultSortColumns: NonEmptyList[SQLSyntax] = NonEmptyList.of(alias.slug)
202 
203     def apply(
204       featureResultName: ResultName[PersistentFeature] = alias.resultName
205     )(resultSet: WrappedResultSet): PersistentFeature = {
206       PersistentFeature.apply(
207         id = resultSet.string(featureResultName.id),
208         slug = resultSet.string(featureResultName.slug),
209         name = resultSet.string(featureResultName.name)
210       )
211     }
212   }
213 
214 }
Line Stmt Id Pos Tree Symbol Tests Code
47 20414 1866 - 1890 Select scalikejdbc.SQLSyntaxSupportFeature.SQLSyntaxSupport.column org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.column
50 21869 1997 - 2017 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext DefaultPersistentFeatureServiceComponent.this.readExecutionContext
51 20919 2054 - 2320 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToOption[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.eq[String]((DefaultPersistentFeatureService.this.featureAlias.field("id"): scalikejdbc.interpolation.SQLSyntax), featureId.value)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory))).map[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ <synthetic> val eta$0$1: scalikejdbc.ResultName[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply$default$1; ((resultSet: scalikejdbc.WrappedResultSet) => org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply(eta$0$1)(resultSet)) }).single; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) } }); <artifact> val x$8: scalikejdbc.TxBoundary[Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7); qual$1.retryableTx[Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7)(x$8) })(context)
59 20506 2328 - 2375 ApplyToImplicitArgs scala.concurrent.Future.map futurePersistentFeature.map[Option[org.make.core.feature.Feature]](((x$1: Option[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]) => x$1.map[org.make.core.feature.Feature](((x$2: org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) => x$2.toFeature))))(context)
63 19499 2480 - 2500 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext DefaultPersistentFeatureServiceComponent.this.readExecutionContext
64 21210 2571 - 2844 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.eq[org.make.core.feature.FeatureSlug]((DefaultPersistentFeatureService.this.featureAlias.field("slug"): scalikejdbc.interpolation.SQLSyntax), slug)(org.make.api.technical.ScalikeSupport.stringEnumBinders[org.make.core.feature.FeatureSlug]((FeatureSlug: enumeratum.values.StringEnum[org.make.core.feature.FeatureSlug]))))).map[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ <synthetic> val eta$0$1: scalikejdbc.ResultName[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply$default$1; ((resultSet: scalikejdbc.WrappedResultSet) => org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply(eta$0$1)(resultSet)) }).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) } }); <artifact> val x$8: scalikejdbc.TxBoundary[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7); qual$1.retryableTx[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7)(x$8) })(context)
73 20129 2852 - 2900 ApplyToImplicitArgs scala.concurrent.Future.map futurePersistentFeatures.map[List[org.make.core.feature.Feature]](((x$3: List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]) => x$3.map[org.make.core.feature.Feature](((x$4: org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) => x$4.toFeature))))(context)
77 19682 3005 - 3026 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext DefaultPersistentFeatureServiceComponent.this.writeExecutionContext
84 21322 3033 - 3330 ApplyToImplicitArgs scala.concurrent.Future.map scala.concurrent.Future.apply[Boolean]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("WRITE") = "WRITE"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("WRITE", x$2); scalikejdbc.NamedDB.apply("WRITE", x$2)(x$3) }); <artifact> val x$4: scalikejdbc.DBSession => Boolean @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.insert.into(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature).namedValues((DefaultPersistentFeatureService.this.column.field("id"): scalikejdbc.interpolation.SQLSyntax).->[String](feature.featureId.value)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory), (DefaultPersistentFeatureService.this.column.field("slug"): scalikejdbc.interpolation.SQLSyntax).->[org.make.core.feature.FeatureSlug](feature.slug)(org.make.api.technical.ScalikeSupport.stringEnumBinders[org.make.core.feature.FeatureSlug]((FeatureSlug: enumeratum.values.StringEnum[org.make.core.feature.FeatureSlug]))), (DefaultPersistentFeatureService.this.column.field("name"): scalikejdbc.interpolation.SQLSyntax).->[String](feature.name)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory))).execute.apply()(session)); <artifact> val x$5: scalikejdbc.TxBoundary[Boolean] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Boolean](x$4); qual$1.retryableTx[Boolean](x$4)(x$5) })(context).map[org.make.core.feature.Feature](((x$5: Boolean) => feature))(context)
88 20415 3438 - 3459 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext DefaultPersistentFeatureServiceComponent.this.writeExecutionContext
96 21990 3466 - 3845 ApplyToImplicitArgs scala.concurrent.Future.map scala.concurrent.Future.apply[Int]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("WRITE") = "WRITE"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("WRITE", x$2); scalikejdbc.NamedDB.apply("WRITE", x$2)(x$3) }); <artifact> val x$4: scalikejdbc.DBSession => Int @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.update.apply(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature).set((DefaultPersistentFeatureService.this.column.field("slug"): scalikejdbc.interpolation.SQLSyntax).->[org.make.core.feature.FeatureSlug](feature.slug)(org.make.api.technical.ScalikeSupport.stringEnumBinders[org.make.core.feature.FeatureSlug]((FeatureSlug: enumeratum.values.StringEnum[org.make.core.feature.FeatureSlug]))), (DefaultPersistentFeatureService.this.column.field("name"): scalikejdbc.interpolation.SQLSyntax).->[String](feature.name)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory)).where(scalikejdbc.`package`.sqls.eq[String]((DefaultPersistentFeatureService.this.column.field("id"): scalikejdbc.interpolation.SQLSyntax), feature.featureId.value)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory))).executeUpdate.apply()(session)); <artifact> val x$5: scalikejdbc.TxBoundary[Int] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Int](x$4); qual$1.retryableTx[Int](x$4)(x$5) })(ctx).map[Option[org.make.core.feature.Feature]](((x0$1: Int) => x0$1 match { case 1 => scala.Some.apply[org.make.core.feature.Feature](feature) case 0 => scala.None }))(ctx)
103 20993 3950 - 3971 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext org.scalatest.testsuite DefaultPersistentFeatureServiceComponent.this.writeExecutionContext
104 19489 3984 - 3984 ApplyToImplicitArgs cats.instances.FutureInstances.catsStdInstancesForFuture org.scalatest.testsuite cats.implicits.catsStdInstancesForFuture(context)
104 20472 3978 - 4214 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[Int]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("WRITE") = "WRITE"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("WRITE", x$2); scalikejdbc.NamedDB.apply("WRITE", x$2)(x$3) }); <artifact> val x$4: scalikejdbc.DBSession => Int @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.delete.from(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.eq[String]((DefaultPersistentFeatureService.this.featureAlias.field("id"): scalikejdbc.interpolation.SQLSyntax), featureId.value)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory))).update.apply()(session)); <artifact> val x$5: scalikejdbc.TxBoundary[Int] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Int](x$4); qual$1.retryableTx[Int](x$4)(x$5) })(context)
110 21212 3978 - 4219 Select cats.Functor.Ops.void org.scalatest.testsuite cats.implicits.toFunctorOps[scala.concurrent.Future, Int](scala.concurrent.Future.apply[Int]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("WRITE") = "WRITE"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("WRITE", x$2); scalikejdbc.NamedDB.apply("WRITE", x$2)(x$3) }); <artifact> val x$4: scalikejdbc.DBSession => Int @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.delete.from(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.eq[String]((DefaultPersistentFeatureService.this.featureAlias.field("id"): scalikejdbc.interpolation.SQLSyntax), featureId.value)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory))).update.apply()(session)); <artifact> val x$5: scalikejdbc.TxBoundary[Int] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Int](x$4); qual$1.retryableTx[Int](x$4)(x$5) })(context))(cats.implicits.catsStdInstancesForFuture(context)).void
114 20246 4313 - 4333 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext DefaultPersistentFeatureServiceComponent.this.readExecutionContext
115 21782 4404 - 4664 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).orderBy((DefaultPersistentFeatureService.this.featureAlias.field("slug"): scalikejdbc.interpolation.SQLSyntax))).map[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ <synthetic> val eta$0$1: scalikejdbc.ResultName[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply$default$1; ((resultSet: scalikejdbc.WrappedResultSet) => org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply(eta$0$1)(resultSet)) }).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) } }); <artifact> val x$8: scalikejdbc.TxBoundary[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7); qual$1.retryableTx[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7)(x$8) })(context)
124 21327 4672 - 4720 ApplyToImplicitArgs scala.concurrent.Future.map futurePersistentFeatures.map[List[org.make.core.feature.Feature]](((x$6: List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]) => x$6.map[org.make.core.feature.Feature](((x$7: org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) => x$7.toFeature))))(context)
128 20310 4849 - 4869 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext DefaultPersistentFeatureServiceComponent.this.readExecutionContext
129 21995 4940 - 5272 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.in[String]((DefaultPersistentFeatureService.this.featureAlias.field("id"): scalikejdbc.interpolation.SQLSyntax), featureIds.map[String](((x$8: org.make.core.feature.FeatureId) => x$8.value)))(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory)).orderBy((DefaultPersistentFeatureService.this.featureAlias.field("slug"): scalikejdbc.interpolation.SQLSyntax))).map[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ <synthetic> val eta$0$1: scalikejdbc.ResultName[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply$default$1; ((resultSet: scalikejdbc.WrappedResultSet) => org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply(eta$0$1)(resultSet)) }).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) } }); <artifact> val x$8: scalikejdbc.TxBoundary[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7); qual$1.retryableTx[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7)(x$8) })(context)
139 20967 5280 - 5328 ApplyToImplicitArgs scala.concurrent.Future.map futurePersistentFeatures.map[List[org.make.core.feature.Feature]](((x$9: List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]) => x$9.map[org.make.core.feature.Feature](((x$10: org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) => x$10.toFeature))))(context)
149 20475 5580 - 5600 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext org.scalatest.testsuite DefaultPersistentFeatureServiceComponent.this.readExecutionContext
151 19494 5672 - 6141 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ val query: scalikejdbc.PagingSQLBuilder[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = scalikejdbc.`package`.select.from[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature](org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.toAndConditionOpt(maybeSlug.map[scalikejdbc.interpolation.SQLSyntax](((slug: String) => scalikejdbc.`package`.sqls.like((DefaultPersistentFeatureService.this.featureAlias.field("slug"): scalikejdbc.interpolation.SQLSyntax), ("%".+(slug).+("%"): String)))))); org.make.api.technical.PersistentServiceUtils.sortOrderQuery[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature, org.make.core.feature.Feature](offset, end, sort, order, query)(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) }).map[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]({ <synthetic> val eta$0$1: scalikejdbc.ResultName[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature] = org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply$default$1; ((resultSet: scalikejdbc.WrappedResultSet) => org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply(eta$0$1)(resultSet)) }).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) } }); <artifact> val x$8: scalikejdbc.TxBoundary[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7); qual$1.retryableTx[List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]](x$7)(x$8) })(context)
164 21128 6149 - 6197 ApplyToImplicitArgs scala.concurrent.Future.map org.scalatest.testsuite futurePersistentFeatures.map[List[org.make.core.feature.Feature]](((x$11: List[org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature]) => x$11.map[org.make.core.feature.Feature](((x$12: org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature) => x$12.toFeature))))(context)
168 20195 6305 - 6325 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext org.scalatest.testsuite DefaultPersistentFeatureServiceComponent.this.readExecutionContext
170 21788 6333 - 6654 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[Int]({ <artifact> val qual$1: org.make.api.technical.DatabaseTransactions.RichDatabase = org.make.api.technical.DatabaseTransactions.RichDatabase({ <artifact> val x$1: String("READ") = "READ"; <artifact> val x$2: scalikejdbc.SettingsProvider = scalikejdbc.NamedDB.apply$default$2; <artifact> val x$3: scalikejdbc.ConnectionPoolContext = scalikejdbc.NamedDB.apply$default$3("READ", x$2); scalikejdbc.NamedDB.apply("READ", x$2)(x$3) }); <artifact> val x$7: scalikejdbc.DBSession => Int @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToOption[Int,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.apply[Nothing](scalikejdbc.`package`.sqls.count).from(org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.as(DefaultPersistentFeatureService.this.featureAlias)).where(scalikejdbc.`package`.sqls.toAndConditionOpt(maybeSlug.map[scalikejdbc.interpolation.SQLSyntax](((slug: String) => scalikejdbc.`package`.sqls.like((DefaultPersistentFeatureService.this.featureAlias.field("slug"): scalikejdbc.interpolation.SQLSyntax), ("%".+(slug).+("%"): String))))))).map[Int](((x$13: scalikejdbc.WrappedResultSet) => x$13.int(1))).single; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[Int,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[Int,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[Int,scalikejdbc.HasExtractor]]; <artifact> val x$6: scalikejdbc.ConnectionPoolContext = stabilizer$1.apply$default$2(); stabilizer$1.apply()(x$4, x$6, x$5) }.getOrElse[Int](0) }); <artifact> val x$8: scalikejdbc.TxBoundary[Int] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Int](x$7); qual$1.retryableTx[Int](x$7)(x$8) })(context)
186 21230 6863 - 6865 Select org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.id PersistentFeature.this.id
186 20479 6901 - 6905 Select org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.name PersistentFeature.this.name
186 19471 6833 - 6906 Apply org.make.core.feature.Feature.apply org.make.core.feature.Feature.apply(x$1, x$3, x$2)
186 20971 6875 - 6892 Apply org.make.core.technical.enumeratum.FallbackingCirceEnum.apply org.make.core.feature.FeatureSlug.apply(PersistentFeature.this.slug)
186 20312 6853 - 6866 Apply org.make.core.feature.FeatureId.apply org.make.core.feature.FeatureId.apply(PersistentFeature.this.id)
186 21918 6887 - 6891 Select org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.slug PersistentFeature.this.slug
194 21131 7102 - 7127 Apply scala.collection.SeqFactory.Delegate.apply scala.`package`.Seq.apply[String]("id", "slug", "name")
195 20237 7167 - 7181 Literal <nosymbol> "id,slug,name"
197 21747 7220 - 7229 Literal <nosymbol> "feature"
206 21083 7565 - 7763 Apply org.make.api.feature.DefaultPersistentFeatureServiceComponent.PersistentFeature.apply DefaultPersistentFeatureServiceComponent.this.PersistentFeature.apply(resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("id"): scalikejdbc.interpolation.SQLSyntax))), resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("slug"): scalikejdbc.interpolation.SQLSyntax))), resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("name"): scalikejdbc.interpolation.SQLSyntax))))
207 21233 7620 - 7640 ApplyImplicitView scalikejdbc.interpolation.Implicits.scalikejdbcSQLSyntaxToStringImplicitDef scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("id"): scalikejdbc.interpolation.SQLSyntax))
207 20276 7603 - 7641 Apply scalikejdbc.WrappedResultSet.string resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("id"): scalikejdbc.interpolation.SQLSyntax)))
208 21987 7675 - 7697 ApplyImplicitView scalikejdbc.interpolation.Implicits.scalikejdbcSQLSyntaxToStringImplicitDef scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("slug"): scalikejdbc.interpolation.SQLSyntax))
208 20922 7658 - 7698 Apply scalikejdbc.WrappedResultSet.string resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("slug"): scalikejdbc.interpolation.SQLSyntax)))
209 20003 7732 - 7754 ApplyImplicitView scalikejdbc.interpolation.Implicits.scalikejdbcSQLSyntaxToStringImplicitDef scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("name"): scalikejdbc.interpolation.SQLSyntax))
209 19473 7715 - 7755 Apply scalikejdbc.WrappedResultSet.string resultSet.string(scalikejdbc.`package`.scalikejdbcSQLSyntaxToStringImplicitDef((featureResultName.field("name"): scalikejdbc.interpolation.SQLSyntax)))