@@ -11,6 +11,7 @@ import com.zaxxer.hikari.HikariDataSource
1111import cats .effect .kernel .Resource
1212import cats .implicits ._
1313import cats .data .OptionT
14+ import cats .data .NonEmptyList
1415
1516
1617case 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