Skip to content

Commit

Permalink
Add JDBC-object mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
xerial committed Jan 20, 2017
1 parent c896ce6 commit 5ab3486
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
15 changes: 15 additions & 0 deletions wvlet-core/src/main/scala/wvlet/core/tablet/Schema.scala
Expand Up @@ -29,6 +29,21 @@ object Schema {
case class ARRAY(elemType: ColumnType) extends ColumnType
case class MAP(keyType: ColumnType, valueType: ColumnType) extends ColumnType
case class RECORD(column: Seq[Column]) extends ColumnType

object ColumnType {
def unapply(s: String): Option[ColumnType] = {
val tpe = s match {
case "varchar" => STRING
case "string" => STRING
case "bigint" => INTEGER
case "double" => FLOAT
case "float" => FLOAT
case "json" => STRING // TODO jse JSON type
case _ => STRING // TODO support more type
}
Some(tpe)
}
}
}

case class Column(
Expand Down
Expand Up @@ -12,6 +12,7 @@
* limitations under the License.
*/
package wvlet.core.tablet
import org.msgpack.value.{ArrayValue, MapValue}
import wvlet.core.time.TimeStamp


Expand All @@ -35,19 +36,17 @@ object TextTabletReader {

}



override def readLong: Long = ???
// TODO type resolution of array and map elements
override def readArray: Seq[_] = ???
override def readArray: ArrayValue = ???
override def readNull: Unit = ???
override def readTimestamp: TimeStamp = ???
override def readMap: Map[_, _] = ???
override def readMap: MapValue = ???
override def isNull: Boolean = ???
override def readString: String = ???
override def readDouble: Double = ???
override def readBinary: Array[Byte] = ???
override def readJson: String = ???
override def readJson: MapValue = ???

}
}
@@ -0,0 +1,66 @@
package wvlet.core.tablet.jdbc

import java.sql.{Connection, ResultSet}

import wvlet.obj._
import wvlet.log.io.IOUtil._

import scala.reflect.ClassTag

/**
*
*/
object SQLObjectMapper {

import scala.reflect.runtime.{universe => ru}

def sqlTypeOf(tpe: ObjectType): String = {
tpe match {
case Primitive.Int => "integer"
case Primitive.Long => "integer"
case Primitive.Float => "float"
case Primitive.Double => "float"
case Primitive.Boolean => "boolean"
case TextType.String => "string"
case TextType.File => "string"
case TextType.Date => "string"
case _ =>
throw new IllegalArgumentException(s"Unknown type ${tpe}")
}
}

def createTableSQLFor[A: ru.TypeTag](tableName: String): String = {
val schema = ObjectSchema.of[A]
val params = for (p <- schema.parameters) yield {
s"${p.name} ${sqlTypeOf(p.valueType)}"
}
s"create table if not exists ${tableName} (${params.mkString(", ")})"
}

def quote(s: String) = s"'${s}'"

def insertRecord[A: ru.TypeTag](obj: A, tableName: String, conn: Connection) {
val schema = ObjectSchema.of[A]
val colSize = schema.parameters.size
val tuple = ("?" * colSize).mkString(", ")
withResource(conn.prepareStatement(s"insert into ${tableName} values(${tuple})")) {prep =>
for ((p, i) <- schema.parameters.zipWithIndex) yield {
val v = p.get(obj)
prep.setObject(i + 1, v)
}
prep.execute()
}
}

def readAs[A: ClassTag](rs: ResultSet): A = {
val cl = implicitly[ClassTag[A]].runtimeClass
val metadata = rs.getMetaData
val cols = metadata.getColumnCount
val b = ObjectBuilder(cl)
for (i <- 1 to cols) {
val colName = metadata.getColumnName(i)
b.set(colName, rs.getObject(i))
}
b.build.asInstanceOf[A]
}
}

0 comments on commit 5ab3486

Please sign in to comment.