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

loresoft / FluentCommand / 16327866078

16 Jul 2025 05:23PM UTC coverage: 55.131% (+0.1%) from 54.995%
16327866078

push

github

pwelter34
improve Imports

1735 of 3650 branches covered (47.53%)

Branch coverage included in aggregate %.

16 of 18 new or added lines in 1 file covered. (88.89%)

7 existing lines in 1 file now uncovered.

4384 of 7449 relevant lines covered (58.85%)

230.55 hits per line

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

90.91
/src/FluentCommand.Import/ImportDefinition.cs
1
using System.Text.Json.Serialization;
2
using System.Text.RegularExpressions;
3

4
namespace FluentCommand.Import;
5

6
/// <summary>
7
/// Represents the configuration and rules for an import operation, including target table, field definitions, and validation settings.
8
/// </summary>
9
public class ImportDefinition
10
{
11
    /// <summary>
12
    /// Gets or sets the name of the import operation.
13
    /// </summary>
14
    /// <value>
15
    /// The name of the import.
16
    /// </value>
17
    [JsonPropertyName("name")]
18
    public string? Name { get; set; }
21✔
19

20
    /// <summary>
21
    /// Gets or sets the name of the target table into which the uploaded data will be merged.
22
    /// </summary>
23
    /// <value>
24
    /// The target table name.
25
    /// </value>
26
    [JsonPropertyName("targetTable")]
27
    public string TargetTable { get; set; } = null!;
12✔
28

29
    /// <summary>
30
    /// Gets or sets a value indicating whether new data can be inserted into the <see cref="TargetTable"/> if it does not already exist.
31
    /// </summary>
32
    /// <value>
33
    /// <c>true</c> if data can be inserted; otherwise, <c>false</c>. The default is <c>true</c>.
34
    /// </value>
35
    [JsonPropertyName("canInsert")]
36
    public bool CanInsert { get; set; } = true;
19✔
37

38
    /// <summary>
39
    /// Gets or sets a value indicating whether existing data in the <see cref="TargetTable"/> can be updated.
40
    /// </summary>
41
    /// <value>
42
    /// <c>true</c> if data can be updated; otherwise, <c>false</c>. The default is <c>true</c>.
43
    /// </value>
44
    [JsonPropertyName("canUpdate")]
45
    public bool CanUpdate { get; set; } = true;
19✔
46

47
    /// <summary>
48
    /// Gets or sets the collection of field definitions that describe how each field is handled during import.
49
    /// </summary>
50
    /// <value>
51
    /// A list of <see cref="FieldDefinition"/> objects representing the import fields.
52
    /// </value>
53
    [JsonPropertyName("fields")]
54
    public List<FieldDefinition> Fields { get; set; } = [];
104✔
55

56
    /// <summary>
57
    /// Gets or sets the maximum number of errors allowed before the import operation is aborted.
58
    /// </summary>
59
    /// <value>
60
    /// The maximum number of errors permitted.
61
    /// </value>
62
    [JsonPropertyName("maxErrors")]
63
    public int MaxErrors { get; set; }
4✔
64

65
    /// <summary>
66
    /// Gets or sets the type of the validator used to validate data rows during import.
67
    /// The type must implement <see cref="IImportValidator"/>.
68
    /// </summary>
69
    /// <value>
70
    /// The <see cref="Type"/> of the validator, which must implement <see cref="IImportValidator"/>.
71
    /// </value>
72
    [JsonPropertyName("validator")]
73
    [JsonConverter(typeof(Converters.TypeJsonConverter))]
74
    [Obsolete("Use ValidatorKey instead. This property will be removed in a future version.")]
75
    public Type? Validator { get; set; }
4✔
76

77
    /// <summary>
78
    /// Gets or sets the service key used to resolve the <see cref="IImportValidator"/> service from the dependency injection container.
79
    /// The service must be registered in the DI container with this key and implement <see cref="IImportValidator"/>.
80
    /// </summary>
81
    /// <value>
82
    /// The service key used to resolve the validator service from the dependency injection container.
83
    /// </value>
84
    [JsonPropertyName("validatorKey")]
85
    public string? ValidatorKey { get; set; }
10✔
86

87
    /// <summary>
88
    /// Builds a mapping between import fields and source headers using regular expressions defined in <see cref="Fields"/>.
89
    /// </summary>
90
    /// <param name="headers">The list of source headers to match against field expressions.</param>
91
    /// <returns>
92
    /// A list of <see cref="FieldMap"/> objects representing the mapping between import fields and source headers.
93
    /// </returns>
94
    public List<FieldMap> BuildMapping(IReadOnlyCollection<FieldMap>? headers)
95
    {
96
        var list = new List<FieldMap>();
3✔
97

98
        // create a mapping for all fields
99
        foreach (var field in Fields)
16✔
100
        {
101
            // Skip fields that cannot be mapped
102
            if (!field.CanMap)
5✔
103
                continue;
104

105
            var map = new FieldMap { Name = field.Name };
4✔
106
            list.Add(map);
4✔
107

108
            // no expression, don't set mapped index
109
            if (field.Expressions == null || field.Expressions.Count == 0
4✔
110
                || headers == null || headers.Count == 0)
4✔
111
            {
112
                continue;
113
            }
114

115
            // for each expression, try to match against headers
116
            foreach (var expression in field.Expressions)
6!
117
            {
118
                foreach (var header in headers)
8!
119
                {
120
                    try
121
                    {
122
                        if (Regex.IsMatch(header.Name, expression))
3✔
123
                        {
124
                            map.Index = header.Index;
2✔
125
                            break; // Stop after the first match
2✔
126
                        }
127
                    }
1✔
NEW
128
                    catch
×
129
                    {
130
                        // skip error
NEW
131
                    }
×
132
                }
133

134
                // Stop checking expressions if we found a match
135
                if (map.Index.HasValue)
2✔
136
                    break;
2✔
137
            }
138
        }
139

140
        return list;
3✔
141

142
    }
143

144
    /// <summary>
145
    /// Builds an <see cref="ImportDefinition"/> using the specified builder action.
146
    /// </summary>
147
    /// <param name="builder">The action that configures the <see cref="ImportDefinitionBuilder"/>.</param>
148
    /// <returns>
149
    /// A fully configured <see cref="ImportDefinition"/> instance.
150
    /// </returns>
151
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/> is <c>null</c>.</exception>
152
    public static ImportDefinition Build(Action<ImportDefinitionBuilder> builder)
153
    {
154
        if (builder == null)
5✔
155
            throw new ArgumentNullException(nameof(builder));
1✔
156

157
        var importDefinition = new ImportDefinition();
4✔
158

159
        var importBuilder = new ImportDefinitionBuilder(importDefinition);
4✔
160
        builder(importBuilder);
4✔
161

162
        return importDefinition;
4✔
163
    }
164

165
    /// <summary>
166
    /// Returns a string that represents the current <see cref="ImportDefinition"/> instance, including the name, target table, and insert/update settings.
167
    /// </summary>
168
    /// <returns>
169
    /// A <see cref="string"/> representation of this <see cref="ImportDefinition"/>.
170
    /// </returns>
171
    public override string ToString()
172
    {
173
        return $"Name: {Name}, Table: {TargetTable}, Insert: {CanInsert}, Update: {CanUpdate}";
×
174
    }
175
}
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