-
Notifications
You must be signed in to change notification settings - Fork 27
FEAT: Improved Connection String handling in Python #307
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
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
12b910e
Spec for the changes
392e64f
Initial changes
3bdc632
Merge remote-tracking branch 'origin/main' into connection_string_all…
f47b214
Remove special characters
1cb96d5
Reomve driver name from pipelines
cba7ff5
Remove markdowns
feef9bb
Refactor connection string handling by consolidating reserved paramet…
264f877
Enhance connection string allow-list by updating parameter synonyms a…
35d55d5
Refactor connection string handling by normalizing parameter names an…
2d5498b
Refactor connection string handling: rename ConnectionStringAllowList…
fa126d9
Refactor connection string handling: remove unused has_param method a…
e6fcea7
Enhance connection string allow-list: add snake_case synonyms and upd…
08d2adb
Enhance connection string allow-list: update packet size parameter to…
a4d4ae0
Docs take too long to render in CR
saurabh500 40140cb
Remove implementation and parser changes summaries for connection str…
saurabh500 9a20195
Update tests/test_012_connection_string_integration.py
saurabh500 280e0e3
CHORE: Remove unused imports from connection string modules
saurabh500 3904340
Merge remote-tracking branch 'origin/main' into saurabh/connection_st…
saurabh500 3e6fb27
Remove unused
saurabh500 c28eaf9
REFACTOR: Move connection string allowlist to constants module
saurabh500 2593057
Merge branch 'main' into saurabh/connection_string_allow_list
saurabh500 5043f8e
Merge branch 'main' into saurabh/connection_string_allow_list
saurabh500 f46ec1c
Add full type hints to connection string methods
saurabh500 b597d31
REFAC: Update connection string handling by consolidating allowlist l…
saurabh500 cb5e5e5
Merge branch 'main' into saurabh/connection_string_allow_list
saurabh500 dd2d07d
Simplify logger imports
saurabh500 d14a758
Merge branch 'main' into saurabh/connection_string_allow_list
saurabh500 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| """ | ||
| Copyright (c) Microsoft Corporation. | ||
| Licensed under the MIT license. | ||
|
|
||
| Connection string builder for mssql-python. | ||
|
|
||
| Reconstructs ODBC connection strings from parameter dictionaries | ||
| with proper escaping and formatting per MS-ODBCSTR specification. | ||
| """ | ||
|
|
||
| from typing import Dict, Optional | ||
| from mssql_python.constants import _CONNECTION_STRING_DRIVER_KEY | ||
|
|
||
| class _ConnectionStringBuilder: | ||
| """ | ||
| Internal builder for ODBC connection strings. Not part of public API. | ||
|
|
||
| Handles proper escaping of special characters and reconstructs | ||
| connection strings in ODBC format. | ||
| """ | ||
|
|
||
| def __init__(self, initial_params: Optional[Dict[str, str]] = None): | ||
| """ | ||
| Initialize the builder with optional initial parameters. | ||
|
|
||
| Args: | ||
| initial_params: Dictionary of initial connection parameters | ||
| """ | ||
| self._params: Dict[str, str] = initial_params.copy() if initial_params else {} | ||
|
|
||
| def add_param(self, key: str, value: str) -> '_ConnectionStringBuilder': | ||
| """ | ||
| Add or update a connection parameter. | ||
|
|
||
| Args: | ||
| key: Parameter name (should be normalized canonical name) | ||
| value: Parameter value | ||
|
|
||
| Returns: | ||
| Self for method chaining | ||
| """ | ||
| self._params[key] = str(value) | ||
| return self | ||
|
|
||
| def build(self) -> str: | ||
| """ | ||
| Build the final connection string. | ||
|
|
||
| Returns: | ||
| ODBC-formatted connection string with proper escaping | ||
|
|
||
| Note: | ||
| - Driver parameter is placed first | ||
| - Other parameters are sorted for consistency | ||
| - Values are escaped if they contain special characters | ||
| """ | ||
| parts = [] | ||
|
|
||
| # Build in specific order: Driver first, then others | ||
| if _CONNECTION_STRING_DRIVER_KEY in self._params: | ||
| parts.append(f"Driver={self._escape_value(self._params['Driver'])}") | ||
|
|
||
| # Add other parameters (sorted for consistency) | ||
| for key in sorted(self._params.keys()): | ||
| if key == 'Driver': | ||
| continue # Already added | ||
|
|
||
| value = self._params[key] | ||
| escaped_value = self._escape_value(value) | ||
| parts.append(f"{key}={escaped_value}") | ||
|
|
||
| # Join with semicolons | ||
| return ';'.join(parts) | ||
|
|
||
| def _escape_value(self, value: str) -> str: | ||
| """ | ||
| Escape a parameter value if it contains special characters. | ||
|
|
||
| Per MS-ODBCSTR specification: | ||
| - Values containing ';', '{', '}', '=', or spaces should be braced for safety | ||
| - '}' inside braced values is escaped as '}}' | ||
| - '{' inside braced values is escaped as '{{' | ||
|
|
||
| Args: | ||
| value: Parameter value to escape | ||
|
|
||
| Returns: | ||
| Escaped value (possibly wrapped in braces) | ||
|
|
||
| Examples: | ||
| >>> builder = _ConnectionStringBuilder() | ||
| >>> builder._escape_value("localhost") | ||
| 'localhost' | ||
Check noticeCode scanning / devskim Accessing localhost could indicate debug code, or could hinder scaling. Note
Do not leave debug code in production
|
||
| >>> builder._escape_value("local;host") | ||
| '{local;host}' | ||
| >>> builder._escape_value("p}w{d") | ||
| '{p}}w{{d}' | ||
| >>> builder._escape_value("ODBC Driver 18 for SQL Server") | ||
| '{ODBC Driver 18 for SQL Server}' | ||
| """ | ||
| if not value: | ||
| return value | ||
|
|
||
| # Check if value contains special characters that require bracing | ||
| # Include spaces and = for safety, even though technically not always required | ||
| needs_braces = any(ch in value for ch in ';{}= ') | ||
|
|
||
| if needs_braces: | ||
| # Escape existing braces by doubling them | ||
| escaped = value.replace('}', '}}').replace('{', '{{') | ||
| return f'{{{escaped}}}' | ||
| else: | ||
| return value | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.