-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: Add .NET 8+ support for System.Data.Odbc #2948
base: main
Are you sure you want to change the base?
Changes from all commits
07c966d
c16edf3
651c811
2a36a03
644555a
e353db6
af4be95
33dac84
e45ad0d
54736ec
7d79957
2665f28
9528a60
3168149
82aaafe
7ac9299
235bbb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -156,5 +156,8 @@ | |
}, | ||
{ | ||
"packageName": "stackexchange.redis" | ||
}, | ||
{ | ||
"packageName": "system.data.odbc" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright 2020 New Relic, Inc. All rights reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
using NewRelic.Agent.Helpers; | ||
using System.Collections.Generic; | ||
using System.Data.Common; | ||
using System.Linq; | ||
|
||
namespace NewRelic.Agent.Extensions.Parsing.ConnectionString | ||
{ | ||
public class OdbcConnectionStringParser : IConnectionStringParser | ||
{ | ||
private static readonly List<string> _hostKeys = new List<string> { "server", "data source", "hostname" }; | ||
private static readonly List<string> _portKeys = new List<string> { "port" }; | ||
private static readonly List<string> _databaseNameKeys = new List<string> { "database" }; | ||
|
||
private readonly DbConnectionStringBuilder _connectionStringBuilder; | ||
|
||
public OdbcConnectionStringParser(string connectionString) | ||
{ | ||
_connectionStringBuilder = new DbConnectionStringBuilder { ConnectionString = connectionString }; | ||
} | ||
|
||
public ConnectionInfo GetConnectionInfo(string utilizationHostName) | ||
{ | ||
var host = ParseHost(); | ||
if (host != null) host = ConnectionStringParserHelper.NormalizeHostname(host, utilizationHostName); | ||
var portPathOrId = ParsePortPathOrId(); | ||
var databaseName = ConnectionStringParserHelper.GetKeyValuePair(_connectionStringBuilder, _databaseNameKeys)?.Value; | ||
var instanceName = ParseInstanceName(); | ||
return new ConnectionInfo(host, portPathOrId, databaseName, instanceName); | ||
} | ||
|
||
private string ParseHost() | ||
{ | ||
var host = ConnectionStringParserHelper.GetKeyValuePair(_connectionStringBuilder, _hostKeys)?.Value; | ||
if (host == null) return null; | ||
|
||
// Example of want we would need to process: win-database.pdx.vm.datanerd.us,1433\SQLEXPRESS | ||
try | ||
{ | ||
var splitIndex = host.IndexOf(StringSeparators.CommaChar); | ||
if (splitIndex == -1) splitIndex = host.IndexOf(StringSeparators.BackslashChar); | ||
host = splitIndex == -1 ? host : host.Substring(0, splitIndex); | ||
} | ||
catch | ||
{ | ||
return null; | ||
} | ||
var endOfHostname = host.IndexOf(StringSeparators.ColonChar); | ||
return endOfHostname == -1 ? host : host.Substring(0, endOfHostname); | ||
} | ||
|
||
private string ParsePortPathOrId() | ||
{ | ||
// Some ODBC drivers use the "port" key to specify the port number | ||
var portPathOrId = ConnectionStringParserHelper.GetKeyValuePair(_connectionStringBuilder, _portKeys)?.Value; | ||
if (!string.IsNullOrWhiteSpace(portPathOrId)) | ||
{ | ||
return portPathOrId; | ||
|
||
} | ||
|
||
// Some ODBC drivers include the port in the "server" or "data source" key | ||
portPathOrId = ConnectionStringParserHelper.GetKeyValuePair(_connectionStringBuilder, _hostKeys)?.Value; | ||
if (portPathOrId == null) return null; | ||
|
||
try | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here. I'm not seeing any execution path where an exception could be thrown. |
||
{ | ||
if (portPathOrId.IndexOf(StringSeparators.ColonChar) != -1) | ||
{ | ||
var startOfValue = portPathOrId.IndexOf(StringSeparators.ColonChar) + 1; | ||
var endOfValue = portPathOrId.Length; | ||
return (startOfValue > 0) ? portPathOrId.Substring(startOfValue, endOfValue - startOfValue) : null; | ||
} | ||
if (portPathOrId.IndexOf(StringSeparators.CommaChar) != -1) | ||
{ | ||
var startOfValue = portPathOrId.IndexOf(StringSeparators.CommaChar) + 1; | ||
var endOfValue = portPathOrId.Contains(StringSeparators.BackslashChar) | ||
? portPathOrId.IndexOf(StringSeparators.BackslashChar) | ||
: portPathOrId.Length; | ||
return (startOfValue > 0) ? portPathOrId.Substring(startOfValue, endOfValue - startOfValue) : null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ternary here (and on line 74 above) isn't necessary -- |
||
} | ||
} | ||
catch | ||
{ | ||
return null; | ||
} | ||
|
||
return "default"; | ||
} | ||
|
||
private string ParseInstanceName() | ||
{ | ||
var instanceName = ConnectionStringParserHelper.GetKeyValuePair(_connectionStringBuilder, _hostKeys)?.Value; | ||
if (instanceName == null) return null; | ||
|
||
try | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary try/catch here also |
||
{ | ||
if (instanceName.IndexOf(StringSeparators.BackslashChar) != -1) | ||
{ | ||
var startOfValue = instanceName.IndexOf(StringSeparators.BackslashChar) + 1; | ||
var endOfValue = instanceName.Length; | ||
return (startOfValue > 0) ? instanceName.Substring(startOfValue, endOfValue - startOfValue) : null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ternary here is also unnecessary. |
||
} | ||
} | ||
catch | ||
{ | ||
return null; | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,7 @@ public enum DatastoreVendor | |
CosmosDB, | ||
Elasticsearch, | ||
DynamoDB, | ||
ODBC, | ||
Other | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This try/catch block seems unnecessary. Looks like the code is already handling all the edge cases that are possible.