-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fromSchema ARRAY mapping corrected (using Chunk) #159
Conversation
var chunkData = Chunk.empty[DynamicValue] | ||
while (arrayRs.next()) | ||
mapPrimitiveType(arrayRs, 2, metaData.getColumnType(2)).foreach { el => | ||
chunkData = chunkData :+ el | ||
} | ||
Some(DynamicValue.Sequence(chunkData)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be more perf/put less pressure on the GC, you'll probably want to use a mutable data structure and then wrap it in a Chunk:
var chunkData = Chunk.empty[DynamicValue] | |
while (arrayRs.next()) | |
mapPrimitiveType(arrayRs, 2, metaData.getColumnType(2)).foreach { el => | |
chunkData = chunkData :+ el | |
} | |
Some(DynamicValue.Sequence(chunkData)) | |
val data = mutable.ArrayBuffer.empty[DynamicValue] | |
while (arrayRs.next()) { | |
mapPrimitiveType(arrayRs, 2, metaData.getColumnType(2)).foreach { el => | |
data += el | |
} | |
} | |
Some(DynamicValue.Sequence(Chunk.fromArray(data.toArray))) |
@peterlopen To do it with partial functions you need to do somethink like this: private[jdbc] def createDynamicDecoder(schema: Schema[_], meta: ResultSetMetaData): ResultSet => DynamicValue =
resultSet => {
val remapName = createRemapTable(schema)
var columnIndex = 1
var listMap = ListMap.empty[String, DynamicValue]
while (columnIndex <= meta.getColumnCount()) {
val name = remapName(meta.getColumnName(columnIndex))
val sqlType = meta.getColumnType(columnIndex)
val value: DynamicValue =
(mapPrimitiveType(resultSet, columnIndex) orElse mapComplexType(resultSet, columnIndex))
.applyOrElse(
sqlType,
_ =>
throw new SQLException(
s"Unsupported SQL type ${sqlType} when attempting to decode result set from a ZIO Schema ${schema}"
)
)
listMap = listMap.updated(name, value)
columnIndex += 1
}
DynamicValue.Record(TypeId.Structural, listMap)
}
private def mapPrimitiveType(
resultSet: ResultSet,
columnIndex: Int
): PartialFunction[Int, DynamicValue] = {
case SqlTypes.BIGINT =>
val bigInt = resultSet.getBigDecimal(columnIndex).toBigInteger()
DynamicValue.Primitive(bigInt, StandardType.BigIntegerType)
...
case SqlTypes.VARCHAR =>
val string = resultSet.getString(columnIndex)
DynamicValue.Primitive(string, StandardType.StringType)
}
private def mapComplexType(resultSet: ResultSet, columnIndex: Int): PartialFunction[Int, DynamicValue] = {
case SqlTypes.ARRAY =>
val arrayRs = resultSet.getArray(columnIndex).getResultSet
val metaData = arrayRs.getMetaData
val data = mutable.ArrayBuffer.empty[DynamicValue]
val add = mapPrimitiveType(arrayRs, 2) andThen (el => { data += el; () })
while (arrayRs.next())
add.applyOrElse(metaData.getColumnType(2), _ => ())
DynamicValue.Sequence(Chunk.fromArray(data.toArray))
} |
hi @guizmaii , thank you for comments, will look into it. |
val metaData = arrayRs.getMetaData | ||
val data = mutable.ArrayBuffer.empty[DynamicValue] | ||
while (arrayRs.next()) | ||
data += mapPrimitiveType(arrayRs, 2)(metaData.getColumnType(2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, this is unsafe. If mapPrimitiveType
pattern matching doesn't match with the metaData.getColumnType(2)
value, this will throw. Is it what you want?
Your previous version based on Option was safe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, I want sql exception with some info. added applyOrElse there. thanks
hi @guizmaii , thanks for helping me with code.
just |
I don't know, sorry but indeed, as I mentioned here #159 (comment) your current code is unsafe and should probably adopt the way I gave you, using |
@peterlopen Why closing? |
@guizmaii I found two other issues with using arrays with zio-jdbc, so I gave up on this approach.
I do not mind merging it, but without fixing other issues it still be incomplete. |
hi,
I found out original ARRAY mapping was not working, this should fix it. in schema ARRAY should be represented as Chunk.
also mapping for BIT should be more compatible (based on docs, works for postgres).
any suggestion to improve code welcome, wrapping everything in Some is not ideal, could not figure out how to do it using partial function and case statements.
thank you.