• 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

35.85
/src/FluentCommand.SqlServer/Query/TemporalBuilder.cs
1
using FluentCommand.Extensions;
2
using FluentCommand.Query.Generators;
3
using FluentCommand.Reflection;
4

5
namespace FluentCommand.Query;
6

7
/// <summary>
8
/// Provides a builder for constructing SQL Server temporal table queries using <c>FOR SYSTEM_TIME</c> clauses.
9
/// </summary>
10
public class TemporalBuilder : StatementBuilder<TemporalBuilder>
11
{
12
    private TableExpression? _from;
13
    private string? _temporal;
14

15
    /// <summary>
16
    /// Initializes a new instance of the <see cref="TemporalBuilder"/> class.
17
    /// </summary>
18
    /// <param name="queryGenerator">The query generator used to build SQL expressions.</param>
19
    /// <param name="parameters">The list of query parameters.</param>
20
    public TemporalBuilder(IQueryGenerator queryGenerator, List<QueryParameter> parameters)
21
        : base(queryGenerator, parameters)
1✔
22
    {
23
    }
1✔
24

25
    /// <summary>
26
    /// Specifies the source table for the temporal query using the table name, schema, and optional alias.
27
    /// </summary>
28
    /// <param name="tableName">The name of the table to query.</param>
29
    /// <param name="tableSchema">The schema of the table (optional).</param>
30
    /// <param name="tableAlias">The alias to use for the table in the query (optional).</param>
31
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
32
    public TemporalBuilder From(
33
        string tableName,
34
        string? tableSchema = null,
35
        string? tableAlias = null)
36
    {
37
        _from = new TableExpression(tableName, tableSchema, tableAlias);
×
38

39
        return this;
×
40
    }
41

42
    /// <summary>
43
    /// Specifies the source table for the temporal query using the entity type and optional alias.
44
    /// </summary>
45
    /// <typeparam name="TEntity">The entity type representing the table.</typeparam>
46
    /// <param name="tableAlias">The alias to use for the table in the query (optional).</param>
47
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
48
    public TemporalBuilder From<TEntity>(
49
        string? tableAlias = null)
50
    {
51
        var typeAccessor = TypeAccessor.GetAccessor<TEntity>();
1✔
52

53
        _from = new TableExpression(typeAccessor.TableName, typeAccessor.TableSchema, tableAlias);
1✔
54

55
        return this;
1✔
56
    }
57

58
    /// <summary>
59
    /// Configures the query to return all rows from the temporal table's history using <c>FOR SYSTEM_TIME ALL</c>.
60
    /// </summary>
61
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
62
    public TemporalBuilder All()
63
    {
64
        _temporal = "FOR SYSTEM_TIME ALL";
×
65
        return this;
×
66
    }
67

68
    /// <summary>
69
    /// Configures the query to return rows as of a specific point in time using <c>FOR SYSTEM_TIME AS OF</c>.
70
    /// </summary>
71
    /// <param name="utcPointInTime">The UTC date and time to query as of.</param>
72
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
73
    public TemporalBuilder AsOf(DateTime utcPointInTime)
74
    {
75
        var paramName = NextParameter();
1✔
76
        var queryParameter = new QueryParameter(paramName, utcPointInTime, typeof(DateTime));
1✔
77

78
        _temporal = $"FOR SYSTEM_TIME AS OF {paramName}";
1✔
79
        Parameters.Add(queryParameter);
1✔
80

81
        return this;
1✔
82
    }
83

84
    /// <summary>
85
    /// Configures the query to return rows that were active between two points in time using <c>FOR SYSTEM_TIME BETWEEN</c>.
86
    /// </summary>
87
    /// <param name="utcStart">The UTC start date and time.</param>
88
    /// <param name="utcEnd">The UTC end date and time.</param>
89
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
90
    public TemporalBuilder Between(DateTime utcStart, DateTime utcEnd)
91
    {
92
        var nameStart = NextParameter();
×
93
        var paramStart = new QueryParameter(nameStart, utcStart, typeof(DateTime));
×
94

95
        var nameEnd = NextParameter();
×
96
        var paramEnd = new QueryParameter(nameEnd, utcEnd, typeof(DateTime));
×
97

98
        _temporal = $"FOR SYSTEM_TIME BETWEEN {nameStart} AND {nameEnd}";
×
99

100
        Parameters.Add(paramStart);
×
101
        Parameters.Add(paramEnd);
×
102

103
        return this;
×
104
    }
105

106
    /// <summary>
107
    /// Configures the query to return rows whose period is contained within the specified range using <c>FOR SYSTEM_TIME CONTAINED IN</c>.
108
    /// </summary>
109
    /// <param name="utcStart">The UTC start date and time.</param>
110
    /// <param name="utcEnd">The UTC end date and time.</param>
111
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
112
    public TemporalBuilder ContainedIn(DateTime utcStart, DateTime utcEnd)
113
    {
114
        var nameStart = NextParameter();
×
115
        var paramStart = new QueryParameter(nameStart, utcStart, typeof(DateTime));
×
116

117
        var nameEnd = NextParameter();
×
118
        var paramEnd = new QueryParameter(nameEnd, utcEnd, typeof(DateTime));
×
119

120
        _temporal = $"FOR SYSTEM_TIME CONTAINED IN ({nameStart}, {nameEnd})";
×
121

122
        Parameters.Add(paramStart);
×
123
        Parameters.Add(paramEnd);
×
124

125
        return this;
×
126
    }
127

128
    /// <summary>
129
    /// Configures the query to return rows that were active from the start time to the end time using <c>FOR SYSTEM_TIME FROM ... AND ...</c>.
130
    /// </summary>
131
    /// <param name="utcStart">The UTC start date and time.</param>
132
    /// <param name="utcEnd">The UTC end date and time.</param>
133
    /// <returns>The same <see cref="TemporalBuilder"/> instance for fluent chaining.</returns>
134
    public TemporalBuilder FromTo(DateTime utcStart, DateTime utcEnd)
135
    {
136
        var nameStart = NextParameter();
×
137
        var paramStart = new QueryParameter(nameStart, utcStart, typeof(DateTime));
×
138

139
        var nameEnd = NextParameter();
×
140
        var paramEnd = new QueryParameter(nameEnd, utcEnd, typeof(DateTime));
×
141

142
        _temporal = $"FOR SYSTEM_TIME FROM {nameStart} AND {nameEnd}";
×
143

144
        Parameters.Add(paramStart);
×
145
        Parameters.Add(paramEnd);
×
146

147
        return this;
×
148
    }
149

150
    /// <summary>
151
    /// Builds the SQL statement for the temporal query using the specified table and temporal clause.
152
    /// </summary>
153
    /// <returns>
154
    /// A <see cref="QueryStatement"/> representing the constructed temporal query and its parameters.
155
    /// </returns>
156
    public override QueryStatement? BuildStatement()
157
    {
158
        if (_from is null)
1!
NEW
159
            throw new InvalidOperationException("The table source must be specified using From() before building the statement.");
×
160

161
        if (_temporal.IsNullOrWhiteSpace())
1!
162
            return new QueryStatement(QueryGenerator.TableExpression(_from), Parameters);
×
163

164
        var table = QueryGenerator.TableExpression(new TableExpression(_from.TableName, _from.TableSchema));
1✔
165

166
        var statement = $"{table} {_temporal}";
1✔
167

168
        if (_from.TableAlias.HasValue())
1!
169
            statement += $" AS [{_from.TableAlias}]";
×
170

171
        return new QueryStatement(statement, Parameters);
1✔
172
    }
173
}
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