こちらの記事を見て「おー」と思ったので、カッとなってこのような Scala のライブラリをつくりました。
こんな感じで使うことができます。H2 がサポートしているものなら任意の SQL 文法を使うことができます。
import scalikejdbc._
import csvquery._
implicit val session = autoCSVSession
val csv = CSV("./sample.csv", Seq("name", "age"))
val count: Long = withCSV(csv) { table =>
sql"select count(*) from $table where age > 20"
.map(_.long(1)).single.apply().get
}
実際にはこのようなクエリになります。このライブラリは csvread をつくるところを巻き取ってくれるというわけです。
select count(*) from csvread('./sample.csv', 'NAME,AGE', 'UTF-8') where age > 20;
また複数の CSV ファイルを読み込んだ csvread 同士を join することができます。
case class Account(name: String, companyName: String, company: Option[Company])
case class Company(name: String, url: String)
val (accountsCsv, companiesCsv) = (
CSV("./accounts.csv", Seq("name", "company_name")),
CSV("./companies.csv", Seq("name", "url"))
)
val accounts: Seq[Account] = withCSV(accountsCsv, companiesCsv) { (a, c) =>
sql"select a.name, a.company_name, c.url from $a a left join $c c on a.company_name = c.name".map { rs =>
new Account(
name = rs.get("name"),
companyName = rs.get("company_name"),
company = rs.stringOpt("url").map(url => Company(rs.get("company_name"), url))
)
}.list.apply()
}
メモリに乗るサイズの関連した複数の CSV を扱う場合などで使いどころがあるかもしれませんね。