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

HicServices / RDMP / 13318089130

13 Feb 2025 10:13PM UTC coverage: 57.398% (+0.004%) from 57.394%
13318089130

Pull #2134

github

jas88
Update ChildProviderTests.cs

Fix up TestUpTo method
Pull Request #2134: CodeQL fixups

11346 of 21308 branches covered (53.25%)

Branch coverage included in aggregate %.

104 of 175 new or added lines in 45 files covered. (59.43%)

362 existing lines in 23 files now uncovered.

32218 of 54590 relevant lines covered (59.02%)

17091.93 hits per line

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

56.68
/Rdmp.Core/ReusableLibraryCode/Settings/RDMPApplicationSettings.cs
1
// Copyright (c) The University of Dundee 2018-2019
2
// This file is part of the Research Data Management Platform (RDMP).
3
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.
6

7
using System;
8
using System.IO;
9
using System.IO.IsolatedStorage;
10
using System.Linq;
11
using System.Threading;
12

13
namespace Rdmp.Core.ReusableLibraryCode.Settings;
14

15
internal sealed class RDMPApplicationSettings
16
{
17
    private readonly IsolatedStorageFile _store;
18
    private readonly Lock _locker = new();
4✔
19

20
    public RDMPApplicationSettings()
4✔
21
    {
22
        try
23
        {
24
            _store = IsolatedStorageFile.GetUserStoreForApplication();
4✔
25
        }
4✔
26
        catch (Exception)
×
27
        {
NEW
28
            _store = IsolatedStorageFile.GetUserStoreForAssembly();
×
29
        }
×
30
    }
4✔
31

32
    /// <summary>
33
    /// Add or Update
34
    /// </summary>
35
    /// <typeparam name="T"></typeparam>
36
    /// <param name="key"></param>
37
    /// <param name="value"></param>
38
    /// <returns></returns>
39
    private bool AddOrUpdateValueInternal<T>(string key, T value)
40
    {
41
        if (value == null)
3,646!
42
        {
43
            Remove(key);
×
44

45
            return true;
×
46
        }
47

48
        var type = value.GetType();
3,646✔
49

50
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
3,646!
51
            type = type.GenericTypeArguments.FirstOrDefault() ??
×
52
                   throw new ArgumentException($"Unable to retrieve type of Nullable {value}");
×
53

54

55
        if (type != typeof(string) &&
3,646!
56
            type != typeof(decimal) &&
3,646✔
57
            type != typeof(double) &&
3,646✔
58
            type != typeof(float) &&
3,646✔
59
            type != typeof(DateTime) &&
3,646✔
60
            type != typeof(Guid) &&
3,646✔
61
            type != typeof(bool) &&
3,646✔
62
            type != typeof(int) &&
3,646✔
63
            type != typeof(long) &&
3,646✔
64
            type != typeof(byte)) throw new ArgumentException($"Value of type {type.Name} is not supported.");
3,646!
65

66
        lock (_locker)
67
        {
68
            string str;
69

70
            switch (value)
71
            {
72
                case decimal:
73
                    return AddOrUpdateValue(key,
×
74
                        Convert.ToString(Convert.ToDecimal(value), System.Globalization.CultureInfo.InvariantCulture));
×
75
                case DateTime:
76
                    return AddOrUpdateValue(key,
×
77
                        Convert.ToString(-Convert.ToDateTime(value).ToUniversalTime().Ticks,
×
78
                            System.Globalization.CultureInfo.InvariantCulture));
×
79
                default:
80
                    str = Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture);
3,646✔
81
                    break;
82
            }
83

84
            string oldValue = null;
3,646✔
85

86
            if (_store.FileExists(key))
3,646✔
87
            {
88
                using var stream = _store.OpenFile(key, FileMode.Open);
3,534✔
89
                using var sr = new StreamReader(stream);
3,534✔
90
                oldValue = sr.ReadToEnd();
3,534✔
91
            }
92

93
            using (var stream = _store.OpenFile(key, FileMode.Create, FileAccess.Write))
3,646✔
94
            {
95
                using var sw = new StreamWriter(stream);
3,646✔
96
                sw.Write(str);
3,646✔
97
            }
98

99
            return oldValue != str;
3,646✔
100
        }
101
    }
3,646✔
102

103
    /// <summary>
104
    /// Get Value
105
    /// </summary>
106
    /// <typeparam name="T"></typeparam>
107
    /// <param name="key"></param>
108
    /// <param name="defaultValue"></param>
109
    /// <returns></returns>
110
    private T GetValueOrDefaultInternal<T>(string key, T defaultValue = default)
111
    {
112
        object value = null;
44,880✔
113
        lock (_locker)
114
        {
115
            try
116
            {
117
                string str = null;
44,880✔
118

119
                // If the key exists, retrieve the value.
120
                if (_store.FileExists(key))
44,880✔
121
                {
122
                    using var stream = _store.OpenFile(key, FileMode.Open);
380✔
123
                    using var sr = new StreamReader(stream);
380✔
124
                    str = sr.ReadToEnd();
380✔
125
                }
126

127
                if (str == null)
44,880✔
128
                    return defaultValue;
44,500✔
129

130
                var type = typeof(T);
380✔
131

132
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
380!
133
                    type = type.GenericTypeArguments.FirstOrDefault();
×
134

135
                if (type == typeof(string))
380✔
136
                {
137
                    value = str;
26✔
138
                }
139

140
                else if (type == typeof(decimal))
354!
141
                {
142
                    var savedDecimal = Convert.ToString(str);
×
143

144

145
                    value = Convert.ToDecimal(savedDecimal, System.Globalization.CultureInfo.InvariantCulture);
×
146

147
                    return (T)value;
×
148
                }
149

150
                else if (type == typeof(double))
354!
151
                {
152
                    value = Convert.ToDouble(str, System.Globalization.CultureInfo.InvariantCulture);
×
153
                }
154

155
                else if (type == typeof(float))
354!
156
                {
157
                    value = Convert.ToSingle(str, System.Globalization.CultureInfo.InvariantCulture);
×
158
                }
159

160
                else if (type == typeof(DateTime))
354!
161
                {
162
                    var ticks = Convert.ToInt64(str, System.Globalization.CultureInfo.InvariantCulture);
×
163
                    //Old value, stored before update to UTC values
164
                    value = ticks >= 0
×
165
                        ? new DateTime(ticks)
×
166
                        :
×
167
                        //New value, UTC
×
168
                        new DateTime(-ticks, DateTimeKind.Utc);
×
169

170

171
                    return (T)value;
×
172
                }
173

174
                else if (type == typeof(Guid))
354!
175
                {
176
                    if (Guid.TryParse(str, out var guid))
×
177
                        value = guid;
×
178
                }
179

180
                else if (type == typeof(bool))
354✔
181
                {
182
                    value = Convert.ToBoolean(str, System.Globalization.CultureInfo.InvariantCulture);
306✔
183
                }
184

185
                else if (type == typeof(int))
48!
186
                {
187
                    value = Convert.ToInt32(str, System.Globalization.CultureInfo.InvariantCulture);
48✔
188
                }
189

190
                else if (type == typeof(long))
×
191
                {
192
                    value = Convert.ToInt64(str, System.Globalization.CultureInfo.InvariantCulture);
×
193
                }
194

195
                else if (type == typeof(byte))
×
196
                {
197
                    value = Convert.ToByte(str, System.Globalization.CultureInfo.InvariantCulture);
×
198
                }
199

200
                else
201
                {
202
                    throw new ArgumentException($"Value of type {type} is not supported.");
×
203
                }
204
            }
380✔
205
            catch (FormatException)
×
206
            {
207
                return defaultValue;
×
208
            }
209
        }
210

211
        return null != value ? (T)value : defaultValue;
380!
212
    }
44,500✔
213

214
    /// <summary>
215
    /// Remove key
216
    /// </summary>
217
    /// <param name="key">Key to remove</param>
218
    public void Remove(string key)
219
    {
NEW
220
        if (_store.FileExists(key))
×
NEW
221
            _store.DeleteFile(key);
×
UNCOV
222
    }
×
223

224
    /// <summary>
225
    /// Clear all keys from settings
226
    /// </summary>
227
    public void Clear()
228
    {
229
        try
230
        {
231
            foreach (var file in _store.GetFileNames()) _store.DeleteFile(file);
274✔
232
        }
2✔
233
        catch (Exception ex)
×
234
        {
235
            Console.WriteLine($"Unable to clear all defaults. Message: {ex.Message}");
×
236
        }
×
237
    }
2✔
238

239
    /// <summary>
240
    /// Checks to see if the key has been added.
241
    /// </summary>
242
    /// <param name="key">Key to check</param>
243
    /// <returns>True if contains key, else false</returns>
NEW
244
    public bool Contains(string key) => _store.FileExists(key);
×
245

246
    #region GetValueOrDefault
247

248
    /// <summary>
249
    /// Gets the current value or the default that you specify.
250
    /// </summary>
251
    /// <param name="key">Key for settings</param>
252
    /// <param name="defaultValue">default value if not set</param>
253
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
254
    /// <returns>Value or default</returns>
255
    public decimal GetValueOrDefault(string key, decimal defaultValue, string fileName = null) =>
256
        GetValueOrDefaultInternal(key, defaultValue);
×
257

258
    /// <summary>
259
    /// Gets the current value or the default that you specify.
260
    /// </summary>
261
    /// <param name="key">Key for settings</param>
262
    /// <param name="defaultValue">default value if not set</param>
263
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
264
    /// <returns>Value or default</returns>
265
    public bool GetValueOrDefault(string key, bool defaultValue, string fileName = null) =>
266
        GetValueOrDefaultInternal(key, defaultValue);
43,180✔
267

268
    /// <summary>
269
    /// Gets the current value or the default that you specify.
270
    /// </summary>
271
    /// <param name="key">Key for settings</param>
272
    /// <param name="defaultValue">default value if not set</param>
273
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
274
    /// <returns>Value or default</returns>
275
    public long GetValueOrDefault(string key, long defaultValue, string fileName = null) =>
276
        GetValueOrDefaultInternal(key, defaultValue);
×
277

278
    /// <summary>
279
    /// Gets the current value or the default that you specify.
280
    /// </summary>
281
    /// <param name="key">Key for settings</param>
282
    /// <param name="defaultValue">default value if not set</param>
283
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
284
    /// <returns>Value or default</returns>
285
    public string GetValueOrDefault(string key, string defaultValue, string fileName = null) =>
286
        GetValueOrDefaultInternal(key, defaultValue);
116✔
287

288
    /// <summary>
289
    /// Gets the current value or the default that you specify.
290
    /// </summary>
291
    /// <param name="key">Key for settings</param>
292
    /// <param name="defaultValue">default value if not set</param>
293
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
294
    /// <returns>Value or default</returns>
295
    public int GetValueOrDefault(string key, int defaultValue, string fileName = null) =>
296
        GetValueOrDefaultInternal(key, defaultValue);
1,584✔
297

298
    /// <summary>
299
    /// Gets the current value or the default that you specify.
300
    /// </summary>
301
    /// <param name="key">Key for settings</param>
302
    /// <param name="defaultValue">default value if not set</param>
303
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
304
    /// <returns>Value or default</returns>
305
    public float GetValueOrDefault(string key, float defaultValue, string fileName = null) =>
306
        GetValueOrDefaultInternal(key, defaultValue);
×
307

308
    /// <summary>
309
    /// Gets the current value or the default that you specify.
310
    /// </summary>
311
    /// <param name="key">Key for settings</param>
312
    /// <param name="defaultValue">default value if not set</param>
313
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
314
    /// <returns>Value or default</returns>
315
    public DateTime GetValueOrDefault(string key, DateTime defaultValue, string fileName = null) =>
316
        GetValueOrDefaultInternal(key, defaultValue);
×
317

318
    /// <summary>
319
    /// Gets the current value or the default that you specify.
320
    /// </summary>
321
    /// <param name="key">Key for settings</param>
322
    /// <param name="defaultValue">default value if not set</param>
323
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
324
    /// <returns>Value or default</returns>
325
    public Guid GetValueOrDefault(string key, Guid defaultValue, string fileName = null) =>
326
        GetValueOrDefaultInternal(key, defaultValue);
×
327

328
    /// <summary>
329
    /// Gets the current value or the default that you specify.
330
    /// </summary>
331
    /// <param name="key">Key for settings</param>
332
    /// <param name="defaultValue">default value if not set</param>
333
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
334
    /// <returns>Value or default</returns>
335
    public double GetValueOrDefault(string key, double defaultValue, string fileName = null) =>
336
        GetValueOrDefaultInternal(key, defaultValue);
×
337

338
    #endregion
339

340
    #region AddOrUpdateValue
341

342
    /// <summary>
343
    /// Adds or updates the value
344
    /// </summary>
345
    /// <param name="key">Key for setting</param>
346
    /// <param name="value">Value to set</param>
347
    /// <returns>True of was added or updated and you need to save it.</returns>
348
    public bool AddOrUpdateValue(string key, decimal value) => AddOrUpdateValueInternal(key, value);
×
349

350
    /// <summary>
351
    /// Adds or updates the value
352
    /// </summary>
353
    /// <param name="key">Key for setting</param>
354
    /// <param name="value">Value to set</param>
355
    /// <returns>True of was added or updated and you need to save it.</returns>
356
    public bool AddOrUpdateValue(string key, bool value) => AddOrUpdateValueInternal(key, value);
274✔
357

358
    /// <summary>
359
    /// Adds or updates the value
360
    /// </summary>
361
    /// <param name="key">Key for setting</param>
362
    /// <param name="value">Value to set</param>
363
    /// <returns>True of was added or updated and you need to save it.</returns>
364
    public bool AddOrUpdateValue(string key, long value) => AddOrUpdateValueInternal(key, value);
×
365

366
    /// <summary>
367
    /// Adds or updates the value
368
    /// </summary>
369
    /// <param name="key">Key for setting</param>
370
    /// <param name="value">Value to set</param>
371
    /// <returns>True of was added or updated and you need to save it.</returns>
372
    public bool AddOrUpdateValue(string key, string value) => AddOrUpdateValueInternal(key, value);
240✔
373

374
    /// <summary>
375
    /// Adds or updates the value
376
    /// </summary>
377
    /// <param name="key">Key for setting</param>
378
    /// <param name="value">Value to set</param>
379
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
380
    /// <returns>True of was added or updated and you need to save it.</returns>
381
    public bool AddOrUpdateValue(string key, int value, string fileName = null) => AddOrUpdateValueInternal(key, value);
3,132✔
382

383
    /// <summary>
384
    /// Adds or updates the value
385
    /// </summary>
386
    /// <param name="key">Key for setting</param>
387
    /// <param name="value">Value to set</param>
388
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
389
    /// <returns>True of was added or updated and you need to save it.</returns>
390
    public bool AddOrUpdateValue(string key, float value, string fileName = null) =>
391
        AddOrUpdateValueInternal(key, value);
×
392

393
    /// <summary>
394
    /// Adds or updates the value
395
    /// </summary>
396
    /// <param name="key">Key for setting</param>
397
    /// <param name="value">Value to set</param>
398
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
399
    /// <returns>True of was added or updated and you need to save it.</returns>
400
    public bool AddOrUpdateValue(string key, DateTime value, string fileName = null) =>
401
        AddOrUpdateValueInternal(key, value);
×
402

403
    /// <summary>
404
    /// Adds or updates the value
405
    /// </summary>
406
    /// <param name="key">Key for setting</param>
407
    /// <param name="value">Value to set</param>
408
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
409
    /// <returns>True of was added or updated and you need to save it.</returns>
410
    public bool AddOrUpdateValue(string key, Guid value, string fileName = null) =>
411
        AddOrUpdateValueInternal(key, value);
×
412

413
    /// <summary>
414
    /// Adds or updates the value
415
    /// </summary>
416
    /// <param name="key">Key for setting</param>
417
    /// <param name="value">Value to set</param>
418
    /// <param name="fileName">Name of file for settings to be stored and retrieved </param>
419
    /// <returns>True of was added or updated and you need to save it.</returns>
420
    public bool AddOrUpdateValue(string key, double value, string fileName = null) =>
421
        AddOrUpdateValueInternal(key, value);
×
422

423
    #endregion
424
}
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