From db675dbf8ed4e239bc36d6b228e0094801825b0a Mon Sep 17 00:00:00 2001 From: Magnus Persson <1431685+magnusp@users.noreply.github.com> Date: Sat, 24 Oct 2026 17:20:21 +0200 Subject: [PATCH] refactor(jdbc): extract DeclaredType parsing --- .../magnusp/libsql/jdbc/DeclaredType.java | 68 +++++++++++++++++++ .../libsql/jdbc/LibsqlResultSetMetaData.java | 54 ++------------- 2 files changed, 74 insertions(+), 48 deletions(-) create mode 100644 libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/DeclaredType.java diff --git a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/DeclaredType.java b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/DeclaredType.java new file mode 100644 index 0000000..d31a623 --- /dev/null +++ b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/DeclaredType.java @@ -0,0 +1,68 @@ +package com.github.magnusp.libsql.jdbc; + +import com.github.magnusp.libsql.hrana.codec.Col; + +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class DeclaredType { + + private static final Pattern COLUMN_TYPENAME = Pattern.compile("([^\\(]*)"); + private static final Pattern COLUMN_TYPECAST = + Pattern.compile("cast\\(.*?\\s+as\\s+(.*?)\\s*\\)"); + private static final Pattern COLUMN_PRECISION = Pattern.compile(".*?\\((.*?)\\)"); + + private final String declType; + + private DeclaredType(String declType) { + this.declType = declType; + } + + static DeclaredType of(Col col) { + String declType = col.decltype(); + if (declType == null) { + String name = col.name(); + if (name != null) { + Matcher matcher = COLUMN_TYPECAST.matcher(name); + declType = matcher.find() ? matcher.group(1) : null; + } + } + return new DeclaredType(declType); + } + + boolean isDeclared() { + return declType != null; + } + + String typeName() { + if (declType != null) { + Matcher matcher = COLUMN_TYPENAME.matcher(declType); + matcher.find(); + return matcher.group(1).toUpperCase(Locale.ENGLISH); + } + return "NUMERIC"; + } + + int precision() { + if (declType == null) { + return 0; + } + Matcher matcher = COLUMN_PRECISION.matcher(declType); + return matcher.find() ? Integer.parseInt(matcher.group(1).split(",")[0].trim()) : 0; + } + + int scale() { + if (declType == null) { + return 0; + } + Matcher matcher = COLUMN_PRECISION.matcher(declType); + if (matcher.find()) { + String[] parts = matcher.group(1).split(","); + if (parts.length == 2) { + return Integer.parseInt(parts[1].trim()); + } + } + return 0; + } +} diff --git a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaData.java b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaData.java index f2d0727..42f5f15 100644 --- a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaData.java +++ b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlResultSetMetaData.java @@ -13,16 +13,9 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class LibsqlResultSetMetaData implements ResultSetMetaData { - private static final Pattern COLUMN_TYPENAME = Pattern.compile("([^\\(]*)"); - private static final Pattern COLUMN_TYPECAST = - Pattern.compile("cast\\(.*?\\s+as\\s+(.*?)\\s*\\)"); - private static final Pattern COLUMN_PRECISION = Pattern.compile(".*?\\((.*?)\\)"); - private final List cols; private final List rows; private final String sql; @@ -104,8 +97,9 @@ public int isNullable(int column) throws SQLException { @Override public boolean isSigned(int column) throws SQLException { - if (declType(column) != null) { - return switch (getColumnTypeName(column)) { + DeclaredType declared = DeclaredType.of(getCol(column)); + if (declared.isDeclared()) { + return switch (declared.typeName()) { case "NUMERIC", "INTEGER", "REAL" -> true; default -> false; }; @@ -143,28 +137,12 @@ public String getSchemaName(int column) throws SQLException { @Override public int getPrecision(int column) throws SQLException { - String declType = declType(column); - if (declType == null) { - return 0; - } - Matcher matcher = COLUMN_PRECISION.matcher(declType); - return matcher.find() ? Integer.parseInt(matcher.group(1).split(",")[0].trim()) : 0; + return DeclaredType.of(getCol(column)).precision(); } @Override public int getScale(int column) throws SQLException { - String declType = declType(column); - if (declType == null) { - return 0; - } - Matcher matcher = COLUMN_PRECISION.matcher(declType); - if (matcher.find()) { - String[] parts = matcher.group(1).split(","); - if (parts.length == 2) { - return Integer.parseInt(parts[1].trim()); - } - } - return 0; + return DeclaredType.of(getCol(column)).scale(); } @Override @@ -189,14 +167,7 @@ public int getColumnType(int column) throws SQLException { @Override public String getColumnTypeName(int column) throws SQLException { - getCol(column); - String declType = declType(column); - if (declType != null) { - Matcher matcher = COLUMN_TYPENAME.matcher(declType); - matcher.find(); - return matcher.group(1).toUpperCase(Locale.ENGLISH); - } - return "NUMERIC"; + return DeclaredType.of(getCol(column)).typeName(); } @Override @@ -223,19 +194,6 @@ public String getColumnClassName(int column) throws SQLException { return XerialColumnType.className(runtimeValue(column)); } - private String declType(int column) throws SQLException { - Col col = getCol(column); - String declType = col.decltype(); - if (declType == null) { - String name = col.name(); - if (name != null) { - Matcher matcher = COLUMN_TYPECAST.matcher(name); - declType = matcher.find() ? matcher.group(1) : null; - } - } - return declType; - } - private String columnName(int column) throws SQLException { String name = getCol(column).name(); return name != null ? name.toLowerCase(Locale.ROOT) : "";