diff --git a/frontend/src/components/DriverManagerModal.test.tsx b/frontend/src/components/DriverManagerModal.test.tsx
index 8033330..a039e05 100644
--- a/frontend/src/components/DriverManagerModal.test.tsx
+++ b/frontend/src/components/DriverManagerModal.test.tsx
@@ -230,4 +230,62 @@ describe('DriverManagerModal toolbar actions', () => {
vi.useRealTimers();
}
});
+
+ it('reinstalls stale MongoDB v2 drivers with the v1 compatibility default', async () => {
+ vi.useFakeTimers({ shouldAdvanceTime: true });
+ try {
+ vi.setSystemTime(new Date(Date.now() + 2 * 60 * 1000));
+ backendApp.GetDriverStatusList.mockResolvedValue({
+ success: true,
+ data: {
+ downloadDir: 'D:/drivers',
+ drivers: [
+ {
+ type: 'mongodb',
+ name: 'MongoDB',
+ builtIn: false,
+ pinnedVersion: '1.17.9',
+ installedVersion: '2.5.0',
+ runtimeAvailable: true,
+ packageInstalled: true,
+ connectable: true,
+ needsUpdate: true,
+ defaultDownloadUrl: 'builtin://activate/mongodb',
+ message: '建议重装',
+ },
+ ],
+ },
+ });
+ backendApp.GetDriverVersionList.mockResolvedValue({
+ success: true,
+ data: {
+ versions: [
+ { version: '2.5.0', downloadUrl: 'builtin://activate/mongodb?version=2.5.0' },
+ { version: '1.17.9', downloadUrl: 'builtin://activate/mongodb', recommended: true },
+ ],
+ },
+ });
+ backendApp.DownloadDriverPackage.mockResolvedValue({ success: true });
+
+ let renderer: ReactTestRenderer;
+ await act(async () => {
+ renderer = create();
+ });
+ await flushPromises();
+
+ const reinstallButton = findButton(renderer!, '重装驱动');
+ await act(async () => {
+ await reinstallButton.props.onClick();
+ });
+
+ expect(backendApp.DownloadDriverPackage).toHaveBeenCalledWith(
+ 'mongodb',
+ '1.17.9',
+ 'builtin://activate/mongodb',
+ 'D:/drivers',
+ );
+ } finally {
+ vi.useRealTimers();
+ }
+ });
});
diff --git a/frontend/src/components/DriverManagerModal.tsx b/frontend/src/components/DriverManagerModal.tsx
index ca1550b..f303a23 100644
--- a/frontend/src/components/DriverManagerModal.tsx
+++ b/frontend/src/components/DriverManagerModal.tsx
@@ -525,6 +525,8 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
return prev;
}
const preferred =
+ (row.needsUpdate ? options.find((option) => option.version === row.pinnedVersion) : undefined) ||
+ (row.needsUpdate ? options.find((option) => option.recommended) : undefined) ||
options.find((option) => option.version === row.installedVersion) ||
options.find((option) => option.version === row.pinnedVersion) ||
options.find((option) => option.recommended) ||
@@ -712,6 +714,8 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
}
const selectedKey = selectedVersionMap[row.type];
const selectedOption =
+ (row.needsUpdate ? versionOptions.find((item) => item.version === row.pinnedVersion) : undefined) ||
+ (row.needsUpdate ? versionOptions.find((item) => item.recommended) : undefined) ||
versionOptions.find((item) => buildVersionOptionKey(item) === selectedKey) ||
versionOptions.find((item) => item.recommended) ||
versionOptions[0];
@@ -1033,7 +1037,7 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
const selectedKey = selectedVersionMap[row.type];
const selectOptions = buildVersionSelectOptions(options);
const mongoHint = row.type === 'mongodb'
- ? '当前仅支持 MongoDB 1.17.x 和 2.x;更老 1.x 暂不提供安装。'
+ ? 'MongoDB 4.0 请使用 1.17.x 兼容驱动;2.x 驱动要求 MongoDB 4.2+。'
: '';
return (
diff --git a/internal/app/methods_driver.go b/internal/app/methods_driver.go
index fc9a33f..fb480b1 100644
--- a/internal/app/methods_driver.go
+++ b/internal/app/methods_driver.go
@@ -352,7 +352,7 @@ const builtinDriverManifestJSON = `{
"vastbase": { "engine": "go", "version": "1.11.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/vastbase" },
"opengauss": { "engine": "go", "version": "1.11.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/opengauss" },
"iris": { "engine": "go", "version": "0.2.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/iris" },
- "mongodb": { "engine": "go", "version": "2.5.0", "checksumPolicy": "off", "downloadUrl": "builtin://activate/mongodb" },
+ "mongodb": { "engine": "go", "version": "1.17.9", "checksumPolicy": "off", "downloadUrl": "builtin://activate/mongodb" },
"tdengine": { "engine": "go", "version": "3.7.8", "checksumPolicy": "off", "downloadUrl": "builtin://activate/tdengine" },
"clickhouse": { "engine": "go", "version": "2.43.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/clickhouse" },
"elasticsearch": { "engine": "go", "version": "8.19.6", "checksumPolicy": "off", "downloadUrl": "builtin://activate/elasticsearch" }
@@ -821,7 +821,7 @@ func (a *App) GetDriverStatusList(downloadDir string, manifestURL string) connec
engine := effectiveDriverEngine(definition)
runtimeAvailable, runtimeReason := db.DriverRuntimeSupportStatus(definition.Type)
pkg, packageMetaExists := readInstalledDriverPackage(resolvedDir, definition.Type)
- needsUpdate, updateReason, expectedRevision := optionalDriverAgentRevisionStatus(definition.Type, pkg, packageMetaExists)
+ needsUpdate, updateReason, expectedRevision := optionalDriverPackageUpdateStatus(definition, pkg, packageMetaExists)
packageInstalled := definition.BuiltIn || packageMetaExists
if runtimeAvailable && db.IsOptionalGoDriver(definition.Type) {
packageInstalled = true
@@ -2828,6 +2828,31 @@ func optionalDriverAgentRevisionStatus(driverType string, pkg installedDriverPac
return true, fmt.Sprintf("原因:%s。影响:%s(已安装标记:%s,当前需要:%s)", updateReason, impact, actual, expected), expected
}
+func optionalDriverPackageUpdateStatus(definition driverDefinition, pkg installedDriverPackage, packageMetaExists bool) (bool, string, string) {
+ needsUpdate, reason, expected := optionalDriverAgentRevisionStatus(definition.Type, pkg, packageMetaExists)
+ if needsUpdate {
+ return true, reason, expected
+ }
+ if mongoDriverNeedsLegacyCompatibilityUpdate(definition, pkg, packageMetaExists) {
+ pinned := strings.TrimSpace(definition.PinnedVersion)
+ installed := strings.TrimSpace(pkg.Version)
+ return true, fmt.Sprintf("原因:当前推荐 MongoDB 兼容驱动版本为 %s,已安装版本为 %s。影响:MongoDB 2.x driver-agent 使用官方 v2 驱动,要求服务端 MongoDB 4.2+;连接 MongoDB 4.0 会出现 wire version 7 不兼容。强烈建议重装对应驱动代理", pinned, installed), expected
+ }
+ return false, "", expected
+}
+
+func mongoDriverNeedsLegacyCompatibilityUpdate(definition driverDefinition, pkg installedDriverPackage, packageMetaExists bool) bool {
+ if normalizeDriverType(definition.Type) != "mongodb" || !packageMetaExists {
+ return false
+ }
+ pinned := normalizeVersion(strings.TrimSpace(definition.PinnedVersion))
+ installed := normalizeVersion(strings.TrimSpace(pkg.Version))
+ if pinned == "" || installed == "" {
+ return false
+ }
+ return resolveMongoDriverMajorFromVersion(installed) == 2 && resolveMongoDriverMajorFromVersion(pinned) == 1
+}
+
func optionalDriverAgentRevisionCurrent(driverType string, executablePath string) (string, bool, error) {
expected := strings.TrimSpace(db.OptionalDriverAgentRevision(driverType))
if expected == "" {
@@ -3967,28 +3992,8 @@ func resolveMongoDriverMajorFromVersion(version string) int {
return 2
}
-func shouldForceSourceBuildForVersion(driverType string, selectedVersion string) bool {
- if normalizeDriverType(driverType) != "mongodb" {
- return false
- }
- return resolveMongoDriverMajorFromVersion(selectedVersion) == 1
-}
-
-func shouldForceSourceBuildForResolvedDownload(driverType string, selectedVersion string, downloadURL string) bool {
- if !shouldForceSourceBuildForVersion(driverType, selectedVersion) {
- return false
- }
-
- parsed, err := url.Parse(strings.TrimSpace(downloadURL))
- if err != nil || parsed == nil {
- return true
- }
- switch strings.ToLower(strings.TrimSpace(parsed.Scheme)) {
- case "http", "https":
- return false
- default:
- return true
- }
+func shouldForceSourceBuildForResolvedDownload(_ string, _ string, _ string) bool {
+ return false
}
func shouldPreferSourceBuildBeforeDownload(driverType string, selectedVersion string) bool {
@@ -4878,7 +4883,7 @@ func resolveOptionalDriverAgentDownloadURLs(definition driverDefinition, rawURL
appendURL(publishedURL)
}
}
- if publishedURL, ok := resolveLatestPublishedDriverDownloadURL(definition); ok {
+ if publishedURL, ok := resolveLatestPublishedDriverDownloadURLForVersion(definition, selectedVersion); ok {
appendURL(publishedURL)
}
}
@@ -5510,6 +5515,10 @@ func fetchLatestReleaseForDriverAssets() (*githubRelease, error) {
}
func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (string, bool) {
+ return resolveLatestPublishedDriverDownloadURLForVersion(definition, "")
+}
+
+func resolveLatestPublishedDriverDownloadURLForVersion(definition driverDefinition, selectedVersion string) (string, bool) {
driverType := normalizeDriverType(definition.Type)
if driverType == "" {
return "", false
@@ -5542,7 +5551,7 @@ func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (strin
return "", false
}
- assetNames := optionalDriverReleaseAssetNames(driverType)
+ assetNames := optionalDriverReleaseAssetNamesForVersion(driverType, selectedVersion)
if len(assetNames) == 0 {
return "", false
}
diff --git a/internal/app/methods_driver_agent_revision_test.go b/internal/app/methods_driver_agent_revision_test.go
index 243e8ef..a7f773b 100644
--- a/internal/app/methods_driver_agent_revision_test.go
+++ b/internal/app/methods_driver_agent_revision_test.go
@@ -33,6 +33,25 @@ func TestOptionalDriverAgentRevisionStatusDetectsStaleClickHouseAgent(t *testing
}
}
+func TestOptionalDriverPackageUpdateStatusDetectsMongoV2WhenLegacyDefault(t *testing.T) {
+ definition, ok := resolveDriverDefinition("mongodb")
+ if !ok {
+ t.Fatal("expected mongodb driver definition")
+ }
+ meta := installedDriverPackage{
+ Version: "2.5.0",
+ AgentRevision: db.OptionalDriverAgentRevision("mongodb"),
+ }
+
+ needsUpdate, reason, _ := optionalDriverPackageUpdateStatus(definition, meta, true)
+ if !needsUpdate {
+ t.Fatal("expected installed MongoDB v2 driver to require reinstall when v1 is the compatibility default")
+ }
+ if !strings.Contains(reason, "MongoDB 4.0") || !strings.Contains(reason, "wire version 7") {
+ t.Fatalf("expected reason to explain MongoDB 4.0 compatibility, got %q", reason)
+ }
+}
+
func TestOptionalDriverAgentRevisionCurrentRejectsStaleMetadata(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
diff --git a/internal/app/methods_driver_version_test.go b/internal/app/methods_driver_version_test.go
index 3ead1f6..af992a4 100644
--- a/internal/app/methods_driver_version_test.go
+++ b/internal/app/methods_driver_version_test.go
@@ -44,6 +44,20 @@ func TestResolveVersionedDriverOptionUsesPublishedMongoV1Release(t *testing.T) {
}
}
+func TestMongoDBDefaultDriverVersionUsesLegacyCompatibleLine(t *testing.T) {
+ definition, ok := resolveDriverDefinition("mongodb")
+ if !ok {
+ t.Fatal("expected mongodb driver definition")
+ }
+
+ if definition.PinnedVersion != "1.17.9" {
+ t.Fatalf("expected MongoDB default driver version 1.17.9, got %q", definition.PinnedVersion)
+ }
+ if got := resolveDriverInstallVersion("", definition.DefaultDownloadURL, definition); got != "1.17.9" {
+ t.Fatalf("expected builtin MongoDB install to resolve version 1.17.9, got %q", got)
+ }
+}
+
func TestCurrentDriverReleaseTagUsesDevLatestForDevBuild(t *testing.T) {
originalVersion := AppVersion
AppVersion = "dev-abc1234"
@@ -220,6 +234,38 @@ func TestResolveOptionalDriverAgentDownloadURLsDoesNotFallbackForHistoricalVersi
}
}
+func TestResolveOptionalDriverAgentDownloadURLsUsesMongoV1AssetForCompatibleDefault(t *testing.T) {
+ definition, ok := resolveDriverDefinition("mongodb")
+ if !ok {
+ t.Fatal("expected mongodb driver definition")
+ }
+
+ originalVersion := AppVersion
+ AppVersion = "0.7.9"
+ t.Cleanup(func() {
+ AppVersion = originalVersion
+ })
+
+ assetName := mongoVersionedReleaseAssetName(1)
+ seedReleaseAssetSizeCache(t, "tag:v0.7.9", map[string]int64{
+ assetName: 24 << 20,
+ })
+ seedReleaseAssetSizeCache(t, "latest", map[string]int64{})
+
+ urls := resolveOptionalDriverAgentDownloadURLs(
+ definition,
+ "builtin://activate/mongodb",
+ "1.17.9",
+ )
+ want := driverReleaseDownloadURL("v0.7.9", assetName)
+ for _, got := range urls {
+ if got == want {
+ return
+ }
+ }
+ t.Fatalf("expected MongoDB v1 release asset %q in candidates, got %v", want, urls)
+}
+
func TestResolveOptionalDriverAgentDownloadURLsSkipsBundleOnlyDamengAsset(t *testing.T) {
definition, ok := resolveDriverDefinition("dameng")
if !ok {
@@ -662,8 +708,8 @@ func TestResolveRecentDriverVersionMetasFallsBackToHistoricalTDengineMatrix(t *t
}
func TestShouldForceSourceBuildForResolvedDownload(t *testing.T) {
- if !shouldForceSourceBuildForResolvedDownload("mongodb", "1.17.4", "builtin://activate/mongodb?channel=history&version=1.17.4") {
- t.Fatal("expected mongodb v1 builtin install to keep source build mode")
+ if shouldForceSourceBuildForResolvedDownload("mongodb", "1.17.4", "builtin://activate/mongodb?channel=history&version=1.17.4") {
+ t.Fatal("expected mongodb v1 builtin install to try published assets before source build")
}
explicitURL := driverReleaseDownloadURL("v1.17.4", mongoVersionedReleaseAssetName(1))