davsclaus opened a new pull request, #28393:
URL: https://github.com/apache/camel/pull/28393

   _Claude Code on behalf of davsclaus_
   
   This group adds the catalog body types (CAMEL-24961) for eleven database 
components: jpa, sql-stored, mybatis, mybatis-bean, jooq, pgevent, 
pg-replication-slot, duckdb, clickhouse, drill and kudu. Each change is only an 
`@BodyTypes` annotation on the Endpoint, plus the JSON it generates and the 
catalog copy. Three doc pages had their body text corrected.
   
   **What the catalog says now**
   
   | Component | Consumer | Producer input | Producer output |
   |---|---|---|---|
   | jpa | one entity per message; a query that selects columns gives an Object 
array or one value | the entity to merge, persist or remove (a List or an array 
needs entityType `java.util.List`); the key with findEntity; not read with a 
query, whose parameters come from the `parameters` option or the 
CamelJpaParameters header | the managed entity that merge returns; unchanged 
with usePersist; the entity or null with findEntity; a query gives a List, its 
one result with singleResult, or the update count as an Integer; outputTarget 
keeps the body |
   | sql-stored | | `any`: a `:#name` parameter reads a Map body, or else the 
header; a List or an Iterator with batch; the template as text with 
useMessageBodyForTemplate | a `Map` of the OUT and INOUT parameters, with 
`#result-set-1` and `#update-count-1`; unchanged with noop, batch or 
outputHeader |
   | mybatis | one row per message as the statement maps it (a List of all rows 
with useIterator=false) | the parameter, handed to MyBatis without conversion | 
by statementType: SelectOne the row or null, SelectList a List; Insert, Update 
and Delete keep the body, with the count in CamelMyBatisResult |
   | mybatis-bean | | the argument of the method, converted by the bean binding 
| what the method returns; a void method keeps the body |
   | jooq | one `UpdatableRecord` of the entityType per row | a record for 
NONE, an `org.jooq.Query` for EXECUTE, an `org.jooq.ResultQuery` for FETCH; not 
read with the `query` option | unchanged; `org.jooq.Result` for FETCH |
   | pgevent | the payload as a `String`, with the channel in a header | `any`, 
converted to a String (under 8000 bytes) | unchanged |
   | pg-replication-slot | `byte[]`: text for test_decoding, JSON for wal2json, 
binary for pgoutput | | |
   | duckdb | | the SQL as text, bytes, a stream or a file; a List of Maps for 
INSERT; a File or a path for COPY | the row count as a `Long`; for QUERY a List 
of Maps (a JSON String with resultFormat=JSON); a `Boolean` for PING |
   | clickhouse | | the rows in the format of the `format` option, as text, 
bytes, a stream or a file, or a List of objects registered on the Client; the 
SQL for QUERY | unchanged, with the count in CamelClickHouseWrittenRows; a 
`String` for QUERY; a `Boolean` for PING |
   | drill | | `any`: the query is the CamelDrillQuery header | a List of Maps 
of the rows |
   | kudu | | a Map of one row for insert, update, upsert and delete; `any` for 
scan and create_table, which take headers | unchanged; a List of Maps for scan |
   
   **Checked at runtime.** Each component ran in throwaway tests that sent 
text, bytes, a stream, a file, a Map, a POJO and no body, and logged the class 
of the body after each step. The tests are not part of the PR. The databases 
used:
   - **Embedded:** H2 for jpa (OpenJPA) and mybatis; HSQLDB for jooq and the 
sql-stored procedures; DuckDB.
   - **Docker:**
     - PostgreSQL 17 for pgevent and pg-replication-slot, with test_decoding 
and pgoutput;
     - ClickHouse 26.9;
     - Apache Drill 1.22.0;
     - a Kudu master and tablet server.
   
   mybatis was run with InOnly and InOut. Not run:
   - sql-stored: a procedure that returns a result set, `function=true`, an 
INOUT parameter.
   - clickhouse: a List of registered POJOs (the client could not read the 
table schema from this server).
   
   **Choices**
   - mybatis has no default statementType, so the default output is `unknown`, 
and every statement type is listed by option.
   - The rows of the mybatis consumer and of SelectOne are `unknown`, because 
the statement's resultType or resultMap decides their class.
   - The javaType of a List of rows is `java.util.List<java.util.Map<String, 
Object>>`, as for the AWS components.
   
   **Doc fixes**
   - mybatis-bean: the body is what the mapper method returns, not only the 
result of a SELECT.
   - mybatis: the result goes to the outputHeader header when that option is 
set.
   - jooq: the operations table said that NONE executes a query. NONE stores 
the record.
   
   **Bugs found, not fixed here.** The JIRAs, one per component, will follow.
   - **mybatis:**
     - With an InOut exchange, Insert, Update and Delete (and their List 
variants) set the body to null instead of keeping it. 
`MyBatisProducer.doProcessResult` uses `getOut()` and copies the body only with 
outputHeader.
     - An Insert with no body stores a row of NULLs, with no error.
   - **jooq:**
     - The `operation` enum of the catalog lists CONSUME, but `JooqOperation` 
has no such value, so `operation=consume` fails.
     - NONE with no body inserts an empty record.
     - EXECUTE or FETCH with neither a body nor `query` fails with 
`NoSuchMethodException: org.jooq.Query.<init>()`.
   - **jpa:**
     - A consumer whose query returns scalar values delivers nothing with the 
default consumeLockEntity=true. Each row is skipped, with only a debug log.
     - The page says the entity class is optional for a producer, but the path 
is required.
   - **sql-stored:**
     - With batch=true, CamelSqlStoredUpdateCount sums the `executeBatch()` 
counts, including SUCCESS_NO_INFO (-2), so 2 items gave -4.
     - A single Map body with batch=true is iterated as map entries, and the 
call fails with an unclear SQLException.
   - **duckdb:**
     - The `query` option is documented "for query when the message body is 
empty", but it replaces a non-empty body too.
     - COPY rejects a `java.nio.file.Path` and a byte[] body.
     - Running a SELECT as execute, or DDL as query, gives a JDBC error with no 
hint to change the operation.
   - **clickhouse:**
     - QUERY decodes the response as a UTF-8 String, so binary formats 
(RowBinary, Native, Parquet) are corrupted.
     - Inserting a List of Maps, or of POJOs that are not registered, fails 
with a NullPointerException inside the client.
     - CamelClickHouseReadRows is the number of rows scanned, not the number 
returned.
   - **pg-replication-slot:** the exchange id is the last received LSN, which 
is not unique. The BEGIN and the first change of a transaction got the same id.
   - **kudu:**
     - No `operation` fails with a NullPointerException.
     - A body that is not a Map fails with a NullPointerException ("rows" is 
null).
     - CamelKuduScanLimit as an Integer fails with a ClassCastException (a raw 
`(Long)` cast).
   - **drill:**
     - No CamelDrillQuery header fails with `SQLException: Error while 
executing SQL "null"`.
     - On JDK 25 the Drill JDBC driver cannot connect (`PooledDirectByteBuf 
cannot be cast to PooledUnsafeDirectByteBuf`) unless run with 
`-Dio.netty.noUnsafe=false`.
   
   Open PR #22358 changes code in camel-jooq, camel-mybatis and camel-sql, but 
not the Endpoint classes or the generated files of this PR.
   
   **Local checks**
   - The 10 changed modules build, with no change to the generated files after 
the build.
   - The 14 catalog copies equal their modules.
   - camel-catalog tests pass (1103).
   - The Endpoint and Component DSLs regenerate with no change.
   - camel-yaml-dsl-validator tests pass (295).
   - camel-jbang-core tests pass (2424 and 238).
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to