Unified · Split
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | <FileAlignment>512</FileAlignment> | 15 | <FileAlignment>512</FileAlignment> |
| 16 | <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | 16 | <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
| 17 | <WarningLevel>4</WarningLevel> | 17 | <WarningLevel>4</WarningLevel> |
| 18 | <LangVersion>9</LangVersion> | ||
| 18 | </PropertyGroup> | 19 | </PropertyGroup> |
| 19 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | 20 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
| 20 | <DebugSymbols>true</DebugSymbols> | 21 | <DebugSymbols>true</DebugSymbols> |
| @@ -95,7 +95,7 @@ namespace GSF.TimeSeries.UI.UserControls · 94 unmodified lines | |||
| 95 | private void DataGridEnabledCheckBox_Click(object sender, RoutedEventArgs e) | 95 | private void DataGridEnabledCheckBox_Click(object sender, RoutedEventArgs e) |
| 96 | { | 96 | { |
| 97 | // Get a reference to the enabled checkbox that was clicked | 97 | // Get a reference to the enabled checkbox that was clicked |
| 98 | if (!(sender is CheckBox enabledCheckBox)) | 98 | if (sender is not CheckBox enabledCheckBox) |
| 99 | return; | 99 | return; |
| 100 | 100 | ||
| 101 | // Get the runtime ID of the currently selected adapter | 101 | // Get the runtime ID of the currently selected adapter |
| @@ -143,7 +143,7 @@ namespace GSF.TimeSeries.UI.UserControls · 41 unmodified lines | |||
| 143 | /// <param name="e">Arguments for the event.</param> | 143 | /// <param name="e">Arguments for the event.</param> |
| 144 | private void Default_Click(object sender, RoutedEventArgs e) | 144 | private void Default_Click(object sender, RoutedEventArgs e) |
| 145 | { | 145 | { |
| 146 | if (!(DataContext is ViewModels.Adapters dataContext) || dataContext.SelectedParameter is null) | 146 | if (DataContext is not ViewModels.Adapters dataContext || dataContext.SelectedParameter is null) |
| 147 | return; | 147 | return; |
| 148 | 148 | ||
| 149 | Dictionary<string, string> settings = dataContext.CurrentItem.ConnectionString.ToNonNullString().ParseKeyValuePairs(); | 149 | Dictionary<string, string> settings = dataContext.CurrentItem.ConnectionString.ToNonNullString().ParseKeyValuePairs(); |
| @@ -177,13 +177,15 @@ namespace GSF.TimeSeries.UI.ViewModels · 176 unmodified lines | |||
| 177 | ((Enum)Enum.Parse(m_info.PropertyType, Value.ToString(), true)).GetDescription(false) : | 177 | ((Enum)Enum.Parse(m_info.PropertyType, Value.ToString(), true)).GetDescription(false) : |
| 178 | null; | 178 | null; |
| 179 | } | 179 | } |
| 180 | #if DEBUG | ||
| 180 | catch (Exception ex) | 181 | catch (Exception ex) |
| 181 | { | 182 | { |
| 182 | #if DEBUG | ||
| 183 | return ex.Message; | 183 | return ex.Message; |
| 184 | #else | 184 | #else |
| 185 | catch | ||
| 186 | { | ||
| 185 | return null; | 187 | return null; |
| 186 | #endif | 188 | #endif |
| 187 | } | 189 | } |
| 188 | } | 190 | } |
| 189 | set { } | 191 | set { } |
| @@ -227,7 +229,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 37 unmodified lines | |||
| 227 | { | 229 | { |
| 228 | try | 230 | try |
| 229 | { | 231 | { |
| 230 | return !(m_info?.GetCustomAttribute<CustomConfigurationEditorAttribute>() is null); | 232 | return m_info?.GetCustomAttribute<CustomConfigurationEditorAttribute>() is not null; |
| 231 | } | 233 | } |
| 232 | catch | 234 | catch |
| 233 | { | 235 | { |
| @@ -244,12 +244,12 @@ namespace GSF.TimeSeries.UI.ViewModels · 243 unmodified lines | |||
| 244 | get => m_selectedParameter; | 244 | get => m_selectedParameter; |
| 245 | set | 245 | set |
| 246 | { | 246 | { |
| 247 | if (!(m_selectedParameter is null)) | 247 | if (m_selectedParameter is not null) |
| 248 | m_selectedParameter.PropertyChanged -= ConnectionStringParameter_PropertyChanged; | 248 | m_selectedParameter.PropertyChanged -= ConnectionStringParameter_PropertyChanged; |
| 249 | 249 | ||
| 250 | m_selectedParameter = value; | 250 | m_selectedParameter = value; |
| 251 | 251 | ||
| 252 | if (!(m_selectedParameter is null)) | 252 | if (m_selectedParameter is not null) |
| 253 | m_selectedParameter.PropertyChanged += ConnectionStringParameter_PropertyChanged; | 253 | m_selectedParameter.PropertyChanged += ConnectionStringParameter_PropertyChanged; |
| 254 | 254 | ||
| 255 | OnPropertyChanged("SelectedParameter"); | 255 | OnPropertyChanged("SelectedParameter"); |
| @@ -310,7 +310,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 54 unmodified lines | |||
| 310 | { | 310 | { |
| 311 | ItemsKeys = Adapter.LoadIDs(null, m_adapterType, SortMember, SortDirection); | 311 | ItemsKeys = Adapter.LoadIDs(null, m_adapterType, SortMember, SortDirection); |
| 312 | 312 | ||
| 313 | if (!(SortSelector is null)) | 313 | if (SortSelector is not null) |
| 314 | { | 314 | { |
| 315 | ItemsKeys = SortDirection == "ASC" ? | 315 | ItemsKeys = SortDirection == "ASC" ? |
| 316 | ItemsKeys.OrderBy(SortSelector).ToList() : | 316 | ItemsKeys.OrderBy(SortSelector).ToList() : |
| @@ -404,7 +404,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 87 unmodified lines | |||
| 404 | .Select(tuple => tuple.Item1) | 404 | .Select(tuple => tuple.Item1) |
| 405 | .SingleOrDefault(type => type.FullName == CurrentItem.TypeName); | 405 | .SingleOrDefault(type => type.FullName == CurrentItem.TypeName); |
| 406 | 406 | ||
| 407 | if (!(selectedType is null)) | 407 | if (selectedType is not null) |
| 408 | { | 408 | { |
| 409 | string pattern = Regex.Escape(FilePath.GetAbsolutePath("").EnsureEnd(Path.DirectorySeparatorChar)); | 409 | string pattern = Regex.Escape(FilePath.GetAbsolutePath("").EnsureEnd(Path.DirectorySeparatorChar)); |
| 410 | CurrentItem.AssemblyName = Regex.Replace(selectedType.Assembly.Location, $"^{pattern}", "", RegexOptions.IgnoreCase); | 410 | CurrentItem.AssemblyName = Regex.Replace(selectedType.Assembly.Location, $"^{pattern}", "", RegexOptions.IgnoreCase); |
| @@ -441,7 +441,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 30 unmodified lines | |||
| 441 | /// <param name="e">Event arguments.</param> | 441 | /// <param name="e">Event arguments.</param> |
| 442 | protected virtual void ConnectionStringParameter_PropertyChanged(object sender, PropertyChangedEventArgs e) | 442 | protected virtual void ConnectionStringParameter_PropertyChanged(object sender, PropertyChangedEventArgs e) |
| 443 | { | 443 | { |
| 444 | if (m_suppressConnectionStringUpdates || !(sender is AdapterConnectionStringParameter parameter) || parameter.Value is null || e.PropertyName != "Value") | 444 | if (m_suppressConnectionStringUpdates || sender is not AdapterConnectionStringParameter parameter || parameter.Value is null || e.PropertyName != "Value") |
| 445 | return; | 445 | return; |
| 446 | 446 | ||
| 447 | try | 447 | try |
| @@ -624,7 +624,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 176 unmodified lines | |||
| 624 | /// </returns> | 624 | /// </returns> |
| 625 | private List<AdapterConnectionStringParameter> GetParameterList(string assemblyName, string typeName) | 625 | private List<AdapterConnectionStringParameter> GetParameterList(string assemblyName, string typeName) |
| 626 | { | 626 | { |
| 627 | if (!(assemblyName is null) && !(typeName is null)) | 627 | if (assemblyName is not null && typeName is not null) |
| 628 | { | 628 | { |
| 629 | // For convenience, start by searching the type | 629 | // For convenience, start by searching the type |
| 630 | // list for a type matching the parameters. | 630 | // list for a type matching the parameters. |
| @@ -637,7 +637,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 6 unmodified lines | |||
| 637 | if (adapterType is null && File.Exists(assemblyName)) | 637 | if (adapterType is null && File.Exists(assemblyName)) |
| 638 | adapterType = Assembly.LoadFrom(assemblyName).GetType(typeName); | 638 | adapterType = Assembly.LoadFrom(assemblyName).GetType(typeName); |
| 639 | 639 | ||
| 640 | if (!(adapterType is null)) | 640 | if (adapterType is not null) |
| 641 | { | 641 | { |
| 642 | // Get the list of properties with ConnectionStringParameterAttribute annotations. | 642 | // Get the list of properties with ConnectionStringParameterAttribute annotations. |
| 643 | IEnumerable<PropertyInfo> infoList = adapterType.GetProperties() | 643 | IEnumerable<PropertyInfo> infoList = adapterType.GetProperties() |
| @@ -686,7 +686,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 42 unmodified lines | |||
| 686 | object defaultValue = null; | 686 | object defaultValue = null; |
| 687 | string description = null; | 687 | string description = null; |
| 688 | 688 | ||
| 689 | if (!(m_parameterList is null)) | 689 | if (m_parameterList is not null) |
| 690 | parameter = m_parameterList.SingleOrDefault(param => param.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase)); | 690 | parameter = m_parameterList.SingleOrDefault(param => param.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase)); |
| 691 | 691 | ||
| 692 | // These are different cases, but we need to extract the description | 692 | // These are different cases, but we need to extract the description |
| @@ -733,7 +733,7 @@ namespace GSF.TimeSeries.UI.ViewModels · 40 unmodified lines | |||
| 733 | { | 733 | { |
| 734 | AdapterConnectionStringParameter parameter = null; | 734 | AdapterConnectionStringParameter parameter = null; |
| 735 | 735 | ||
| 736 | if (!(m_parameterList is null)) | 736 | if (m_parameterList is not null) |
| 737 | parameter = m_parameterList.SingleOrDefault(param => param.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); | 737 | parameter = m_parameterList.SingleOrDefault(param => param.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); |
| 738 | 738 | ||
| 739 | return parameter ?? new AdapterConnectionStringParameter() | 739 | return parameter ?? new AdapterConnectionStringParameter() |
| @@ -32,10 +32,11 @@ using System.Security.Claims; · 31 unmodified lines | |||
| 32 | using System.Web.Http; | 32 | using System.Web.Http; |
| 33 | using GSF.Data; | 33 | using GSF.Data; |
| 34 | using GSF.Data.Model; | 34 | using GSF.Data.Model; |
| 35 | using GSF.Reflection; | ||
| 36 | using Newtonsoft.Json; | 35 | using Newtonsoft.Json; |
| 37 | using Newtonsoft.Json.Linq; | 36 | using Newtonsoft.Json.Linq; |
| 38 | 37 | ||
| 38 | #pragma warning disable CS1591 // TODO: Fix missing XML comments for publicly visible types and members | ||
| 39 | |||
| 39 | namespace GSF.Web.Model | 40 | namespace GSF.Web.Model |
| 40 | { | 41 | { |
| 41 | /// <summary> | 42 | /// <summary> |
| @@ -45,6 +46,7 @@ namespace GSF.Web.Model · 3 unmodified lines | |||
| 45 | public class ModelController<T> : ApiController where T : class, new() | 46 | public class ModelController<T> : ApiController where T : class, new() |
| 46 | { | 47 | { |
| 47 | #region [ Members ] | 48 | #region [ Members ] |
| 49 | |||
| 48 | /// <summary> | 50 | /// <summary> |
| 49 | /// Class Providing Search Parameters for the Search Endpoints | 51 | /// Class Providing Search Parameters for the Search Endpoints |
| 50 | /// </summary> | 52 | /// </summary> |
| @@ -223,10 +225,10 @@ namespace GSF.Web.Model · 172 unmodified lines | |||
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | /// <summary> | 227 | /// <summary> |
| 226 | /// Gets record from associated table with a primary key matching the id provided | 228 | /// Gets record from associated table with a primary key matching the <paramref name="id"/> provided. |
| 227 | /// </summary> | 229 | /// </summary> |
| 228 | /// <param name="id">ID to be used</param> | 230 | /// <param name="id">ID to be used</param> |
| 229 | /// <returns><see cref="IHttpActionResult"/> containing <see cref="T"/> or <see cref="Exception"/></returns> | 231 | /// <returns><see cref="IHttpActionResult"/> containing <typeparamref name="T"/> or <see cref="Exception"/></returns> |
| 230 | [HttpGet, Route("One/{id}")] | 232 | [HttpGet, Route("One/{id}")] |
| 231 | public virtual IHttpActionResult GetOne(string id) | 233 | public virtual IHttpActionResult GetOne(string id) |
| 232 | { | 234 | { |
| @@ -266,7 +268,7 @@ namespace GSF.Web.Model · 33 unmodified lines | |||
| 266 | } | 268 | } |
| 267 | 269 | ||
| 268 | /// <summary> | 270 | /// <summary> |
| 269 | /// Gets a sorted list of <see cref="T"/>. | 271 | /// Gets a sorted list of <typeparamref name="T"/>. |
| 270 | /// </summary> | 272 | /// </summary> |
| 271 | /// <param name="sort"> the Field to be sorted by.</param> | 273 | /// <param name="sort"> the Field to be sorted by.</param> |
| 272 | /// <param name="ascending"> parameter to indicate whether the list is in ascending order.</param> | 274 | /// <param name="ascending"> parameter to indicate whether the list is in ascending order.</param> |
| @@ -345,7 +347,7 @@ namespace GSF.Web.Model · 72 unmodified lines | |||
| 345 | /// <summary> | 347 | /// <summary> |
| 346 | /// Adds a new Record. | 348 | /// Adds a new Record. |
| 347 | /// </summary> | 349 | /// </summary> |
| 348 | /// <param name="record"> The <see cref="T"/> record to be added.</param> | 350 | /// <param name="record"> The <typeparamref name="T"/> record to be added.</param> |
| 349 | /// <returns><see cref="IHttpActionResult"/> containing the added record or <see cref="Exception"/> </returns> | 351 | /// <returns><see cref="IHttpActionResult"/> containing the added record or <see cref="Exception"/> </returns> |
| 350 | [HttpPost, Route("Add")] | 352 | [HttpPost, Route("Add")] |
| 351 | public virtual IHttpActionResult Post([FromBody] JObject record) | 353 | public virtual IHttpActionResult Post([FromBody] JObject record) |
| @@ -378,7 +380,7 @@ namespace GSF.Web.Model · 26 unmodified lines | |||
| 378 | /// <summary> | 380 | /// <summary> |
| 379 | /// Updates an existing Record. | 381 | /// Updates an existing Record. |
| 380 | /// </summary> | 382 | /// </summary> |
| 381 | /// <param name="record"> The <see cref="T"/> record to be updated.</param> | 383 | /// <param name="record"> The <typeparamref name="T"/> record to be updated.</param> |
| 382 | /// <returns><see cref="IHttpActionResult"/> containing the updated record or <see cref="Exception"/> </returns> | 384 | /// <returns><see cref="IHttpActionResult"/> containing the updated record or <see cref="Exception"/> </returns> |
| 383 | 385 | ||
| 384 | [HttpPatch, Route("Update")] | 386 | [HttpPatch, Route("Update")] |
| @@ -424,7 +426,7 @@ namespace GSF.Web.Model · 39 unmodified lines | |||
| 424 | /// <summary> | 426 | /// <summary> |
| 425 | /// Deletes an existing Record. | 427 | /// Deletes an existing Record. |
| 426 | /// </summary> | 428 | /// </summary> |
| 427 | /// <param name="record"> The <see cref="T"/> record to be deleted.</param> | 429 | /// <param name="record"> The <typeparamref name="T"/> record to be deleted.</param> |
| 428 | /// <returns><see cref="IHttpActionResult"/> containing the number of records deleted or <see cref="Exception"/> </returns> | 430 | /// <returns><see cref="IHttpActionResult"/> containing the number of records deleted or <see cref="Exception"/> </returns> |
| 429 | 431 | ||
| 430 | [HttpDelete, Route("Delete")] | 432 | [HttpDelete, Route("Delete")] |
| @@ -481,7 +483,7 @@ namespace GSF.Web.Model · 50 unmodified lines | |||
| 481 | } | 483 | } |
| 482 | 484 | ||
| 483 | /// <summary> | 485 | /// <summary> |
| 484 | /// Gets all records from associated table, filtered and sorted as defined in <see cref="postData"/>. | 486 | /// Gets all records from associated table, filtered and sorted as defined in <paramref name="postData"/>. |
| 485 | /// </summary> | 487 | /// </summary> |
| 486 | /// <param name="postData"><see cref="PostData"/> containing the search and sort parameters</param> | 488 | /// <param name="postData"><see cref="PostData"/> containing the search and sort parameters</param> |
| 487 | /// <returns><see cref="IHttpActionResult"/> containing <see cref="IEnumerable{T}"/> or <see cref="Exception"/></returns> | 489 | /// <returns><see cref="IHttpActionResult"/> containing <see cref="IEnumerable{T}"/> or <see cref="Exception"/></returns> |
| @@ -733,7 +735,7 @@ namespace GSF.Web.Model · 245 unmodified lines | |||
| 733 | SELECT | 735 | SELECT |
| 734 | SRC.*, | 736 | SRC.*, |
| 735 | ''AFV_'' + AF.{SearchSettings.FieldKeyField} AS AFFieldKey, | 737 | ''AFV_'' + AF.{SearchSettings.FieldKeyField} AS AFFieldKey, |
| 736 | AF.{SearchSettings.ValueField} AS AFValue | 738 | AF.{SearchSettings.ValueField} AS AFValue |
| 737 | FROM {tableName} SRC LEFT JOIN | 739 | FROM {tableName} SRC LEFT JOIN |
| 738 | {SearchSettings.AdditionalFieldTable} AF ON {joinCondition} | 740 | {SearchSettings.AdditionalFieldTable} AF ON {joinCondition} |
| 739 | ) as FullTbl ' + (SELECT CASE WHEN Len(@PivotColumns) > 0 THEN 'PIVOT ( | 741 | ) as FullTbl ' + (SELECT CASE WHEN Len(@PivotColumns) > 0 THEN 'PIVOT ( |
| @@ -743,9 +745,9 @@ namespace GSF.Web.Model · 3 unmodified lines | |||
| 743 | DECLARE @NoNPivotColumns NVARCHAR(MAX) = N'''' | 745 | DECLARE @NoNPivotColumns NVARCHAR(MAX) = N'''' |
| 744 | SELECT @NoNPivotColumns = @NoNPivotColumns + ''[''+ name + ''],'' | 746 | SELECT @NoNPivotColumns = @NoNPivotColumns + ''[''+ name + ''],'' |
| 745 | FROM tempdb.sys.columns WHERE object_id = Object_id(''tempdb..#Tbl'') AND name NOT LIKE ''AFV%''; | 747 | FROM tempdb.sys.columns WHERE object_id = Object_id(''tempdb..#Tbl'') AND name NOT LIKE ''AFV%''; |
| 746 | DECLARE @CleanSQL NVARCHAR(MAX) = N''SELECT '' + SUBSTRING(@NoNPivotColumns,0, LEN(@NoNPivotColumns)) + ''FROM #Tbl ORDER BY { postData.OrderBy} {(postData.Ascending ? "ASC" : "DESC")}'' | 748 | DECLARE @CleanSQL NVARCHAR(MAX) = N''SELECT '' + SUBSTRING(@NoNPivotColumns,0, LEN(@NoNPivotColumns)) + ''FROM #Tbl ORDER BY { postData.OrderBy} {(postData.Ascending ? "ASC" : "DESC")}'' |
| 747 | 749 | ||
| 748 | exec sp_executesql @CleanSQL | 750 | exec sp_executesql @CleanSQL |
| 749 | ' | 751 | ' |
| 750 | exec sp_executesql @SQLStatement"; | 752 | exec sp_executesql @SQLStatement"; |
| 751 | else | 753 | else |
| @@ -759,7 +761,7 @@ namespace GSF.Web.Model · 7 unmodified lines | |||
| 759 | SELECT | 761 | SELECT |
| 760 | SRC.*, | 762 | SRC.*, |
| 761 | ''AFV_'' + AF.{SearchSettings.FieldKeyField} AS AFFieldKey, | 763 | ''AFV_'' + AF.{SearchSettings.FieldKeyField} AS AFFieldKey, |
| 762 | AF.{SearchSettings.ValueField} AS AFValue | 764 | AF.{SearchSettings.ValueField} AS AFValue |
| 763 | FROM ({CustomView.Replace("'", "''")}) SRC LEFT JOIN | 765 | FROM ({CustomView.Replace("'", "''")}) SRC LEFT JOIN |
| 764 | {SearchSettings.AdditionalFieldTable} AF ON {joinCondition} | 766 | {SearchSettings.AdditionalFieldTable} AF ON {joinCondition} |
| 765 | ) as FullTbl ' + (SELECT CASE WHEN Len(@PivotColumns) > 0 THEN 'PIVOT ( | 767 | ) as FullTbl ' + (SELECT CASE WHEN Len(@PivotColumns) > 0 THEN 'PIVOT ( |
| @@ -769,9 +771,9 @@ namespace GSF.Web.Model · 3 unmodified lines | |||
| 769 | DECLARE @NoNPivotColumns NVARCHAR(MAX) = N'''' | 771 | DECLARE @NoNPivotColumns NVARCHAR(MAX) = N'''' |
| 770 | SELECT @NoNPivotColumns = @NoNPivotColumns + ''[''+ name + ''],'' | 772 | SELECT @NoNPivotColumns = @NoNPivotColumns + ''[''+ name + ''],'' |
| 771 | FROM tempdb.sys.columns WHERE object_id = Object_id(''tempdb..#Tbl'') AND name NOT LIKE ''AFV%''; | 773 | FROM tempdb.sys.columns WHERE object_id = Object_id(''tempdb..#Tbl'') AND name NOT LIKE ''AFV%''; |
| 772 | DECLARE @CleanSQL NVARCHAR(MAX) = N''SELECT '' + SUBSTRING(@NoNPivotColumns,0, LEN(@NoNPivotColumns)) + ''FROM #Tbl ORDER BY { postData.OrderBy} {(postData.Ascending ? "ASC" : "DESC")}'' | 774 | DECLARE @CleanSQL NVARCHAR(MAX) = N''SELECT '' + SUBSTRING(@NoNPivotColumns,0, LEN(@NoNPivotColumns)) + ''FROM #Tbl ORDER BY { postData.OrderBy} {(postData.Ascending ? "ASC" : "DESC")}'' |
| 773 | 775 | ||
| 774 | exec sp_executesql @CleanSQL | 776 | exec sp_executesql @CleanSQL |
| 775 | ' | 777 | ' |
| 776 | exec sp_executesql @SQLStatement"; | 778 | exec sp_executesql @SQLStatement"; |
| 777 | } | 779 | } |