Skip to content

Commit 4a7c399

Browse files
committed
migrate all components to the new database integration config format
1 parent d1e8f49 commit 4a7c399

16 files changed

+644
-1393
lines changed

src/notebooks/deepnote/integrations/integrationDetector.ts

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@ import { inject, injectable } from 'inversify';
22

33
import { logger } from '../../../platform/logging';
44
import { IDeepnoteNotebookManager } from '../../types';
5-
import {
6-
DATAFRAME_SQL_INTEGRATION_ID,
7-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE,
8-
IntegrationStatus,
9-
IntegrationWithStatus,
10-
RawLegacyIntegrationType
11-
} from '../../../platform/notebooks/deepnote/integrationTypes';
5+
import { IntegrationStatus, IntegrationWithStatus } from '../../../platform/notebooks/deepnote/integrationTypes';
126
import { IIntegrationDetector, IIntegrationStorage } from './types';
7+
import { DatabaseIntegrationType, databaseIntegrationTypes } from '@deepnote/database-integrations';
138

149
/**
1510
* Service for detecting integrations used in Deepnote notebooks
@@ -40,40 +35,25 @@ export class IntegrationDetector implements IIntegrationDetector {
4035
const integrations = new Map<string, IntegrationWithStatus>();
4136

4237
// Use the project's integrations field as the source of truth
43-
const projectIntegrations = project.project.integrations || [];
38+
const projectIntegrations = project.project.integrations?.slice() ?? [];
4439
logger.debug(`IntegrationDetector: Found ${projectIntegrations.length} integrations in project.integrations`);
4540

4641
for (const projectIntegration of projectIntegrations) {
4742
const integrationId = projectIntegration.id;
48-
49-
// Skip the internal DuckDB integration
50-
if (integrationId === DATAFRAME_SQL_INTEGRATION_ID) {
51-
continue;
52-
}
53-
54-
logger.debug(`IntegrationDetector: Found integration: ${integrationId} (${projectIntegration.type})`);
55-
56-
// Map the Deepnote integration type to our IntegrationType
57-
const integrationType =
58-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE[projectIntegration.type as RawLegacyIntegrationType];
59-
60-
// Skip unknown integration types
61-
if (!integrationType) {
62-
logger.warn(
63-
`IntegrationDetector: Unknown integration type '${projectIntegration.type}' for integration ID '${integrationId}'. Skipping.`
64-
);
43+
const integrationType = projectIntegration.type;
44+
if (!(databaseIntegrationTypes as readonly string[]).includes(integrationType)) {
45+
logger.debug(`IntegrationDetector: Skipping unsupported integration type: ${integrationType}`);
6546
continue;
6647
}
6748

6849
// Check if the integration is configured
6950
const config = await this.integrationStorage.getIntegrationConfig(integrationId);
70-
7151
const status: IntegrationWithStatus = {
72-
config: config || null,
52+
config: config ?? null,
7353
status: config ? IntegrationStatus.Connected : IntegrationStatus.Disconnected,
7454
// Include integration metadata from project for prefilling when config is null
7555
integrationName: projectIntegration.name,
76-
integrationType: integrationType
56+
integrationType: integrationType as DatabaseIntegrationType
7757
};
7858

7959
integrations.set(integrationId, status);

src/notebooks/deepnote/integrations/integrationManager.ts

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import { inject, injectable } from 'inversify';
2-
import { commands, l10n, NotebookDocument, window, workspace } from 'vscode';
2+
import { commands, l10n, window, workspace } from 'vscode';
33

44
import { IExtensionContext } from '../../../platform/common/types';
55
import { Commands } from '../../../platform/common/constants';
66
import { logger } from '../../../platform/logging';
77
import { IIntegrationDetector, IIntegrationManager, IIntegrationStorage, IIntegrationWebviewProvider } from './types';
8-
import {
9-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE,
10-
IntegrationStatus,
11-
LegacyIntegrationType,
12-
IntegrationWithStatus,
13-
RawLegacyIntegrationType
14-
} from '../../../platform/notebooks/deepnote/integrationTypes';
15-
import { BlockWithIntegration, scanBlocksForIntegrations } from './integrationUtils';
8+
import { IntegrationStatus } from '../../../platform/notebooks/deepnote/integrationTypes';
169
import { IDeepnoteNotebookManager } from '../../types';
10+
import { DatabaseIntegrationType, databaseIntegrationTypes } from '@deepnote/database-integrations';
1711

1812
/**
1913
* Manages integration UI and commands for Deepnote notebooks
@@ -143,14 +137,6 @@ export class IntegrationManager implements IIntegrationManager {
143137

144138
// First try to detect integrations from the stored project
145139
let integrations = await this.integrationDetector.detectIntegrations(projectId);
146-
147-
// If no integrations found in stored project, scan cells directly
148-
// This handles the case where the notebook was already open when the extension loaded
149-
if (integrations.size === 0) {
150-
logger.debug(`IntegrationManager: No integrations found in stored project, scanning cells directly`);
151-
integrations = await this.detectIntegrationsFromCells(activeNotebook);
152-
}
153-
154140
logger.debug(`IntegrationManager: Found ${integrations.size} integrations`);
155141

156142
// If a specific integration was requested (e.g., from status bar click),
@@ -164,21 +150,15 @@ export class IntegrationManager implements IIntegrationManager {
164150
const projectIntegration = project?.project.integrations?.find((i) => i.id === selectedIntegrationId);
165151

166152
let integrationName: string | undefined;
167-
let integrationType: LegacyIntegrationType | undefined;
153+
let integrationType: DatabaseIntegrationType | undefined;
168154

169-
if (projectIntegration) {
155+
// Validate that projectIntegration.type against supported types
156+
if (
157+
projectIntegration &&
158+
(databaseIntegrationTypes as readonly string[]).includes(projectIntegration.type)
159+
) {
170160
integrationName = projectIntegration.name;
171-
172-
// Validate that projectIntegration.type exists in the mapping before lookup
173-
if (projectIntegration.type in DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE) {
174-
// Map the Deepnote integration type to our IntegrationType
175-
integrationType =
176-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE[projectIntegration.type as RawLegacyIntegrationType];
177-
} else {
178-
logger.warn(
179-
`IntegrationManager: Unknown integration type '${projectIntegration.type}' for integration ID '${selectedIntegrationId}' in project '${projectId}'. Integration type will be undefined.`
180-
);
181-
}
161+
integrationType = projectIntegration.type as DatabaseIntegrationType;
182162
}
183163

184164
integrations.set(selectedIntegrationId, {
@@ -197,35 +177,4 @@ export class IntegrationManager implements IIntegrationManager {
197177
// Show the webview with optional selected integration
198178
await this.webviewProvider.show(projectId, integrations, selectedIntegrationId);
199179
}
200-
201-
/**
202-
* Detect integrations by scanning cells directly (fallback method)
203-
* This is used when the project isn't stored in the notebook manager
204-
*/
205-
private async detectIntegrationsFromCells(notebook: NotebookDocument): Promise<Map<string, IntegrationWithStatus>> {
206-
// Collect all cells with SQL integration metadata
207-
const blocksWithIntegrations: BlockWithIntegration[] = [];
208-
209-
for (const cell of notebook.getCells()) {
210-
const metadata = cell.metadata;
211-
logger.trace(`IntegrationManager: Cell ${cell.index} metadata:`, metadata);
212-
213-
// Check cell metadata for sql_integration_id
214-
if (metadata && typeof metadata === 'object') {
215-
const integrationId = (metadata as Record<string, unknown>).sql_integration_id;
216-
if (typeof integrationId === 'string') {
217-
logger.debug(`IntegrationManager: Found integration ${integrationId} in cell ${cell.index}`);
218-
blocksWithIntegrations.push({
219-
id: `cell-${cell.index}`,
220-
sql_integration_id: integrationId
221-
});
222-
}
223-
}
224-
}
225-
226-
logger.debug(`IntegrationManager: Found ${blocksWithIntegrations.length} cells with integrations`);
227-
228-
// Use the shared utility to scan blocks and build the status map
229-
return scanBlocksForIntegrations(blocksWithIntegrations, this.integrationStorage, 'IntegrationManager');
230-
}
231180
}

src/notebooks/deepnote/integrations/integrationUtils.ts

Lines changed: 0 additions & 68 deletions
This file was deleted.

src/notebooks/deepnote/integrations/integrationWebview.ts

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,8 @@ import { logger } from '../../../platform/logging';
77
import { LocalizedMessages, SharedMessages } from '../../../messageTypes';
88
import { IDeepnoteNotebookManager, ProjectIntegration } from '../../types';
99
import { IIntegrationStorage, IIntegrationWebviewProvider } from './types';
10-
import {
11-
LEGACY_INTEGRATION_TYPE_TO_DEEPNOTE,
12-
LegacyIntegrationType,
13-
LegacyIntegrationConfig,
14-
IntegrationStatus,
15-
IntegrationWithStatus,
16-
RawLegacyIntegrationType
17-
} from '../../../platform/notebooks/deepnote/integrationTypes';
10+
import { IntegrationStatus, IntegrationWithStatus } from '../../../platform/notebooks/deepnote/integrationTypes';
11+
import { DatabaseIntegrationConfig } from '@deepnote/database-integrations';
1812

1913
/**
2014
* Manages the webview panel for integration configuration
@@ -222,7 +216,7 @@ export class IntegrationWebviewProvider implements IIntegrationWebviewProvider {
222216
private async handleMessage(message: {
223217
type: string;
224218
integrationId?: string;
225-
config?: LegacyIntegrationConfig;
219+
config?: DatabaseIntegrationConfig;
226220
}): Promise<void> {
227221
switch (message.type) {
228222
case 'configure':
@@ -264,7 +258,7 @@ export class IntegrationWebviewProvider implements IIntegrationWebviewProvider {
264258
/**
265259
* Save the configuration for an integration
266260
*/
267-
private async saveConfiguration(integrationId: string, config: LegacyIntegrationConfig): Promise<void> {
261+
private async saveConfiguration(integrationId: string, config: DatabaseIntegrationConfig): Promise<void> {
268262
try {
269263
await this.integrationStorage.save(config);
270264

@@ -351,22 +345,15 @@ export class IntegrationWebviewProvider implements IIntegrationWebviewProvider {
351345
}
352346

353347
// Skip DuckDB integration (internal, not a real Deepnote integration)
354-
if (type === LegacyIntegrationType.DuckDB) {
348+
if (type === 'pandas-dataframe') {
355349
logger.trace(`IntegrationWebviewProvider: Skipping internal DuckDB integration ${id}`);
356350
return null;
357351
}
358352

359-
// Map to Deepnote integration type
360-
const deepnoteType: RawLegacyIntegrationType | undefined = LEGACY_INTEGRATION_TYPE_TO_DEEPNOTE[type];
361-
if (!deepnoteType) {
362-
logger.warn(`IntegrationWebviewProvider: Cannot map type ${type} for integration ${id}, skipping`);
363-
return null;
364-
}
365-
366353
return {
367354
id,
368355
name: integration.config?.name || integration.integrationName || id,
369-
type: deepnoteType
356+
type
370357
};
371358
})
372359
.filter((integration): integration is ProjectIntegration => integration !== null);

src/notebooks/deepnote/sqlCellStatusBarProvider.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,9 @@ import { IExtensionSyncActivationService } from '../../platform/activation/types
2222
import { IDisposableRegistry } from '../../platform/common/types';
2323
import { IIntegrationStorage } from './integrations/types';
2424
import { Commands } from '../../platform/common/constants';
25-
import {
26-
DATAFRAME_SQL_INTEGRATION_ID,
27-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE,
28-
LegacyIntegrationType,
29-
RawLegacyIntegrationType
30-
} from '../../platform/notebooks/deepnote/integrationTypes';
25+
import { DATAFRAME_SQL_INTEGRATION_ID } from '../../platform/notebooks/deepnote/integrationTypes';
3126
import { IDeepnoteNotebookManager } from '../types';
27+
import { DatabaseIntegrationType, databaseIntegrationTypes } from '@deepnote/database-integrations';
3228

3329
/**
3430
* QuickPick item with an integration ID
@@ -347,9 +343,11 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
347343
continue;
348344
}
349345

350-
const integrationType =
351-
DEEPNOTE_TO_LEGACY_INTEGRATION_TYPE[projectIntegration.type as RawLegacyIntegrationType];
352-
const typeLabel = integrationType ? this.getIntegrationTypeLabel(integrationType) : projectIntegration.type;
346+
const integrationType = projectIntegration.type;
347+
const typeLabel =
348+
integrationType && (databaseIntegrationTypes as readonly string[]).includes(integrationType)
349+
? this.getIntegrationTypeLabel(integrationType as DatabaseIntegrationType)
350+
: projectIntegration.type;
353351

354352
const item: LocalQuickPickItem = {
355353
label: projectIntegration.name || projectIntegration.id,
@@ -432,13 +430,13 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
432430
this._onDidChangeCellStatusBarItems.fire();
433431
}
434432

435-
private getIntegrationTypeLabel(type: LegacyIntegrationType): string {
433+
private getIntegrationTypeLabel(type: DatabaseIntegrationType): string {
436434
switch (type) {
437-
case LegacyIntegrationType.Postgres:
435+
case 'pgsql':
438436
return l10n.t('PostgreSQL');
439-
case LegacyIntegrationType.BigQuery:
437+
case 'big-query':
440438
return l10n.t('BigQuery');
441-
case LegacyIntegrationType.Snowflake:
439+
case 'snowflake':
442440
return l10n.t('Snowflake');
443441
default:
444442
return String(type);

0 commit comments

Comments
 (0)