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

loresoft / FluentCommand / 23278216331

19 Mar 2026 03:19AM UTC coverage: 57.398% (+0.7%) from 56.658%
23278216331

push

github

pwelter34
Enable nullable and improve source generators

1403 of 3069 branches covered (45.72%)

Branch coverage included in aggregate %.

527 of 907 new or added lines in 58 files covered. (58.1%)

22 existing lines in 10 files now uncovered.

4288 of 6846 relevant lines covered (62.64%)

330.58 hits per line

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

75.0
/src/FluentCommand/Query/JoinBuilder.cs
1
using FluentCommand.Query.Generators;
2

3
namespace FluentCommand.Query;
4

5
/// <summary>
6
/// Provides a builder for constructing SQL JOIN clauses with fluent, chainable methods.
7
/// </summary>
8
public class JoinBuilder : JoinBuilder<JoinBuilder>
9
{
10
    /// <summary>
11
    /// Initializes a new instance of the <see cref="JoinBuilder"/> class.
12
    /// </summary>
13
    /// <param name="queryGenerator">The <see cref="IQueryGenerator"/> used to generate SQL expressions.</param>
14
    /// <param name="parameters">The list of <see cref="QueryParameter"/> objects for the query.</param>
15
    public JoinBuilder(IQueryGenerator queryGenerator, List<QueryParameter> parameters)
16
        : base(queryGenerator, parameters)
1✔
17
    {
18
    }
1✔
19
}
20

21
/// <summary>
22
/// Provides a generic base class for building SQL JOIN clauses with fluent, chainable methods.
23
/// </summary>
24
/// <typeparam name="TBuilder">The type of the builder for fluent chaining.</typeparam>
25
public class JoinBuilder<TBuilder> : StatementBuilder<TBuilder>
26
    where TBuilder : JoinBuilder<TBuilder>
27
{
28
    private string? _leftColumnName;
29
    private string? _leftTableAlias;
30
    private string? _rightColumnName;
31
    private string? _rightTableName;
32
    private string? _rightTableSchema;
33
    private string? _rightTableAlias;
34
    private JoinTypes _joinType = JoinTypes.Inner;
35

36
    /// <summary>
37
    /// Initializes a new instance of the <see cref="JoinBuilder{TBuilder}"/> class.
38
    /// </summary>
39
    /// <param name="queryGenerator">The <see cref="IQueryGenerator"/> used to generate SQL expressions.</param>
40
    /// <param name="parameters">The list of <see cref="QueryParameter"/> objects for the query.</param>
41
    public JoinBuilder(IQueryGenerator queryGenerator, List<QueryParameter> parameters)
42
        : base(queryGenerator, parameters)
13✔
43
    {
44
    }
13✔
45

46
    /// <summary>
47
    /// Specifies the left column to join on.
48
    /// </summary>
49
    /// <param name="columnName">The name of the column in the left table.</param>
50
    /// <param name="tableAlias">The alias of the left table.</param>
51
    /// <returns>
52
    /// The same builder instance for method chaining.
53
    /// </returns>
54
    public TBuilder Left(
55
        string columnName,
56
        string tableAlias)
57
    {
58
        _leftColumnName = columnName;
13✔
59
        _leftTableAlias = tableAlias;
13✔
60

61
        return (TBuilder)this;
13✔
62
    }
63

64
    /// <summary>
65
    /// Specifies the right column and table to join on.
66
    /// </summary>
67
    /// <param name="columnName">The name of the column in the right table.</param>
68
    /// <param name="tableName">The name of the right table.</param>
69
    /// <param name="tableSchema">The schema of the right table.</param>
70
    /// <param name="tableAlias">The alias of the right table. If <c>null</c>, the table name is used as the alias.</param>
71
    /// <returns>
72
    /// The same builder instance for method chaining.
73
    /// </returns>
74
    public TBuilder Right(
75
        string columnName,
76
        string tableName,
77
        string? tableSchema,
78
        string? tableAlias)
79
    {
80
        _rightColumnName = columnName;
13✔
81
        _rightTableName = tableName;
13✔
82
        _rightTableSchema = tableSchema;
13✔
83
        _rightTableAlias = tableAlias ?? tableName;
13!
84

85
        return (TBuilder)this;
13✔
86
    }
87

88
    /// <summary>
89
    /// Specifies the type of SQL JOIN operation to use.
90
    /// </summary>
91
    /// <param name="joinType">The <see cref="JoinTypes"/> value indicating the type of join (e.g., Inner, Left, Right).</param>
92
    /// <returns>
93
    /// The same builder instance for method chaining.
94
    /// </returns>
95
    public TBuilder Type(JoinTypes joinType)
96
    {
97
        _joinType = joinType;
1✔
98

99
        return (TBuilder)this;
1✔
100
    }
101

102
    /// <summary>
103
    /// Builds and returns the <see cref="JoinExpression"/> representing the configured JOIN clause.
104
    /// </summary>
105
    /// <returns>
106
    /// The <see cref="JoinExpression"/> for the JOIN clause.
107
    /// </returns>
108
    /// <exception cref="InvalidOperationException">Thrown if the left or right side of the join has not been specified.</exception>
109
    public virtual JoinExpression BuildExpression()
110
    {
111
        if (_leftTableAlias is null || _leftColumnName is null)
13!
NEW
112
            throw new InvalidOperationException("Left join column and table alias must be specified.");
×
113

114
        if (_rightTableName is null || _rightTableAlias is null || _rightColumnName is null)
13!
NEW
115
            throw new InvalidOperationException("Right join table, alias, and column must be specified.");
×
116

117
        return new JoinExpression(
13✔
118
            LeftTableAlias: _leftTableAlias,
13✔
119
            LeftColumnName: _leftColumnName,
13✔
120
            RightTableName: _rightTableName,
13✔
121
            RightTableAlias: _rightTableAlias,
13✔
122
            RightColumnName: _rightColumnName,
13✔
123
            RightTableSchema: _rightTableSchema,
13✔
124
            JoinType: _joinType);
13✔
125
    }
126

127
    /// <summary>
128
    /// Builds the SQL JOIN statement using the current configuration.
129
    /// </summary>
130
    /// <returns>
131
    /// A <see cref="QueryStatement"/> containing the SQL JOIN clause and its parameters.
132
    /// </returns>
133
    public override QueryStatement? BuildStatement()
134
    {
NEW
135
        var joinClause = QueryGenerator.JoinExpression(BuildExpression());
×
136

137
        return new QueryStatement(joinClause, Parameters);
×
138
    }
139
}
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

© 2026 Coveralls, Inc