Skip to content

Commit 56414d5

Browse files
committed
Fix DSN construction for remote server connections
1 parent 00a2a2e commit 56414d5

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

src/firebird/driver/core.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,9 +2164,31 @@ def _connect_helper(dsn: str, host: str, port: str, database: str, protocol: Net
21642164
if protocol is not None:
21652165
dsn = f'{protocol.name.lower()}://'
21662166
if host and port:
2167-
dsn += f'{host}:{port}/'
2167+
dsn += f'{host}:{port}'
21682168
elif host:
2169-
dsn += f'{host}/'
2169+
dsn += host
2170+
# Add database path
2171+
# When there's a host, URLs need proper path formatting:
2172+
# - Unix absolute paths (start with '/') - need double slash to preserve the leading /
2173+
# because Firebird URL parsing strips one /
2174+
# - Windows absolute paths (contain ':') - concatenate directly without separator
2175+
# - Aliases/relative paths - need '/' separator
2176+
# When there's no host (loopback), the path is used as-is
2177+
if host:
2178+
# For URLs with host
2179+
if database.startswith('/'):
2180+
# Unix absolute path - use double slash so Firebird keeps the leading /
2181+
dsn += f'/{database}' # Results in inet://host//absolute/path
2182+
elif ':' in database: # Windows path (e.g., C:\...)
2183+
dsn += database # Concatenate directly without separator
2184+
else: # Relative/alias
2185+
dsn += f'/{database}'
2186+
else:
2187+
# Loopback - path is used as-is after ://
2188+
if database.startswith('/') or ':' in database:
2189+
dsn += database
2190+
else:
2191+
dsn += f'/{database}'
21702192
else:
21712193
dsn = ''
21722194
if host and host.startswith('\\\\'): # Windows Named Pipes
@@ -2178,7 +2200,7 @@ def _connect_helper(dsn: str, host: str, port: str, database: str, protocol: Net
21782200
dsn += f'{host}/{port}:'
21792201
elif host:
21802202
dsn += f'{host}:'
2181-
dsn += database
2203+
dsn += database
21822204
return dsn
21832205

21842206
def _is_dsn(value: str) -> bool:
@@ -2401,10 +2423,9 @@ def create_database(database: str | Path, *, user: str | None=None, password: st
24012423
if db_config is None:
24022424
db_config = driver_config.db_defaults
24032425
srv_config = driver_config.server_defaults
2404-
if _is_dsn(database):
2405-
dsn = database
2406-
database = None
2407-
srv_config.host.clear()
2426+
dsn = database
2427+
database = None
2428+
srv_config.host.clear()
24082429
else:
24092430
database = db_config.database.value
24102431
dsn = db_config.dsn.value

0 commit comments

Comments
 (0)