Skip to content

Refactor libsql-jdbc into focused units #194

Closed
21 of 21 issues completed
Closed

Description

@magnusp

Goal

Turn the four god-classes in libsql-jdbc into focused units without changing a single observable behavior. The driver is a drop-in replacement for xerial sqlite-jdbc 3.53.4.0, so quirks, messages, SQL text, and exception types are the contract. Only structure moves.

Reader load is the success measure. About 1,300 lines leave the four largest files, and each pass must make one part of the code easier to trace. A pass that does not lower reader load gets reverted.

Why now

LibsqlResultSet is 1498 lines, LibsqlDatabaseMetaData 1057, SqlTableReference 998, LibsqlResultSetMetaData 680. Each mixes a JDBC surface with an algorithm that belongs in its own file. The baseline is green. ./mvnw -pl libsql-jdbc -am test ran 374 tests with 0 failures at 404bba6, and the selected xerial conformance suite is green at the same head (#193).

The rule

One pass is one PR. Each pass pins behavior, moves code, and proves the pin still holds. No pass adds behavior, and no pass edits an existing assertion. A pass that finds a bug splits it out and ships the structural change first.

Passes that touch the same file run in order, not in parallel. The blocked-by links below encode that.

Map

Pass Moves out Target
#1 real text SQLite %!.17g formatter from LibsqlResultSet 1498 → under 1250
#2 LOBs LibsqlBlob, LibsqlClob under 1050
#3 numeric text SqliteNumericText, duplicate getter ladders under 950
#4 date and time SqliteDateTimeValues under 850
#5 autoincrement SqlAutoIncrement 680 → under 580
#6 column type XerialColumnType under 480
#7 declared type DeclaredType under 430
#8 table resolver TableMetadataResolver under 300
#9 SQL parser SqlCursor, FromClauseParser, SelectItemParser, TableBinding 998 → under 450
#10 metadata SQL MetadataSql 1057 → under 950
#11 columns shaper named row records under 900
#12 foreign keys ForeignKeyMetadata under 800
connection cleanup one send path, one update-count path 763 → under 750
#13 savepoints named state transitions 763 → under 740
#14 statement results one attachment path, closeDetached 702 → under 650
#15 parameter metadata ParameterMetaDataView 614 → under 560
#16 URL parser named parse steps parse under 30 lines

Predicate (done)

  • ./mvnw -pl libsql-jdbc -am test green, and no existing assertion edited.
  • ./mvnw spotless:check green.
  • ./mvnw -pl libsql-conformance -am verify green (272 selected xerial tests).
  • Passes that touch connection, statement, prepared statement, or driver also run ./mvnw -pl libsql-itests -am verify with DOCKER_CONFIG set per AGENTS.md section 4.
  • Public API and every message unchanged.

Decisions

  • Removing the unused public LibsqlResultSetMetaData(Statement, StmtResult) constructor is a public API change. No pass touches it until the operator decides.
  • LibsqlPreparedStatement keeps implements ParameterMetaData. Pass 15 moves the method bodies behind a view so instanceof still holds. Dropping the interface is a separate compatibility decision.

Bugs found during the survey

Two defects are tracked under this epic as bug issues and are not refactors. They ship in their own PRs with a red test first.

Rejected on purpose

  • Splitting the unsupported-operation blocks. No line savings, and grouping tempts normalizing UnsupportedOperationException against SQLFeatureNotSupportedException.
  • Merging valueAtCursor and valueForMetadata. Different NULL semantics.
  • Rewriting the REAL formatter or the type if-chains. The quirks are the contract.
  • Unifying Locale.ENGLISH and Locale.ROOT upper-casing. No reader-load gain.
  • Consolidating the two constraint-name parsers. Both are pinned byte for byte, and the swap carries behavior risk with no structural win.

Activity

  1. added
    P2Normal priority: edge case, feature gap, or test/process improvement
    on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal priority: edge case, feature gap, or test/process improvement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions