├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── README.md
├── build.sbt
├── project
├── build.properties
└── plugins.sbt
└── src
├── main
└── scala
│ └── com
│ └── github
│ └── takezoe
│ └── scala
│ └── jdbc
│ ├── DB.scala
│ ├── IOUtils.scala
│ ├── TypeMapper.scala
│ └── package.scala
└── test
└── scala
└── com
└── github
└── takezoe
└── scala
└── jdbc
└── SqlTemplateSpec.scala
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | test:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v1
12 | - name: Set up JDK 1.8
13 | uses: actions/setup-java@v1
14 | with:
15 | java-version: 1.8
16 | - name: Test with SBT
17 | run: sbt +test
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.class
3 | *.log
4 |
5 | # sbt specific
6 | dist/*
7 | target/
8 | lib_managed/
9 | src_managed/
10 | project/boot/
11 | project/plugins/project/
12 |
13 | # Scala-IDE specific
14 | .scala_dependencies
15 |
16 | # IntelliJ specific
17 | .idea
18 | .idea_modules
19 |
20 | # Metals specific
21 | .metals
22 | .vscode
23 | .bloop
24 | metals.sbt
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # scala-jdbc [](https://github.com/takezoe/scala-jdbc/actions) [](https://index.scala-lang.org/takezoe/scala-jdbc/scala-jdbc)
2 |
3 | Better JDBC wrapper for Scala.
4 |
5 | ```scala
6 | libraryDependencies += "com.github.takezoe" %% "scala-jdbc" % "1.0.5"
7 | ```
8 |
9 | You can use better-jdbc by adding a following import statements:
10 |
11 | ```scala
12 | import com.github.takezoe.scala.jdbc._
13 | ```
14 |
15 | ## Select
16 |
17 | Extract values from `ResultSet`:
18 |
19 | ```scala
20 | val users: Seq[(Int, String)] = DB.autoClose(conn) { db =>
21 | db.select("SELECT * FROM USERS"){ rs =>
22 | (rs.getInt("USER_ID"), rs.getString("USER_NAME"))
23 | }
24 | }
25 | ```
26 |
27 | Retrieve a first record:
28 |
29 | ```scala
30 | val user: Option[(Int, String)] = DB.autoClose(conn) { db =>
31 | db.selectFirst(sql"SELECT * FROM USERS WHERE USER_ID = $userId"){ rs =>
32 | (rs.getInt("USER_ID"), rs.getString("USER_NAME"))
33 | }
34 | }
35 | ```
36 |
37 | Map `ResultSet` to the case class:
38 |
39 | ```scala
40 | case class User(userId: Int, userName: String)
41 |
42 | val users: Seq[User] = DB.autoClose(conn) { db =>
43 | db.select("SELECT USER_ID, USER_NAME FROM USERS", User.apply _)
44 | }
45 | ```
46 |
47 | ## Update
48 |
49 | ```scala
50 | DB.autoClose(conn) { db =>
51 | db.update(sql"INSERT INTO USERS (USER_ID, USER_NAME) VALUES ($userId, $userName)")
52 | }
53 | ```
54 |
55 | ## Transaction
56 |
57 | ```scala
58 | DB.autoClose(conn) { db =>
59 | db.transaction {
60 | db.update(sql"DELETE FROM GROUP WHERE USER_ID = $userId")
61 | db.update(sql"DELETE FROM USERS WHERE USER_ID = $userId")
62 | }
63 | }
64 | ```
65 |
66 | ## Large data
67 |
68 | Process large data using `scan` method:
69 |
70 | ```scala
71 | DB.autoClose(conn) { db =>
72 | db.scan("SELECT * FROM USERS"){ rs =>
73 | println(rs.getString("USER_NAME"))
74 | }
75 | }
76 | ```
77 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | name := "scala-jdbc"
2 |
3 | organization := "com.github.takezoe"
4 |
5 | version := "1.0.6"
6 |
7 | scalaVersion := "2.13.8"
8 |
9 | crossScalaVersions := Seq("2.11.12", "2.12.16", "2.13.8", "3.2.0")
10 |
11 | libraryDependencies ++= Seq(
12 | "org.scalatest" %% "scalatest" % "3.2.13" % "test",
13 | "com.h2database" % "h2" % "1.4.192" % "test"
14 | )
15 |
16 | publishMavenStyle := true
17 |
18 | publishTo := {
19 | val nexus = "https://oss.sonatype.org/"
20 | if (version.value.trim.endsWith("SNAPSHOT"))
21 | Some("snapshots" at nexus + "content/repositories/snapshots")
22 | else
23 | Some("releases" at nexus + "service/local/staging/deploy/maven2")
24 | }
25 |
26 | scalacOptions := Seq("-deprecation", "-feature")
27 |
28 | //unmanagedClasspath in Compile += baseDirectory.value / "src" / "main" / "resources"
29 |
30 | Test / publishArtifact := false
31 |
32 | pomIncludeRepository := { _ => false }
33 |
34 | pomExtra := (
35 | https://github.com/takezoe/scala-jdbc
36 |
37 |
38 | The Apache Software License, Version 2.0
39 | http://www.apache.org/licenses/LICENSE-2.0.txt
40 |
41 |
42 |
43 | https://github.com/takezoe/scala-jdbc
44 | scm:git:https://github.com/takezoe/scala-jdbc.git
45 |
46 |
47 |
48 | takezoe
49 | Naoki Takezoe
50 | takezoe_at_gmail.com
51 | +9
52 |
53 |
54 | )
55 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version = 1.7.1
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | logLevel := Level.Warn
2 |
3 | addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")
4 |
--------------------------------------------------------------------------------
/src/main/scala/com/github/takezoe/scala/jdbc/DB.scala:
--------------------------------------------------------------------------------
1 | package com.github.takezoe.scala.jdbc
2 |
3 | import java.sql._
4 | import scala.reflect.ClassTag
5 | import IOUtils._
6 |
7 | object DB {
8 |
9 | def apply(conn: Connection)(implicit typeMapper: TypeMapper = new TypeMapper()) =
10 | new DB(conn, typeMapper)
11 |
12 | def autoClose[T](conn: Connection)(f: DB => T)(implicit typeMapper: TypeMapper = new TypeMapper()) =
13 | apply(conn).autoClose(f)
14 |
15 | }
16 |
17 | class DB(conn: Connection, typeMapper: TypeMapper){
18 |
19 | def update(template: SqlTemplate): Int = {
20 | execute(conn, template){ stmt =>
21 | stmt.executeUpdate()
22 | }
23 | }
24 |
25 | def selectFirst[T](template: SqlTemplate)(f: ResultSet => T): Option[T] = {
26 | execute(conn, template){ stmt =>
27 | using(stmt.executeQuery()){ rs =>
28 | if(rs.next){
29 | Some(f(rs))
30 | } else {
31 | None
32 | }
33 | }
34 | }
35 | }
36 |
37 | def selectFirst[P1, T](template: SqlTemplate, f: (P1) => T)(implicit c1: ClassTag[P1]): Option[T] =
38 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1)))
39 |
40 | def selectFirst[P1, P2, T](template: SqlTemplate, f: (P1, P2) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2]): Option[T] =
41 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2)))
42 |
43 | def selectFirst[P1, P2, P3, T](template: SqlTemplate, f: (P1, P2, P3) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3]): Option[T] =
44 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3)))
45 |
46 | def selectFirst[P1, P2, P3, P4, T](template: SqlTemplate, f: (P1, P2, P3, P4) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4]): Option[T] =
47 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4)))
48 |
49 | def selectFirst[P1, P2, P3, P4, P5, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5]): Option[T] =
50 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5)))
51 |
52 | def selectFirst[P1, P2, P3, P4, P5, P6, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6]): Option[T] =
53 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6)))
54 |
55 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7]): Option[T] =
56 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7)))
57 |
58 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8]): Option[T] =
59 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8)))
60 |
61 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9]): Option[T] =
62 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9)))
63 |
64 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10]): Option[T] =
65 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10)))
66 |
67 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11]): Option[T] =
68 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11)))
69 |
70 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12]): Option[T] =
71 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12)))
72 |
73 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13]): Option[T] =
74 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13)))
75 |
76 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14]): Option[T] =
77 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14)))
78 |
79 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15]): Option[T] =
80 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15)))
81 |
82 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16]): Option[T] =
83 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16)))
84 |
85 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17]): Option[T] =
86 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17)))
87 |
88 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18]): Option[T] =
89 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18)))
90 |
91 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19]): Option[T] =
92 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19)))
93 |
94 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20]): Option[T] =
95 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20)))
96 |
97 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21]): Option[T] =
98 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21)))
99 |
100 | def selectFirst[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21], c22: ClassTag[P22]): Option[T] =
101 | selectFirst(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21), typeMapper.get[P22](rs, 22)))
102 |
103 | def select[T](template: SqlTemplate)(f: ResultSet => T): Seq[T] = {
104 | execute(conn, template){ stmt =>
105 | using(stmt.executeQuery()){ rs =>
106 | val list = new scala.collection.mutable.ListBuffer[T]
107 | while(rs.next){
108 | list += f(rs)
109 | }
110 | list.toSeq
111 | }
112 | }
113 | }
114 |
115 | def select[P1, T](template: SqlTemplate, f: (P1) => T)(implicit c1: ClassTag[P1]): Seq[T] =
116 | select(template)(rs => f(typeMapper.get[P1](rs, 1)))
117 |
118 | def select[P1, P2, T](template: SqlTemplate, f: (P1, P2) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2]): Seq[T] =
119 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2)))
120 |
121 | def select[P1, P2, P3, T](template: SqlTemplate, f: (P1, P2, P3) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3]): Seq[T] =
122 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3)))
123 |
124 | def select[P1, P2, P3, P4, T](template: SqlTemplate, f: (P1, P2, P3, P4) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4]): Seq[T] =
125 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4)))
126 |
127 | def select[P1, P2, P3, P4, P5, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5]): Seq[T] =
128 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5)))
129 |
130 | def select[P1, P2, P3, P4, P5, P6, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6]): Seq[T] =
131 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6)))
132 |
133 | def select[P1, P2, P3, P4, P5, P6, P7, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7]): Seq[T] =
134 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7)))
135 |
136 | def select[P1, P2, P3, P4, P5, P6, P7, P8, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8]): Seq[T] =
137 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8)))
138 |
139 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9]): Seq[T] =
140 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9)))
141 |
142 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10]): Seq[T] =
143 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10)))
144 |
145 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11]): Seq[T] =
146 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11)))
147 |
148 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12]): Seq[T] =
149 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12)))
150 |
151 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13]): Seq[T] =
152 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13)))
153 |
154 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14]): Seq[T] =
155 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14)))
156 |
157 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15]): Seq[T] =
158 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15)))
159 |
160 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16]): Seq[T] =
161 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16)))
162 |
163 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17]): Seq[T] =
164 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17)))
165 |
166 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18]): Seq[T] =
167 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18)))
168 |
169 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19]): Seq[T] =
170 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19)))
171 |
172 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20]): Seq[T] =
173 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20)))
174 |
175 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21]): Seq[T] =
176 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21)))
177 |
178 | def select[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) => T)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21], c22: ClassTag[P22]): Seq[T] =
179 | select(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21), typeMapper.get[P22](rs, 22)))
180 |
181 | def selectInt(template: SqlTemplate): Option[Int] = {
182 | selectFirst(template)(_.getInt(1))
183 | }
184 |
185 | def selectString(template: SqlTemplate): Option[String] = {
186 | selectFirst(template)(_.getString(1))
187 | }
188 |
189 | def scan[T](template: SqlTemplate)(f: ResultSet => Unit): Unit = {
190 | execute(conn, template){ stmt =>
191 | using(stmt.executeQuery()){ rs =>
192 | while(rs.next){
193 | f(rs)
194 | }
195 | }
196 | }
197 | }
198 |
199 | def scan[P1, T](template: SqlTemplate, f: (P1) => Unit)(implicit c1: ClassTag[P1]): Unit =
200 | scan(template)(rs => f(typeMapper.get[P1](rs, 1)))
201 |
202 | def scan[P1, P2, T](template: SqlTemplate, f: (P1, P2) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2]): Unit =
203 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2)))
204 |
205 | def scan[P1, P2, P3, T](template: SqlTemplate, f: (P1, P2, P3) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3]): Unit =
206 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3)))
207 |
208 | def scan[P1, P2, P3, P4, T](template: SqlTemplate, f: (P1, P2, P3, P4) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4]): Unit =
209 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4)))
210 |
211 | def scan[P1, P2, P3, P4, P5, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5]): Unit =
212 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5)))
213 |
214 | def scan[P1, P2, P3, P4, P5, P6, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6]): Unit =
215 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6)))
216 |
217 | def scan[P1, P2, P3, P4, P5, P6, P7, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7]): Unit =
218 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7)))
219 |
220 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8]): Unit =
221 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8)))
222 |
223 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9]): Unit =
224 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9)))
225 |
226 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10]): Unit =
227 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10)))
228 |
229 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11]): Unit =
230 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11)))
231 |
232 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12]): Unit =
233 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12)))
234 |
235 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13]): Unit =
236 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13)))
237 |
238 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14]): Unit =
239 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14)))
240 |
241 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15]): Unit =
242 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15)))
243 |
244 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16]): Unit =
245 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16)))
246 |
247 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17]): Unit =
248 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17)))
249 |
250 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18]): Unit =
251 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18)))
252 |
253 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19]): Unit =
254 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19)))
255 |
256 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20]): Unit =
257 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20)))
258 |
259 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21]): Unit =
260 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21)))
261 |
262 | def scan[P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, T](template: SqlTemplate, f: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) => Unit)(implicit c1: ClassTag[P1], c2: ClassTag[P2], c3: ClassTag[P3], c4: ClassTag[P4], c5: ClassTag[P5], c6: ClassTag[P6], c7: ClassTag[P7], c8: ClassTag[P8], c9: ClassTag[P9], c10: ClassTag[P10], c11: ClassTag[P11], c12: ClassTag[P12], c13: ClassTag[P13], c14: ClassTag[P14], c15: ClassTag[P15], c16: ClassTag[P16], c17: ClassTag[P17], c18: ClassTag[P18], c19: ClassTag[P19], c20: ClassTag[P20], c21: ClassTag[P21], c22: ClassTag[P22]): Unit =
263 | scan(template)(rs => f(typeMapper.get[P1](rs, 1), typeMapper.get[P2](rs, 2), typeMapper.get[P3](rs, 3), typeMapper.get[P4](rs, 4), typeMapper.get[P5](rs, 5), typeMapper.get[P6](rs, 6), typeMapper.get[P7](rs, 7), typeMapper.get[P8](rs, 8), typeMapper.get[P9](rs, 9), typeMapper.get[P10](rs, 10), typeMapper.get[P11](rs, 11), typeMapper.get[P12](rs, 12), typeMapper.get[P13](rs, 13), typeMapper.get[P14](rs, 14), typeMapper.get[P15](rs, 15), typeMapper.get[P16](rs, 16), typeMapper.get[P17](rs, 17), typeMapper.get[P18](rs, 18), typeMapper.get[P19](rs, 19), typeMapper.get[P20](rs, 20), typeMapper.get[P21](rs, 21), typeMapper.get[P22](rs, 22)))
264 |
265 | def autoClose[T](f: DB => T): T = {
266 | try {
267 | f(this)
268 | } finally {
269 | close()
270 | }
271 | }
272 |
273 | def transaction[T](f: => T): T = {
274 | conn.setAutoCommit(false)
275 | try {
276 | val r = f
277 | conn.commit()
278 | r
279 | } catch {
280 | case e: Throwable =>
281 | rollbackQuietly(conn)
282 | throw e
283 | }
284 | }
285 |
286 | def close(): Unit = conn.close()
287 |
288 | protected def execute[T](conn: Connection, template: SqlTemplate)(f: (PreparedStatement) => T): T = {
289 | using(conn.prepareStatement(template.sql)){ stmt =>
290 | template.params.zipWithIndex.foreach { case (x, i) =>
291 | typeMapper.set(stmt, i + 1, x)
292 | }
293 | f(stmt)
294 | }
295 | }
296 |
297 | }
298 |
--------------------------------------------------------------------------------
/src/main/scala/com/github/takezoe/scala/jdbc/IOUtils.scala:
--------------------------------------------------------------------------------
1 | package com.github.takezoe.scala.jdbc
2 |
3 | import java.io.{ByteArrayOutputStream, InputStream}
4 | import java.sql.Connection
5 |
6 | object IOUtils {
7 |
8 | def closeQuietly(closeable: AutoCloseable): Unit = {
9 | if(closeable != null){
10 | try {
11 | closeable.close()
12 | } catch {
13 | case e: Exception => // Ignore
14 | }
15 | }
16 | }
17 |
18 | def rollbackQuietly(conn: Connection): Unit = {
19 | try {
20 | conn.rollback()
21 | } catch {
22 | case e: Exception => e.printStackTrace()
23 | }
24 | }
25 |
26 | def using[T <: AutoCloseable, R](closeable: T)(f: T => R): R = {
27 | try {
28 | f(closeable)
29 | } finally {
30 | closeQuietly(closeable)
31 | }
32 | }
33 |
34 | def readStreamAsString(in: InputStream): String = {
35 | val buf = new Array[Byte](1024 * 8)
36 | var length = 0
37 | using(new ByteArrayOutputStream()) { out =>
38 | while ({ length = in.read(buf); length } != -1) {
39 | out.write(buf, 0, length)
40 | }
41 | new String(out.toByteArray, "UTF-8")
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/scala/com/github/takezoe/scala/jdbc/TypeMapper.scala:
--------------------------------------------------------------------------------
1 | package com.github.takezoe.scala.jdbc
2 |
3 | import java.sql._
4 | import scala.reflect.ClassTag
5 |
6 | class TypeMapper {
7 |
8 | def set(stmt: PreparedStatement, index: Int, value: Any): Unit = {
9 | value match {
10 | case x: Int => stmt.setInt(index, x)
11 | case x: Long => stmt.setLong(index, x)
12 | case x: Double => stmt.setDouble(index, x)
13 | case x: Short => stmt.setShort(index, x)
14 | case x: Float => stmt.setFloat(index, x)
15 | case x: Timestamp => stmt.setTimestamp(index, x)
16 | case x: Date => stmt.setDate(index, x)
17 | case x: Time => stmt.setTime(index, x)
18 | case x: String => stmt.setString(index, x)
19 | case _ => throw new UnsupportedOperationException(s"Unsupported type: ${value.getClass.getName}")
20 | }
21 | }
22 |
23 | def get[T](rs: ResultSet, index: Int)(implicit m: ClassTag[T]): T = {
24 | val c = m.runtimeClass
25 | (if(c.isAssignableFrom(classOf[Int])) {
26 | rs.getInt(index)
27 | } else if(c.isAssignableFrom(classOf[Long])) {
28 | rs.getLong(index)
29 | } else if(c.isAssignableFrom(classOf[Double])) {
30 | rs.getDouble(index)
31 | } else if(c.isAssignableFrom(classOf[Float])) {
32 | rs.getFloat(index)
33 | } else if(c.isAssignableFrom(classOf[Short])) {
34 | rs.getShort(index)
35 | } else if(c.isAssignableFrom(classOf[Timestamp])) {
36 | rs.getTimestamp(index)
37 | } else if(c.isAssignableFrom(classOf[Date])) {
38 | rs.getDate(index)
39 | } else if(c.isAssignableFrom(classOf[Time])) {
40 | rs.getTime(index)
41 | } else if(c.isAssignableFrom(classOf[String])){
42 | rs.getString(index)
43 | } else {
44 | throw new UnsupportedOperationException(s"Unsupported type: ${c.getName}")
45 | }).asInstanceOf[T]
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/src/main/scala/com/github/takezoe/scala/jdbc/package.scala:
--------------------------------------------------------------------------------
1 | package com.github.takezoe.scala
2 |
3 | import com.github.takezoe.scala.jdbc.SqlTemplate
4 |
5 | import scala.language.implicitConversions
6 |
7 | package object jdbc {
8 |
9 | /**
10 | * Implicit conversion to convert a raw string with no parameter to SqlTemplate
11 | */
12 | implicit def String2SqlTemplate(sql: String): SqlTemplate = SqlTemplate(sql)
13 |
14 | /**
15 | * String interpolation to convert a variable-embedded SQL to SqlTemplate
16 | */
17 | implicit class SqlStringInterpolation(val sc: StringContext) extends AnyVal {
18 | def sql(args: Any*): SqlTemplate = {
19 | val sql = sc.parts.mkString("?")
20 | SqlTemplate(sql, args:_*)
21 | }
22 | }
23 |
24 | case class SqlTemplate(sql: String, params: Any*)
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/scala/com/github/takezoe/scala/jdbc/SqlTemplateSpec.scala:
--------------------------------------------------------------------------------
1 | package com.github.takezoe.scala.jdbc
2 |
3 | import java.sql.DriverManager
4 |
5 | import org.scalatest.funsuite.AnyFunSuite
6 |
7 | class SqlTemplateSpec extends AnyFunSuite {
8 |
9 | test("set parameters"){
10 | val a = Article(0, System.currentTimeMillis, "takezoe", "Database access in Scala")
11 | Class.forName("org.h2.Driver")
12 | DB.autoClose(DriverManager.getConnection("jdbc:h2:mem:test;TRACE_LEVEL_FILE=4")) { db =>
13 | db.update(sql"""CREATE TABLE articles (
14 | id serial PRIMARY KEY,
15 | published bigint NOT NULL,
16 | author varchar (50) NOT NULL,
17 | title varchar (100) NOT NULL
18 | )""")
19 |
20 | db.update(sql"INSERT INTO articles (published,author,title) VALUES (${a.published},${a.author},${a.title})")
21 |
22 | val aricles = db.select("SELECT * FROM articles", Article.apply _)
23 | assert(aricles.size == 1)
24 | }
25 | }
26 |
27 | }
28 |
29 | case class Article(id: Long, published: Long, author: String, title: String)
--------------------------------------------------------------------------------