Skip to content

Commit bb76dca

Browse files
committed
improve query
1 parent 6a1ef56 commit bb76dca

File tree

3 files changed

+64
-32
lines changed

3 files changed

+64
-32
lines changed

src/main/scala/scmindex/core/SCMIndexService.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ object SCMIndexService {
3030
then filterset.libs
3131
else libs.intersect(filterset.libs)
3232
resp <- OptionT.liftF(service.indexer.query(queryString, libsToSolr, params, returns, tags, rows, start))
33-
entriesIO = resp.items
34-
.map { id => service.storage.get(id) }
35-
.sequence
36-
.map {lst => lst.flatMap(_.toList)}
33+
entriesIO = service.storage.get(resp.items).map {lst => lst.flatMap(_.toList)}
3734
entries <- OptionT.liftF(entriesIO)
3835
} yield QueryResult(resp.total, resp.libs, resp.params, resp.returns, resp.tags, entries)
3936
optt.value
@@ -46,7 +43,7 @@ object SCMIndexService {
4643
(using Indexer[T, ID], Storage[S, ID]): IO[Option[SCMIndexEntry]] = {
4744
val e = for {
4845
id <- OptionT(service.indexer.get(lib, name))
49-
entry <- OptionT(service.storage.get(id))
46+
entry <- OptionT(service.storage.get(List(id)).map(lst => lst.get(0).get))
5047
} yield entry
5148
e.value
5249
}

src/main/scala/scmindex/core/Storage.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait Storage[T, ID] {
99

1010
def init(): IO[Unit]
1111
def save(lst: List[SCMIndexEntry]): IO[List[(ID, SCMIndexEntry)]]
12-
def get(id: ID): IO[Option[SCMIndexEntry]]
12+
def get(ids: List[ID]): IO[List[Option[SCMIndexEntry]]]
1313

1414
def saveFiltersets(f: List[Filterset]): IO[Unit]
1515
def getFiltersets(): IO[List[Filterset]]

src/main/scala/scmindex/persistance/SqliteStorage.scala

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.zaxxer.hikari.HikariDataSource
1111
import cats.effect.kernel.Resource
1212
import cats.implicits._
1313
import cats.data.OptionT
14+
import cats.data.NonEmptyList
1415

1516

1617
case class SqliteStorage(datasource: DataSource, transactor: Resource[IO, Transactor[IO]])
@@ -87,22 +88,21 @@ object SqliteStorage {
8788
})
8889
}
8990

90-
def glueIndexEntry(entries: List[(Int, Option[Int], String, Option[String], Option[String], Option[String])], tags: List[(Int, String)], subsigs: List[(Int, String, String)]): Either[Exception, Option[SCMIndexEntry]] = {
91-
val tagsMap = tags.groupMap(e => e._1)(e => e._2)
92-
val subsigsMap = subsigs.groupMap(e => e._1)(e => for {
93-
sigSexpr <- SexprParser.read(e._3)
94-
sig <- SCMIndexEntry.doParseSubsig(e._2, sigSexpr)
95-
} yield sig).mapValues(lst => lst.sequence)
91+
def glueIndexEntry(
92+
entries: List[(Int, Option[Int], String, Option[String], Option[String], Option[String])],
93+
tagsMap: Map[Int, List[String]],
94+
subsigsMap: Map[Int, List[SubSigEntry]]): Either[Exception, Option[SCMIndexEntry]] =
95+
{
9696
def rowToEntrySingle(e: (Int, Option[Int], String, Option[String], Option[String], Option[String])): Either[Exception, SCMIndexEntrySingle] = {
9797
for {
9898
sexprString <- e._5.toRight(Exception("Missing signature"))
9999
name <- e._4.toRight(Exception("Missing name"))
100100
lib = e._3
101101
sigSexpr <- SexprParser.read(sexprString)
102102
sig <- SCMIndexEntry.parseSignature(sigSexpr)
103-
subsigs <- subsigsMap.get(e._1) match {
103+
subsigs = subsigsMap.get(e._1) match {
104104
case Some(e) => e
105-
case None => Right(List())
105+
case None => List()
106106
}
107107
tags = tagsMap.get(e._1) match {
108108
case Some(t) => t
@@ -123,24 +123,59 @@ object SqliteStorage {
123123
}
124124
}
125125

126-
def get(id: Int): IO[Option[SCMIndexEntry]] = {
127-
val statements = for {
128-
entries <- sql"select id, group_id, lib, name, signature, description from index_entry where id = $id or group_id = $id"
129-
.query[(Int, Option[Int], String, Option[String], Option[String], Option[String])]
130-
.to[List]
131-
tags <- sql"select index_entry_id, name from index_entry_tag where index_entry_id = $id or index_entry_id in (select id from index_entry where group_id = $id)"
132-
.query[(Int, String)]
133-
.to[List]
134-
subsigs <- sql"select index_entry_id, name, signature from index_entry_subsignature where index_entry_id = $id or index_entry_id in (select id from index_entry where group_id = $id)"
135-
.query[(Int, String, String)]
136-
.to[List]
137-
} yield glueIndexEntry(entries, tags, subsigs)
138-
t.transactor.use(xa => {
139-
for {
140-
result <- statements.transact(xa)
141-
unwrapped <- IO.fromEither(result)
142-
} yield unwrapped
143-
})
126+
127+
def glueIndexEntries(
128+
ids: List[Int],
129+
entries: List[(Int, Option[Int], String, Option[String], Option[String], Option[String])],
130+
tags: List[(Int, String)],
131+
subsigs: List[(Int, String, String)]): Either[Exception, List[Option[SCMIndexEntry]]] =
132+
{
133+
for {
134+
subsigsMapEntries <- subsigs.map(s => for {
135+
sigSexpr <- SexprParser.read(s._3)
136+
sig <- SCMIndexEntry.doParseSubsig(s._2, sigSexpr)
137+
} yield (s._1, sig)).sequence
138+
subsigsMap = subsigsMapEntries.groupMap(e => e._1)(e => e._2)
139+
tagsMap = tags.groupMap(e => e._1)(e => e._2)
140+
indexEntries <- ids.map(id => {
141+
val relevantEntries = entries.filter(e => {
142+
e._1 == id || e._2.contains(id)
143+
})
144+
glueIndexEntry(relevantEntries, tagsMap, subsigsMap)
145+
}).sequence
146+
} yield indexEntries
147+
}
148+
149+
def get(ids: List[Int]): IO[List[Option[SCMIndexEntry]]] = {
150+
def doGet(ids: NonEmptyList[Int]) = {
151+
val statements = for {
152+
entries <- (fr"select id, group_id, lib, name, signature, description from index_entry where" ++ Fragments.in(fr"id", ids) ++ fr" or " ++ Fragments.in(fr"group_id", ids))
153+
.query[(Int, Option[Int], String, Option[String], Option[String], Option[String])]
154+
.to[List]
155+
tags <- (fr"select index_entry_id, name from index_entry_tag where" ++
156+
Fragments.in(fr"index_entry_id", ids) ++
157+
fr" or index_entry_id in (select id from index_entry where " ++
158+
Fragments.in(fr"group_id", ids) ++ fr")")
159+
.query[(Int, String)]
160+
.to[List]
161+
subsigs <- (fr"select index_entry_id, name, signature from index_entry_subsignature where" ++
162+
Fragments.in(fr"index_entry_id", ids) ++
163+
fr" or index_entry_id in (select id from index_entry where " ++
164+
Fragments.in(fr"group_id", ids) ++ fr")")
165+
.query[(Int, String, String)]
166+
.to[List]
167+
} yield glueIndexEntries(ids.toList, entries, tags, subsigs)
168+
t.transactor.use(xa => {
169+
for {
170+
result <- statements.transact(xa)
171+
unwrapped <- IO.fromEither(result)
172+
} yield unwrapped
173+
})
174+
}
175+
NonEmptyList.fromList(ids) match {
176+
case Some(lst) => doGet(lst)
177+
case None => IO.pure(List())
178+
}
144179
}
145180

146181
def saveFilterset(f: Filterset): ConnectionIO[Unit] = {

0 commit comments

Comments
 (0)