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

jhannes / fluent-jdbc / #195

05 Oct 2025 02:47PM UTC coverage: 92.242% (-0.05%) from 92.296%
#195

push

jhannes-test
simplify the creation of DbContextSqlBuilder based on a table

* TODO: This blurs the distance between DbContextSqlBuilder and DbContextSelectBuilder and could be solved with making DbContextSelect builder support custom "select" expressions

6 of 6 new or added lines in 3 files covered. (100.0%)

1 existing line in 1 file now uncovered.

1189 of 1289 relevant lines covered (92.24%)

0.92 hits per line

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

86.96
/src/main/java/org/fluentjdbc/DbContextSqlBuilder.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
 * Used to construct SQL SELECT statements in a flexible way with {@link #where(String, Object)}
11
 * clauses, {@link #select(String...)} column names, {@link #from(String)} table statement,
12
 * {@link #groupBy(String...)}, {@link #orderBy(String)} and {@link #skipAndLimit(int, int)}.
13
 *
14
 * <h2>Example:</h2>
15
 *
16
 * <pre>
17
 * new DbContextSqlBuilder(dbContext)
18
 *      .select("first_name", "last_name")
19
 *      .select("p.id")
20
 *      .from("person p full join organizations o")
21
 *      .where("organization_sector", sector)
22
 *      .limit(100)
23
 *      .list(row -&gt; List.of(row.getString("first_name"), row.getString("last_name"), row.getUUID("p.id"));
24
 * </pre>
25
 *
26
 */
27
public class DbContextSqlBuilder implements DbContextListableSelect<DbContextSqlBuilder> {
28

29
    private final DatabaseSqlBuilder builder;
30
    private final DbContext dbContext;
31

32
    public DbContextSqlBuilder(DbContext dbContext) {
33
        this(dbContext, new DatabaseSqlBuilder(dbContext.getStatementFactory()));
1✔
34
    }
1✔
35

36
    public DbContextSqlBuilder(DbContext dbContext, DatabaseSqlBuilder builder) {
1✔
37
        this.dbContext = dbContext;
1✔
38
        this.builder = builder;
1✔
39
    }
1✔
40

41
    /**
42
     * Implemented as <code>return this</code> for compatibility purposes
43
     */
44
    @Override
45
    public DbContextSqlBuilder query() {
UNCOV
46
        return this;
×
47
    }
48

49
    /**
50
     * Add the arguments to the column list for the <code>SELECT column, column...</code> statement
51
     */
52
    @CheckReturnValue
53
    public DbContextSqlBuilder select(String... columns) {
54
        return query(builder.select(columns));
1✔
55
    }
56

57
    /**
58
     * Replace the "from" part of the <code>SELECT ... FROM fromStatement</code> in the select statement
59
     */
60
    @CheckReturnValue
61
    public DbContextSqlBuilder from(String fromStatement) {
62
        return query(builder.from(fromStatement));
1✔
63
    }
64

65
    @Override
66
    public DbContextSqlBuilder where(DatabaseQueryParameter parameter) {
67
        builder.where(parameter);
1✔
68
        return this;
1✔
69
    }
70

71
    /**
72
     * Add the arguments to the column list for the <code>SELECT ... FROM ... ... GROUP BY groupByStatement</code> statement
73
     */
74
    @CheckReturnValue
75
    public DbContextSqlBuilder groupBy(String... groupByStatement) {
76
        return query(builder.groupBy(groupByStatement));
1✔
77
    }
78

79
    /**
80
     * Adds <code>ORDER BY ...</code> clause to the <code>SELECT</code> statement
81
     */
82
    @Override
83
    public DbContextSqlBuilder orderBy(String orderByClause) {
84
        return query(builder.orderBy(orderByClause));
1✔
85
    }
86

87
    /**
88
     * If you haven't called {@link #orderBy}, the results of {@link DatabaseListableQueryBuilder#list}
89
     * will be unpredictable. Call <code>unordered()</code> if you are okay with this.
90
     */
91
    @CheckReturnValue
92
    public DbContextSqlBuilder unordered() {
93
        return query(builder.unordered());
1✔
94
    }
95

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

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

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

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

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

151
    /**
152
     * Executes the <code>SELECT * FROM ...</code> statement and calls back to
153
     * {@link DatabaseResult.RowConsumer} for each returned row
154
     */
155
    @Override
156
    public void forEach(DatabaseResult.RowConsumer consumer) {
157
        builder.forEach(getConnection(), consumer);
×
158
    }
×
159

160
    @SuppressWarnings("unused")
161
    private DbContextSqlBuilder query(DatabaseSqlBuilder builder) {
162
        return this;
1✔
163
    }
164

165
    @Nonnull
166
    private Connection getConnection() {
167
        return dbContext.getThreadConnection();
1✔
168
    }
169
}
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