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

loresoft / FluentCommand / 16330989171

16 Jul 2025 09:44PM UTC coverage: 55.225% (-0.005%) from 55.23%
16330989171

push

github

pwelter34
Update ImportDefinition.cs

1739 of 3650 branches covered (47.64%)

Branch coverage included in aggregate %.

0 of 1 new or added line in 1 file covered. (0.0%)

4391 of 7450 relevant lines covered (58.94%)

230.53 hits per line

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

89.29
/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
    /// Retrieves a field definition by its name, ignoring case.
89
    /// </summary>
90
    /// <param name="name">The name of the field to retrieve.</param>
91
    /// <returns>
92
    /// The <see cref="FieldDefinition"/> that matches the specified name, or <see langword="null"/> if no matching field is found.
93
    /// </returns>
94
    public FieldDefinition? GetField(string name)
95
    {
NEW
96
        return Fields.Find(f => f.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
×
97
    }
98

99
    /// <summary>
100
    /// Builds a mapping between import fields and source headers using regular expressions defined in <see cref="Fields"/>.
101
    /// </summary>
102
    /// <param name="headers">The list of source headers to match against field expressions.</param>
103
    /// <returns>
104
    /// A list of <see cref="FieldMap"/> objects representing the mapping between import fields and source headers.
105
    /// </returns>
106
    public List<FieldMap> BuildMapping(IReadOnlyCollection<FieldMap>? headers)
107
    {
108
        var list = new List<FieldMap>();
3✔
109

110
        // create a mapping for all fields
111
        foreach (var field in Fields)
16✔
112
        {
113
            // Skip fields that cannot be mapped
114
            if (!field.CanMap)
5✔
115
                continue;
116

117
            var map = new FieldMap { Name = field.Name };
4✔
118
            list.Add(map);
4✔
119

120
            // no expression, don't set mapped index
121
            if (field.Expressions == null || field.Expressions.Count == 0
4✔
122
                || headers == null || headers.Count == 0)
4✔
123
            {
124
                continue;
125
            }
126

127
            // for each expression, try to match against headers
128
            foreach (var expression in field.Expressions)
6!
129
            {
130
                foreach (var header in headers)
8!
131
                {
132
                    try
133
                    {
134
                        if (Regex.IsMatch(header.Name, expression))
3✔
135
                        {
136
                            map.Index = header.Index;
2✔
137
                            break; // Stop after the first match
2✔
138
                        }
139
                    }
1✔
140
                    catch
×
141
                    {
142
                        // skip error
143
                    }
×
144
                }
145

146
                // Stop checking expressions if we found a match
147
                if (map.Index.HasValue)
2✔
148
                    break;
2✔
149
            }
150
        }
151

152
        return list;
3✔
153

154
    }
155

156
    /// <summary>
157
    /// Builds an <see cref="ImportDefinition"/> using the specified builder action.
158
    /// </summary>
159
    /// <param name="builder">The action that configures the <see cref="ImportDefinitionBuilder"/>.</param>
160
    /// <returns>
161
    /// A fully configured <see cref="ImportDefinition"/> instance.
162
    /// </returns>
163
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/> is <c>null</c>.</exception>
164
    public static ImportDefinition Build(Action<ImportDefinitionBuilder> builder)
165
    {
166
        if (builder == null)
5✔
167
            throw new ArgumentNullException(nameof(builder));
1✔
168

169
        var importDefinition = new ImportDefinition();
4✔
170

171
        var importBuilder = new ImportDefinitionBuilder(importDefinition);
4✔
172
        builder(importBuilder);
4✔
173

174
        return importDefinition;
4✔
175
    }
176

177
    /// <summary>
178
    /// Returns a string that represents the current <see cref="ImportDefinition"/> instance, including the name, target table, and insert/update settings.
179
    /// </summary>
180
    /// <returns>
181
    /// A <see cref="string"/> representation of this <see cref="ImportDefinition"/>.
182
    /// </returns>
183
    public override string ToString()
184
    {
185
        return $"Name: {Name}, Table: {TargetTable}, Insert: {CanInsert}, Update: {CanUpdate}";
×
186
    }
187
}
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