java.sql.ResultSetMetaData Scala Examples

The following examples show how to use java.sql.ResultSetMetaData. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: JdbcSchemaFns.scala    From eel-sdk   with Apache License 2.0 5 votes vote down vote up
package io.eels.component.jdbc

import java.sql.{ResultSet, ResultSetMetaData}

import com.sksamuel.exts.Logging
import io.eels.component.jdbc.dialect.JdbcDialect
import io.eels.schema.{Field, StructType}


object JdbcSchemaFns extends Logging {

  def fromJdbcResultset(rs: ResultSet, dialect: JdbcDialect): StructType = {

    val md = rs.getMetaData
    val columnCount = md.getColumnCount
    logger.trace(s"Resultset column count is $columnCount")

    val cols = (1 to columnCount).map { k =>
      Field(
          name = md.getColumnLabel(k),
          dataType = dialect.fromJdbcType(k, md),
          nullable = md.isNullable(k) == ResultSetMetaData.columnNullable
      )
    }

    StructType(cols.toList)
  }
} 
Example 2
Source File: OracleJdbcDialect.scala    From eel-sdk   with Apache License 2.0 5 votes vote down vote up
package io.eels.component.jdbc.dialect

import java.sql.{ResultSetMetaData, Types}

import com.sksamuel.exts.Logging
import io.eels.component.jdbc.JdbcReaderConfig
import io.eels.schema.{BooleanType, ByteType, DataType, DecimalType, DoubleType, Field, FloatType, IntType, LongType, Precision, Scale, ShortType}

class OracleJdbcDialect extends GenericJdbcDialect with Logging {

  private val config = JdbcReaderConfig()

  // oracle uses its own timestamp types
  override def sanitize(value: Any): Any = {
    if (value == null) null
    else value match {
      case other if other.getClass.getName == "oracle.sql.TIMESTAMP" =>
        value.getClass.getDeclaredMethod("timestampValue").invoke(value)
      case other => super.sanitize(other)
    }
  }

  override def toJdbcType(field: Field): String = field.dataType match {
    // https://docs.oracle.com/cd/E19501-01/819-3659/gcmaz/
    case BooleanType => "NUMBER(1)"
    case IntType(_) => "NUMBER(10)"
    case LongType(_) => "NUMBER(19)"
    case FloatType => "NUMBER(19, 4)"
    case DoubleType => "NUMBER(19, 4)"
    case ByteType(_) => "NUMBER(3)"
    case ShortType(_) => "NUMBER(5)"
    case _ => super.toJdbcType(field)
  }

  private def decimalType(column: Int, metadata: ResultSetMetaData): DataType = {
    val precision = metadata.getPrecision(column)
    val scale = metadata.getScale(column)
    require(scale <= precision, "Scale must be less than precision")

    (precision, scale) match {
      // Jdbc returns precision == 0 and scale == -127 for NUMBER fields which have no precision/scale
      // http://stackoverflow.com/questions/593197/what-is-the-default-precision-and-scale-for-a-number-in-oracle
      case (0, _) => DecimalType(config.defaultPrecision, config.defaultScale)
      case (_, -127L) => DecimalType(config.defaultPrecision, config.defaultScale)
      case (x, 0) if x > 9 => LongType.Signed
      case (_, 0) => IntType.Signed
      case (_, _) => DecimalType(Precision(precision), Scale(scale))
    }
  }

  override def fromJdbcType(column: Int, metadata: ResultSetMetaData): DataType = {
    metadata.getColumnType(column) match {
      case Types.DECIMAL | Types.NUMERIC => decimalType(column, metadata)
      case _ => super.fromJdbcType(column, metadata)
    }
  }
} 
Example 3
Source File: DataServiceTest.scala    From kafka-jdbc-connector   with Apache License 2.0 5 votes vote down vote up
package com.agoda.kafka.connector.jdbc.services

import java.sql.{Connection, PreparedStatement, ResultSet, ResultSetMetaData}

import com.agoda.kafka.connector.jdbc.utils.DataConverter
import org.apache.kafka.connect.data.Schema
import org.apache.kafka.connect.source.SourceRecord
import org.scalatest.mockito.MockitoSugar
import org.mockito.Mockito._
import org.scalatest.{Matchers, WordSpec}

import scala.concurrent.duration._
import scala.util.Success

class DataServiceTest extends WordSpec with Matchers with MockitoSugar {

  "Data Service" should {

    val spName = "stored-procedure"
    val connection = mock[Connection]
    val converter = mock[DataConverter]
    val sourceRecord1 = mock[SourceRecord]
    val sourceRecord2 = mock[SourceRecord]
    val resultSet = mock[ResultSet]
    val resultSetMetadata = mock[ResultSetMetaData]
    val preparedStatement = mock[PreparedStatement]
    val schema = mock[Schema]

    val dataService = new DataService {

      override def storedProcedureName: String = spName

      override protected def createPreparedStatement(connection: Connection) = Success(preparedStatement)

      override protected def extractRecords(resultSet: ResultSet, schema: Schema) = Success(Seq(sourceRecord1, sourceRecord2))

      override def dataConverter: DataConverter = converter
    }

    "get records" in {
      doNothing().when(preparedStatement).setQueryTimeout(1)
      when(preparedStatement.executeQuery).thenReturn(resultSet)
      when(resultSet.getMetaData).thenReturn(resultSetMetadata)
      when(converter.convertSchema(spName, resultSetMetadata)).thenReturn(Success(schema))

      dataService.getRecords(connection, 1.second) shouldBe Success(Seq(sourceRecord1, sourceRecord2))

      verify(preparedStatement).setQueryTimeout(1)
      verify(preparedStatement).executeQuery
      verify(resultSet).getMetaData
      verify(converter).convertSchema(spName, resultSetMetadata)
    }
  }
} 
Example 4
Source File: KsqlResultSetMetaData.scala    From ksql-jdbc-driver   with Apache License 2.0 5 votes vote down vote up
package com.github.mmolimar.ksql.jdbc.resultset

import java.sql.{ResultSetMetaData, Types}

import com.github.mmolimar.ksql.jdbc.Exceptions._
import com.github.mmolimar.ksql.jdbc.implicits.toIndexedMap
import com.github.mmolimar.ksql.jdbc.{HeaderField, InvalidColumn}
import io.confluent.ksql.schema.ksql.{SqlBaseType => KsqlType}


class KsqlResultSetMetaData(private[jdbc] val columns: List[HeaderField]) extends ResultSetMetaDataNotSupported {

  private val fieldByIndex: Map[Int, HeaderField] = columns

  private def getField(index: Int): HeaderField = fieldByIndex.getOrElse(index,
    throw InvalidColumn(s"Column with index '$index' does not exist."))

  override def getColumnClassName(column: Int): String = {
    getField(column).jdbcType match {
      case Types.INTEGER => classOf[java.lang.Integer]
      case Types.BIGINT => classOf[java.lang.Long]
      case Types.DOUBLE => classOf[java.lang.Double]
      case Types.DECIMAL => classOf[java.math.BigDecimal]
      case Types.BOOLEAN => classOf[java.lang.Boolean]
      case Types.VARCHAR => classOf[java.lang.String]
      case Types.JAVA_OBJECT => classOf[java.util.Map[AnyRef, AnyRef]]
      case Types.ARRAY => classOf[java.sql.Array]
      case Types.STRUCT => classOf[java.sql.Struct]
      case _ => classOf[java.lang.String]
    }
  }.getName

  override def getColumnCount: Int = columns.size

  override def getColumnDisplaySize(column: Int): Int = getField(column).length

  override def getColumnLabel(column: Int): String = getField(column).label

  override def getColumnName(column: Int): String = getField(column).name

  override def getColumnTypeName(column: Int): String = {
    getField(column).jdbcType match {
      case Types.INTEGER => KsqlType.INTEGER
      case Types.BIGINT => KsqlType.BIGINT
      case Types.DOUBLE => KsqlType.DOUBLE
      case Types.DECIMAL => KsqlType.DECIMAL
      case Types.BOOLEAN => KsqlType.BOOLEAN
      case Types.VARCHAR => KsqlType.STRING
      case Types.JAVA_OBJECT => KsqlType.MAP
      case Types.ARRAY => KsqlType.ARRAY
      case Types.STRUCT => KsqlType.STRUCT
      case _ => KsqlType.STRING
    }
  }.name

  override def getColumnType(column: Int): Int = getField(column).jdbcType

  override def getPrecision(column: Int): Int = getField(column).jdbcType match {
    case Types.DOUBLE => -1
    case _ => 0
  }

  override def getScale(column: Int): Int = getField(column).jdbcType match {
    case Types.DOUBLE => -1
    case _ => 0
  }

  override def isCaseSensitive(column: Int): Boolean = getField(column).jdbcType match {
    case Types.VARCHAR => true
    case _ => false
  }

  override def isNullable(column: Int): Int = ResultSetMetaData.columnNullableUnknown

  override def isAutoIncrement(column: Int): Boolean = false

  override def isCurrency(column: Int): Boolean = false

  override def isSearchable(column: Int): Boolean = true

  override def isReadOnly(column: Int): Boolean = false

  override def isWritable(column: Int): Boolean = !isReadOnly(column)

  override def isDefinitelyWritable(column: Int): Boolean = isWritable(column)

  override def isSigned(column: Int): Boolean = getField(column).jdbcType match {
    case Types.TINYINT | Types.SMALLINT | Types.INTEGER |
         Types.BIGINT | Types.FLOAT | Types.DOUBLE | Types.DECIMAL => true
    case _ => false
  }

}