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.keyword
21 
22 import grizzled.slf4j.Logging
23 import org.make.api.extensions.MakeDBExecutionContextComponent
24 import org.make.api.technical.DatabaseTransactions._
25 import org.make.api.technical.ScalikeSupport._
26 import org.make.api.technical.ShortenedNames
27 import org.make.core.technical.Pagination
28 import org.make.core.keyword.Keyword
29 import org.make.core.question.QuestionId
30 import scalikejdbc._
31 
32 import scala.concurrent.Future
33 
34 trait DefaultPersistentKeywordServiceComponent extends PersistentKeywordServiceComponent {
35   this: MakeDBExecutionContextComponent =>
36 
37   override lazy val persistentKeywordService: PersistentKeywordService = new DefaultPersistentKeywordService
38 
39   class DefaultPersistentKeywordService
40       extends PersistentKeywordService
41       with ShortenedNames
42       with SQLSyntaxSupport[Keyword]
43       with Logging {
44     private val keywords = SQLSyntaxSupportFactory[Keyword]()
45     private val kw = keywords.syntax
46 
47     override def get(key: String, questionId: QuestionId): Future[Option[Keyword]] = {
48       implicit val context: EC = readExecutionContext
49       Future(NamedDB("READ").retryableTx { implicit session =>
50         withSQL {
51           select
52             .from(keywords.as(kw))
53             .where
54             .eq(kw.key, key)
55             .and
56             .eq(kw.questionId, questionId)
57             .orderBy(kw.key)
58             .asc
59         }.map(keywords.apply(kw.resultName)).single()
60       })
61     }
62 
63     override def findAll(questionId: QuestionId): Future[Seq[Keyword]] = {
64       implicit val context: EC = readExecutionContext
65       Future(NamedDB("READ").retryableTx { implicit session =>
66         withSQL {
67           select
68             .from(keywords.as(kw))
69             .where(sqls.eq(kw.questionId, questionId))
70             .orderBy(kw.key)
71             .asc
72         }.map(keywords.apply(kw.resultName)).list()
73       })
74     }
75 
76     override def findTop(questionId: QuestionId, limit: Pagination.Limit): Future[Seq[Keyword]] = {
77       implicit val context: EC = readExecutionContext
78       Future(NamedDB("READ").retryableTx { implicit session =>
79         withSQL {
80           select
81             .from(keywords.as(kw))
82             .where
83             .eq(kw.questionId, questionId)
84             .and
85             .eq(kw.topKeyword, true)
86             .orderBy(kw.score)
87             .desc
88             .limit(limit.extractInt)
89         }.map(keywords.apply(kw.resultName)).list()
90       })
91     }
92 
93     def resetTop(questionId: QuestionId): Future[Unit] = {
94       implicit val context: EC = writeExecutionContext
95       Future(NamedDB("WRITE").retryableTx { implicit session =>
96         withSQL {
97           update(keywords)
98             .set(keywords.column.topKeyword -> false)
99             .where
100             .eq(kw.topKeyword, true)
101             .and
102             .eq(kw.questionId, questionId)
103         }.update()
104       })
105     }
106 
107     def createKeywords(questionId: QuestionId, items: Seq[Keyword]): Future[Unit] = {
108       implicit val context: EC = writeExecutionContext
109       Future(NamedDB("WRITE").retryableTx { implicit session =>
110         def values(keyword: Keyword, columns: Seq[SQLSyntax]): Seq[ParameterBinder] = {
111           val namedValues = autoNamedValues(keyword, keywords.column)
112           columns.map(namedValues(_))
113         }
114         items match {
115           case Seq() => true
116           case _ =>
117             val columnsNames: Seq[SQLSyntax] = keywords.column.columns.toSeq
118             withSQL {
119               insert
120                 .into(keywords)
121                 .columns(columnsNames: _*)
122                 .multipleValues(items.map(values(_, columnsNames)): _*)
123             }.execute()
124         }
125       })
126     }
127 
128     def updateTop(questionId: QuestionId, items: Seq[Keyword]): Future[Unit] = {
129       implicit val context: EC = writeExecutionContext
130       Future(NamedDB("WRITE").retryableTx { implicit session =>
131         items.foreach { keyword =>
132           withSQL {
133             update(keywords)
134               .set(autoNamedValues(keyword, keywords.column, "key", "questionId"))
135               .where
136               .eq(kw.key, keyword.key)
137               .and
138               .eq(kw.questionId, keyword.questionId)
139           }.update()
140         }
141       })
142     }
143 
144   }
145 }
Line Stmt Id Pos Tree Symbol Tests Code
45 21058 1678 - 1693 Select scalikejdbc.SQLSyntaxSupportFeature.SQLSyntaxSupport.syntax org.scalatest.testsuite DefaultPersistentKeywordService.this.keywords.syntax
48 20199 1815 - 1835 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext org.scalatest.testsuite DefaultPersistentKeywordServiceComponent.this.readExecutionContext
49 21796 1842 - 2185 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[Option[org.make.core.keyword.Keyword]]({ <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.core.keyword.Keyword] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToOption[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](DefaultPersistentKeywordService.this.keywords.as(DefaultPersistentKeywordService.this.kw)).where.eq[String]((DefaultPersistentKeywordService.this.kw.field("key"): scalikejdbc.interpolation.SQLSyntax), key)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory).and.eq[org.make.core.question.QuestionId]((DefaultPersistentKeywordService.this.kw.field("questionId"): scalikejdbc.interpolation.SQLSyntax), questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders).orderBy((DefaultPersistentKeywordService.this.kw.field("key"): scalikejdbc.interpolation.SQLSyntax)).asc).map[org.make.core.keyword.Keyword](((rs: scalikejdbc.WrappedResultSet) => DefaultPersistentKeywordService.this.keywords.apply(DefaultPersistentKeywordService.this.kw.resultName)(rs))).single; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.core.keyword.Keyword,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.core.keyword.Keyword]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Option[org.make.core.keyword.Keyword]](x$7); qual$1.retryableTx[Option[org.make.core.keyword.Keyword]](x$7)(x$8) })(context)
64 20813 2301 - 2321 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext org.scalatest.testsuite DefaultPersistentKeywordServiceComponent.this.readExecutionContext
65 19886 2328 - 2616 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[List[org.make.core.keyword.Keyword]]({ <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.core.keyword.Keyword] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](DefaultPersistentKeywordService.this.keywords.as(DefaultPersistentKeywordService.this.kw)).where(scalikejdbc.`package`.sqls.eq[org.make.core.question.QuestionId]((DefaultPersistentKeywordService.this.kw.field("questionId"): scalikejdbc.interpolation.SQLSyntax), questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders)).orderBy((DefaultPersistentKeywordService.this.kw.field("key"): scalikejdbc.interpolation.SQLSyntax)).asc).map[org.make.core.keyword.Keyword](((rs: scalikejdbc.WrappedResultSet) => DefaultPersistentKeywordService.this.keywords.apply(DefaultPersistentKeywordService.this.kw.resultName)(rs))).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.core.keyword.Keyword,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.core.keyword.Keyword]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.core.keyword.Keyword]](x$7); qual$1.retryableTx[List[org.make.core.keyword.Keyword]](x$7)(x$8) })(context)
77 21963 2757 - 2777 Select org.make.api.extensions.MakeDBExecutionContextComponent.readExecutionContext DefaultPersistentKeywordServiceComponent.this.readExecutionContext
78 20975 2784 - 3173 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[List[org.make.core.keyword.Keyword]]({ <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.core.keyword.Keyword] @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => { <synthetic> <stable> <artifact> val stabilizer$1: scalikejdbc.SQLToList[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = scalikejdbc.`package`.withSQL.apply[Nothing](scalikejdbc.`package`.select.from[Nothing](DefaultPersistentKeywordService.this.keywords.as(DefaultPersistentKeywordService.this.kw)).where.eq[org.make.core.question.QuestionId]((DefaultPersistentKeywordService.this.kw.field("questionId"): scalikejdbc.interpolation.SQLSyntax), questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders).and.eq[Boolean]((DefaultPersistentKeywordService.this.kw.field("topKeyword"): scalikejdbc.interpolation.SQLSyntax), true)(scalikejdbc.this.ParameterBinderFactory.booleanParameterBinderFactory).orderBy((DefaultPersistentKeywordService.this.kw.field("score"): scalikejdbc.interpolation.SQLSyntax)).desc.limit(limit.extractInt)).map[org.make.core.keyword.Keyword](((rs: scalikejdbc.WrappedResultSet) => DefaultPersistentKeywordService.this.keywords.apply(DefaultPersistentKeywordService.this.kw.resultName)(rs))).list; { <artifact> val x$4: scalikejdbc.DBSession = session; <artifact> val x$5: scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] =:= scalikejdbc.SQL[org.make.core.keyword.Keyword,scalikejdbc.HasExtractor] @scala.reflect.internal.annotations.uncheckedBounds = GeneralizedTypeConstraintsForWithExtractor.this.=:=.tpEquals[scalikejdbc.SQL[org.make.core.keyword.Keyword,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.core.keyword.Keyword]] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[List[org.make.core.keyword.Keyword]](x$7); qual$1.retryableTx[List[org.make.core.keyword.Keyword]](x$7)(x$8) })(context)
94 20058 3273 - 3294 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext DefaultPersistentKeywordServiceComponent.this.writeExecutionContext
95 21634 3301 - 3601 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[Unit]({ { <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(DefaultPersistentKeywordService.this.keywords).set((DefaultPersistentKeywordService.this.keywords.column.field("topKeyword"): scalikejdbc.interpolation.SQLSyntax).->[Boolean](false)(scalikejdbc.this.ParameterBinderFactory.booleanParameterBinderFactory)).where.eq[Boolean]((DefaultPersistentKeywordService.this.kw.field("topKeyword"): scalikejdbc.interpolation.SQLSyntax), true)(scalikejdbc.this.ParameterBinderFactory.booleanParameterBinderFactory).and.eq[org.make.core.question.QuestionId]((DefaultPersistentKeywordService.this.kw.field("questionId"): scalikejdbc.interpolation.SQLSyntax), questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders)).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)
108 21136 3728 - 3749 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext org.scalatest.testsuite DefaultPersistentKeywordServiceComponent.this.writeExecutionContext
109 20201 3756 - 4400 ApplyToImplicitArgs scala.concurrent.Future.apply org.scalatest.testsuite scala.concurrent.Future.apply[Unit]({ { <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) => { def values(keyword: org.make.core.keyword.Keyword, columns: Seq[scalikejdbc.SQLSyntax]): Seq[scalikejdbc.ParameterBinder] = { val namedValues: Map[scalikejdbc.SQLSyntax,scalikejdbc.ParameterBinder] = (scala.collection.immutable.Map.apply[scalikejdbc.interpolation.SQLSyntax, scalikejdbc.ParameterBinder]((DefaultPersistentKeywordService.this.keywords.column.field("questionId"): scalikejdbc.interpolation.SQLSyntax).->[org.make.core.question.QuestionId](keyword.questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders), (DefaultPersistentKeywordService.this.keywords.column.field("key"): scalikejdbc.interpolation.SQLSyntax).->[String](keyword.key)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory), (DefaultPersistentKeywordService.this.keywords.column.field("label"): scalikejdbc.interpolation.SQLSyntax).->[String](keyword.label)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory), (DefaultPersistentKeywordService.this.keywords.column.field("score"): scalikejdbc.interpolation.SQLSyntax).->[Float](keyword.score)(scalikejdbc.this.ParameterBinderFactory.floatParameterBinderFactory), (DefaultPersistentKeywordService.this.keywords.column.field("count"): scalikejdbc.interpolation.SQLSyntax).->[eu.timepit.refined.types.numeric.NonNegInt](keyword.count)(org.make.api.technical.ScalikeSupport.refinedParameterBinderFactory[Int, eu.timepit.refined.numeric.NonNegative, eu.timepit.refined.api.Refined](scalikejdbc.this.ParameterBinderFactory.intParameterBinderFactory, api.this.RefType.refinedRefType)), (DefaultPersistentKeywordService.this.keywords.column.field("topKeyword"): scalikejdbc.interpolation.SQLSyntax).->[Boolean](keyword.topKeyword)(scalikejdbc.this.ParameterBinderFactory.booleanParameterBinderFactory)): Map[scalikejdbc.SQLSyntax,scalikejdbc.ParameterBinder]); columns.map[scalikejdbc.ParameterBinder](((x$1: scalikejdbc.SQLSyntax) => namedValues.apply(x$1))) }; items match { case scala.`package`.Seq.unapplySeq[org.make.core.keyword.Keyword](<unapply-selector>) <unapply> () => true case _ => { val columnsNames: Seq[scalikejdbc.SQLSyntax] = DefaultPersistentKeywordService.this.keywords.column.columns.toSeq; scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.insert.into(DefaultPersistentKeywordService.this.keywords).columns((columnsNames: _*)).multipleValues((items.map[Seq[scalikejdbc.ParameterBinder]](((x$2: org.make.core.keyword.Keyword) => values(x$2, columnsNames))): _*))).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)
129 21799 4522 - 4543 Select org.make.api.extensions.MakeDBExecutionContextComponent.writeExecutionContext DefaultPersistentKeywordServiceComponent.this.writeExecutionContext
130 20772 4550 - 4946 ApplyToImplicitArgs scala.concurrent.Future.apply scala.concurrent.Future.apply[Unit]({ <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 => Unit @scala.reflect.internal.annotations.uncheckedBounds = ((implicit session: scalikejdbc.DBSession) => items.foreach[Int](((keyword: org.make.core.keyword.Keyword) => scalikejdbc.`package`.withSQL.apply[scalikejdbc.UpdateOperation](scalikejdbc.`package`.update.apply(DefaultPersistentKeywordService.this.keywords).set((scala.collection.immutable.Map.apply[scalikejdbc.interpolation.SQLSyntax, scalikejdbc.ParameterBinder]((DefaultPersistentKeywordService.this.keywords.column.field("label"): scalikejdbc.interpolation.SQLSyntax).->[String](keyword.label)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory), (DefaultPersistentKeywordService.this.keywords.column.field("score"): scalikejdbc.interpolation.SQLSyntax).->[Float](keyword.score)(scalikejdbc.this.ParameterBinderFactory.floatParameterBinderFactory), (DefaultPersistentKeywordService.this.keywords.column.field("count"): scalikejdbc.interpolation.SQLSyntax).->[eu.timepit.refined.types.numeric.NonNegInt](keyword.count)(org.make.api.technical.ScalikeSupport.refinedParameterBinderFactory[Int, eu.timepit.refined.numeric.NonNegative, eu.timepit.refined.api.Refined](scalikejdbc.this.ParameterBinderFactory.intParameterBinderFactory, api.this.RefType.refinedRefType)), (DefaultPersistentKeywordService.this.keywords.column.field("topKeyword"): scalikejdbc.interpolation.SQLSyntax).->[Boolean](keyword.topKeyword)(scalikejdbc.this.ParameterBinderFactory.booleanParameterBinderFactory)): Map[scalikejdbc.SQLSyntax,scalikejdbc.ParameterBinder])).where.eq[String]((DefaultPersistentKeywordService.this.kw.field("key"): scalikejdbc.interpolation.SQLSyntax), keyword.key)(scalikejdbc.this.ParameterBinderFactory.stringParameterBinderFactory).and.eq[org.make.core.question.QuestionId]((DefaultPersistentKeywordService.this.kw.field("questionId"): scalikejdbc.interpolation.SQLSyntax), keyword.questionId)(org.make.api.technical.ScalikeSupport.questionIdBinders)).update.apply()(session)))); <artifact> val x$5: scalikejdbc.TxBoundary[Unit] @scala.reflect.internal.annotations.uncheckedBounds = qual$1.retryableTx$default$2[Unit](x$4); qual$1.retryableTx[Unit](x$4)(x$5) })(context)