Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions lib/features/connections/connection_default_name.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// The name a connection gets when the user leaves the name field empty.
///
/// With a URI the name comes from the URI's host and port, not from the
/// form's host field (which a URI overrides): `Redis: cache.example.com:6380`.
/// The port is the URI's, else [defaultPort]; a `+srv` URI has none. A URI
/// without a host (a multi-host replica set list, a malformed one) gives
/// `Redis (URI)`. Without a URI the name is [fields]:
/// `Redis localhost:6379`.
String defaultConnectionName({
required String label,
required int defaultPort,
required String uri,
required String fields,
}) {
final text = uri.trim();
if (text.isEmpty) return fields;
final parsed = Uri.tryParse(text);
if (parsed == null || parsed.host.isEmpty) return '$label (URI)';
final srv = parsed.scheme.endsWith('+srv');
if (srv) return '$label: ${parsed.host}';
final port = parsed.hasPort ? parsed.port : defaultPort;
return '$label: ${parsed.host}:$port';
}
11 changes: 9 additions & 2 deletions lib/features/mongodb/mongodb_connection_form.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart' as material;
import 'package:querya_desktop/features/connections/connection_default_name.dart';
import 'package:querya_desktop/core/security/connection_environment.dart';
import 'package:querya_desktop/features/connections/environment_section.dart';
import 'package:querya_desktop/core/database/mongodb_connection.dart';
Expand Down Expand Up @@ -315,8 +316,14 @@ class _MongoConnectionFormContentState
final data = _formData;
if (!data.isValid) return;

final displayName =
data.name.isNotEmpty ? data.name : 'MongoDB ${data.host}:${data.port}';
final displayName = data.name.isNotEmpty
? data.name
: defaultConnectionName(
label: 'MongoDB',
defaultPort: 27017,
uri: data.connectionString ?? '',
fields: 'MongoDB ${data.host}:${data.port}',
);

final initial = widget.initial;
var row = ConnectionRow(
Expand Down
11 changes: 8 additions & 3 deletions lib/features/mysql/mysql_connection_form.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart' as material;
import 'package:querya_desktop/features/connections/connection_default_name.dart';
import 'package:querya_desktop/core/security/connection_environment.dart';
import 'package:querya_desktop/features/connections/environment_section.dart';
import 'package:querya_desktop/core/database/mysql_connection.dart';
Expand Down Expand Up @@ -247,9 +248,13 @@ class _MysqlConnectionFormContentState
final uri = _effectiveConnectionUri();
final displayName = name.isNotEmpty
? name
: (uri.isNotEmpty
? 'MySQL (URI)'
: 'MySQL $host:$port${database.isNotEmpty ? '/$database' : ''}');
: defaultConnectionName(
label: 'MySQL',
defaultPort: 3306,
uri: uri,
fields:
'MySQL $host:$port${database.isNotEmpty ? '/$database' : ''}',
);
final initial = widget.initial;
var row = ConnectionRow(
id: initial?.id,
Expand Down
12 changes: 7 additions & 5 deletions lib/features/postgresql/postgresql_connection_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:file_selector/file_selector.dart';
import 'package:flutter/material.dart' as material;
import 'package:querya_desktop/features/connections/connection_default_name.dart';
import 'package:querya_desktop/core/security/connection_environment.dart';
import 'package:querya_desktop/features/connections/environment_section.dart';
import 'package:querya_desktop/core/database/postgres_connection.dart';
Expand Down Expand Up @@ -335,13 +336,14 @@ class _PostgresConnectionFormContentState
}
}

final effectiveHost = uriHost ?? host;
final effectivePort = uriPort ?? port;
final displayName = name.isNotEmpty
? name
: (effectiveUri.isNotEmpty
? 'PostgreSQL: $effectiveHost:$effectivePort'
: 'PostgreSQL $host:$port/$database');
: defaultConnectionName(
label: 'PostgreSQL',
defaultPort: 5432,
uri: effectiveUri,
fields: 'PostgreSQL $host:$port/$database',
);
final initial = widget.initial;
var row = ConnectionRow(
id: initial?.id,
Expand Down
10 changes: 9 additions & 1 deletion lib/features/redis/redis_connection_form.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart' as material;
import 'package:querya_desktop/features/connections/connection_default_name.dart';
import 'package:querya_desktop/core/security/connection_environment.dart';
import 'package:querya_desktop/features/connections/environment_section.dart';
import 'package:querya_desktop/core/database/redis_connection.dart';
Expand Down Expand Up @@ -210,7 +211,14 @@ class _RedisConnectionFormContentState
final host = _hostController.text.trim();
final port = int.tryParse(_portController.text.trim()) ?? 6379;
final uri = _effectiveConnectionUri();
final displayName = name.isNotEmpty ? name : 'Redis $host:$port';
final displayName = name.isNotEmpty
? name
: defaultConnectionName(
label: 'Redis',
defaultPort: 6379,
uri: uri,
fields: 'Redis $host:$port',
);
final initial = widget.initial;
var row = ConnectionRow(
id: id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ void main() {
final secrets = await tester
.runAsync(() => ConnectionSecretsStore.readForConnection(row.id!));
expect(secrets!.connectionString, contains(host));
// The name comes from the URI's host, not the form's default one (#1257).
expect(row.name, contains(host));
// The sidebar reloads from the database after the save.
await waitFor(tester, inSidebar(row.name), 'the new connection');
await app.close(tester);
Expand Down
38 changes: 38 additions & 0 deletions test/features/connections/connection_default_name_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:querya_desktop/features/connections/connection_default_name.dart';

String _name(String label, int port, String uri) => defaultConnectionName(
label: label,
defaultPort: port,
uri: uri,
fields: '$label localhost:$port',
);

void main() {
test('a URI names the connection after its host and port', () {
expect(_name('Redis', 6379, 'redis://:p@cache.example.com:6380'),
'Redis: cache.example.com:6380');
expect(_name('MySQL', 3306, 'mysql://u:p@my.example.com:3307/app'),
'MySQL: my.example.com:3307');
expect(_name('MongoDB', 27017, 'mongodb://u:p@mongo.example.com:27018/app'),
'MongoDB: mongo.example.com:27018');
});

test('a URI without a port uses the type default', () {
expect(_name('Redis', 6379, 'redis://cache.example.com'),
'Redis: cache.example.com:6379');
});

test('a +srv URI has no port', () {
expect(_name('MongoDB', 27017, 'mongodb+srv://u:p@c0.example.net/db'),
'MongoDB: c0.example.net');
});

test('a URI without a host falls back to (URI)', () {
expect(_name('Redis', 6379, 'not a uri'), 'Redis (URI)');
});

test('without a URI the name comes from the fields', () {
expect(_name('Redis', 6379, ' '), 'Redis localhost:6379');
});
}
Loading