• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jhannes / fluent-jdbc / #198

06 Oct 2025 10:27PM UTC coverage: 91.711% (-0.5%) from 92.242%
#198

push

jhannes-test
improved ergonomics of select builders

88 of 100 new or added lines in 13 files covered. (88.0%)

2 existing lines in 1 file now uncovered.

1195 of 1303 relevant lines covered (91.71%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.65
/src/main/java/org/fluentjdbc/DbContextTableQueryBuilder.java
1
package org.fluentjdbc;
2

3
import javax.annotation.CheckReturnValue;
4
import javax.annotation.Nonnull;
5
import java.sql.Connection;
6
import java.util.List;
7
import java.util.stream.Stream;
8

9
/**
10
 * Generate <code>SELECT</code> statements by collecting <code>WHERE</code> expressions and parameters.Example:
11
 *
12
 * <pre>
13
 * {@link DbContextTable} table = context.table("database_test_table");
14
 * try (DbContextConnection ignored = context.startConnection(dataSource)) {
15
 *      List&lt;Person&gt; result = table
16
 *          .where("firstName", firstName)
17
 *          .whereExpression("lastName like ?", "joh%")
18
 *          .whereIn("status", statuses)
19
 *          .orderBy("lastName")
20
 *          .list(row -&gt; new Person(row));
21
 * }
22
 * </pre>
23
 *
24
 * @see org.fluentjdbc.DatabaseTableQueryBuilder
25
 */
26
public class DbContextTableQueryBuilder implements DbContextListableSelect<DbContextTableQueryBuilder> {
27

28
    private final DbContextTable dbContextTable;
29
    private final DatabaseTableQueryBuilder builder;
30

31
    public DbContextTableQueryBuilder(DbContextTable dbContextTable) {
1✔
32
        this.dbContextTable = dbContextTable;
1✔
33
        builder = new DatabaseTableQueryBuilder(dbContextTable.getTable());
1✔
34
    }
1✔
35

36
    /**
37
     * Returns this. Needed to make {@link DbContextTableQueryBuilder} interchangeable with {@link DbContextTable}
38
     */
39
    @Override
40
    public DbContextTableQueryBuilder query() {
41
        return this;
1✔
42
    }
43

44

45
    @CheckReturnValue
46
    private DbContextTableQueryBuilder query(@SuppressWarnings("unused") DatabaseTableQueryBuilder builder) {
47
        return this;
1✔
48
    }
49

50
    /**
51
     * Add the arguments to the column list for the <code>SELECT column, column...</code> statement
52
     */
53
    @CheckReturnValue
54
    public DbContextSelectBuilder select(String... columns) {
NEW
55
        return new DbContextSelectBuilder(dbContextTable.getDbContext(), builder.select(columns));
×
56
    }
57

58
    /**
59
     * Adds the parameter to the WHERE-clause and all the parameter list.
60
     * E.g. <code>where(new DatabaseQueryParameter("created_at between ? and ?", List.of(earliestDate, latestDate)))</code>
61
     */
62
    @Override
63
    public DbContextTableQueryBuilder where(DatabaseQueryParameter parameter) {
64
        return query(builder.where(parameter));
1✔
65
    }
66

67
    /**
68
     * Adds <code>ORDER BY ...</code> clause to the <code>SELECT</code> statement
69
     */
70
    @Override
71
    public DbContextTableQueryBuilder orderBy(String orderByClause) {
72
        return query(builder.orderBy(orderByClause));
1✔
73
    }
74

75
    /**
76
     * If you haven't called {@link #orderBy}, the results of {@link #list}
77
     * will be unpredictable. Call <code>unordered()</code> if you are okay with this.
78
     */
79
    @CheckReturnValue
80
    public DbContextTableQueryBuilder unordered() {
81
        return query(builder.unordered());
1✔
82
    }
83

84
    /**
85
     * Adds <code>FETCH ... ROWS ONLY</code> clause to the <code>SELECT</code> statement.
86
     * FETCH FIRST was introduced in
87
     * <a href="https://en.wikipedia.org/wiki/Select_%28SQL%29#Limiting_result_rows">SQL:2008</a>
88
     * and is supported by Postgresql 8.4, Oracle 12c, IBM DB2, HSQLDB, H2, and SQL Server 2012.
89
     */
90
    @CheckReturnValue
91
    public DbContextSelectBuilder limit(int rowCount) {
92
        return skipAndLimit(0, rowCount);
1✔
93
    }
94

95
    /**
96
     * Adds <code>OFFSET ... ROWS FETCH ... ROWS ONLY</code> clause to the <code>SELECT</code>
97
     * statement. FETCH FIRST was introduced in
98
     * <a href="https://en.wikipedia.org/wiki/Select_%28SQL%29#Limiting_result_rows">SQL:2008</a>
99
     * and is supported by Postgresql 8.4, Oracle 12c, IBM DB2, HSQLDB, H2, and SQL Server 2012.
100
     */
101
    @CheckReturnValue
102
    public DbContextSelectBuilder skipAndLimit(int offset, int rowCount) {
103
        return new DbContextSelectBuilder(dbContextTable.getDbContext(), builder.skipAndLimit(offset, rowCount));
1✔
104
    }
105

106
    /**
107
     * Execute the query and map each return value over the {@link DatabaseResult.RowMapper} function to return a stream. Example:
108
     * <pre>
109
     *     table.where("status", status).stream(row -&gt; row.getInstant("created_at"))
110
     * </pre>
111
     */
112
    @Override
113
    public <OBJECT> Stream<OBJECT> stream(DatabaseResult.RowMapper<OBJECT> mapper) {
114
        return builder.stream(getConnection(), mapper);
1✔
115
    }
116

117
    /**
118
     * Execute the query and map each return value over the {@link DatabaseResult.RowMapper} function to return a list. Example:
119
     * <pre>
120
     *     List&lt;Instant&gt; creationTimes = table.where("status", status).list(row -&gt; row.getInstant("created_at"))
121
     * </pre>
122
     */
123
    @Override
124
    public <OBJECT> List<OBJECT> list(DatabaseResult.RowMapper<OBJECT> mapper) {
125
        return builder.list(getConnection(), mapper);
1✔
126
    }
127

128
    /**
129
     * Executes <code>SELECT count(*) FROM ...</code> on the query and returns the result
130
     */
131
    @Override
132
    public int getCount() {
133
        return builder.getCount(getConnection());
1✔
134
    }
135

136
    /**
137
     * If the query returns no rows, returns {@link SingleRow#absent}, if exactly one row is returned, maps it and return it,
138
     * if more than one is returned, throws `IllegalStateException`
139
     *
140
     * @param mapper Function object to map a single returned row to an object
141
     * @return the mapped row if one row is returned, {@link SingleRow#absent} otherwise
142
     * @throws MultipleRowsReturnedException if more than one row was matched the query
143
     */
144
    @Nonnull
145
    @Override
146
    public <OBJECT> SingleRow<OBJECT> singleObject(DatabaseResult.RowMapper<OBJECT> mapper) {
147
        return builder.singleObject(getConnection(), mapper);
1✔
148
    }
149

150
    /**
151
     * Returns a string from the specified column name
152
     *
153
     * @return the mapped row if one row is returned, {@link SingleRow#absent} otherwise
154
     * @throws MultipleRowsReturnedException if more than one row was matched the query
155
     */
156
    @Nonnull
157
    @Override
158
    public SingleRow<String> singleString(String fieldName) {
159
        return builder.singleString(getConnection(), fieldName);
1✔
160
    }
161

162
    /**
163
     * Executes the <code>SELECT * FROM ...</code> statement and calls back to
164
     * {@link DatabaseResult.RowConsumer} for each returned row
165
     */
166
    @Override
167
    public void forEach(DatabaseResult.RowConsumer consumer) {
168
        builder.forEach(getConnection(), consumer);
1✔
169
    }
1✔
170

171
    /**
172
     * Executes <code>DELETE FROM tableName WHERE ....</code>
173
     */
174
    public int executeDelete() {
175
        return builder.delete(getConnection());
1✔
176
    }
177

178
    /**
179
     * Creates a {@link DbContextUpdateBuilder} object to fluently generate a <code>UPDATE ...</code> statement
180
     */
181
    @CheckReturnValue
182
    public DbContextUpdateBuilder update() {
183
        return new DbContextUpdateBuilder(this.dbContextTable, builder.update());
1✔
184
    }
185

186
    @CheckReturnValue
187
    public DbContextInsertOrUpdateBuilder insertOrUpdate() {
188
        return new DbContextInsertOrUpdateBuilder(this.dbContextTable, builder.insertOrUpdate());
1✔
189
    }
190

191
    @CheckReturnValue
192
    private Connection getConnection() {
193
        return dbContextTable.getConnection();
1✔
194
    }
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc