@malloy-publisher/server 0.0.124 → 0.0.126

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -310,42 +310,6 @@ async function attachPostgres(
310
310
  logger.info(`Successfully attached PostgreSQL database: ${attachedDb.name}`);
311
311
  }
312
312
 
313
- async function attachMotherDuck(
314
- connection: DuckDBConnection,
315
- attachedDb: AttachedDatabase,
316
- ): Promise<void> {
317
- if (!attachedDb.motherDuckConnection) {
318
- throw new Error(
319
- `MotherDuck connection configuration missing for: ${attachedDb.name}`,
320
- );
321
- }
322
-
323
- const config = attachedDb.motherDuckConnection;
324
-
325
- if (!config.database) {
326
- throw new Error(
327
- `MotherDuck database name is required for: ${attachedDb.name}`,
328
- );
329
- }
330
-
331
- await installAndLoadExtension(connection, "motherduck");
332
-
333
- // Set token if provided
334
- if (config.accessToken) {
335
- const escapedToken = escapeSQL(config.accessToken);
336
- await connection.runSQL(`SET motherduck_token = '${escapedToken}';`);
337
- }
338
-
339
- const connectionString = `md:${config.database}`;
340
- logger.info(
341
- `Connecting to MotherDuck database: ${config.database} as ${attachedDb.name}`,
342
- );
343
-
344
- const attachCommand = `ATTACH '${connectionString}' AS ${attachedDb.name} (TYPE motherduck, READ_ONLY);`;
345
- await connection.runSQL(attachCommand);
346
- logger.info(`Successfully attached MotherDuck database: ${attachedDb.name}`);
347
- }
348
-
349
313
  // Main attachment function
350
314
  async function attachDatabasesToDuckDB(
351
315
  duckdbConnection: DuckDBConnection,
@@ -355,7 +319,6 @@ async function attachDatabasesToDuckDB(
355
319
  bigquery: attachBigQuery,
356
320
  snowflake: attachSnowflake,
357
321
  postgres: attachPostgres,
358
- motherduck: attachMotherDuck,
359
322
  };
360
323
 
361
324
  for (const attachedDb of attachedDatabases) {
@@ -596,6 +559,37 @@ export async function createProjectConnections(
596
559
  break;
597
560
  }
598
561
 
562
+ case "motherduck": {
563
+ if (!connection.motherduckConnection) {
564
+ throw new Error(
565
+ "MotherDuck connection configuration is missing.",
566
+ );
567
+ }
568
+
569
+ if (!connection.motherduckConnection.accessToken) {
570
+ throw new Error("MotherDuck access token is required.");
571
+ }
572
+
573
+ let databasePath = `md:`;
574
+ // Build the MotherDuck database path
575
+ if (connection.motherduckConnection.database) {
576
+ databasePath = `md:${connection.motherduckConnection.database}?attach_mode=single`;
577
+ }
578
+
579
+ // Create MotherDuck connection using DuckDBConnectionOptions interface
580
+ const motherduckConnection = new DuckDBConnection({
581
+ name: connection.name,
582
+ databasePath: databasePath,
583
+ motherDuckToken: connection.motherduckConnection.accessToken,
584
+ workingDirectory: projectPath,
585
+ });
586
+
587
+ connectionMap.set(connection.name, motherduckConnection);
588
+ connection.attributes =
589
+ getConnectionAttributes(motherduckConnection);
590
+ break;
591
+ }
592
+
599
593
  default: {
600
594
  throw new Error(`Unsupported connection type: ${connection.type}`);
601
595
  }
@@ -738,12 +732,6 @@ export async function testConnectionConfig(
738
732
 
739
733
  // Use createProjectConnections to create the connection, then test it
740
734
  // TODO: Test duckdb connections?
741
- if (connectionConfig.type === "duckdb") {
742
- return {
743
- status: "ok",
744
- errorMessage: "",
745
- };
746
- }
747
735
 
748
736
  const { malloyConnections } = await createProjectConnections(
749
737
  [connectionConfig], // Pass the single connection config
@@ -260,6 +260,39 @@ export async function getSchemasForConnection(
260
260
  `Failed to get schemas for DuckDB connection ${connection.name}: ${(error as Error).message}`,
261
261
  );
262
262
  }
263
+ } else if (connection.type === "motherduck") {
264
+ if (!connection.motherduckConnection) {
265
+ throw new Error("MotherDuck connection is required");
266
+ }
267
+ try {
268
+ // Use MotherDuck's INFORMATION_SCHEMA.SCHEMATA to list schemas
269
+ const result = await malloyConnection.runSQL(
270
+ "SELECT DISTINCT schema_name as row FROM information_schema.schemata ORDER BY schema_name",
271
+ { rowLimit: 1000 },
272
+ );
273
+ const rows = standardizeRunSQLResult(result);
274
+ console.log(rows);
275
+ return rows.map((row: unknown) => {
276
+ const typedRow = row as { row: string };
277
+ return {
278
+ name: typedRow.row,
279
+ isHidden: [
280
+ "information_schema",
281
+ "performance_schema",
282
+ "",
283
+ ].includes(typedRow.row),
284
+ isDefault: false,
285
+ };
286
+ });
287
+ } catch (error) {
288
+ console.error(
289
+ `Error getting schemas for MotherDuck connection ${connection.name}:`,
290
+ error,
291
+ );
292
+ throw new Error(
293
+ `Failed to get schemas for MotherDuck connection ${connection.name}: ${(error as Error).message}`,
294
+ );
295
+ }
263
296
  } else {
264
297
  throw new Error(`Unsupported connection type: ${connection.type}`);
265
298
  }
@@ -509,8 +542,30 @@ export async function listTablesForSchema(
509
542
  `Failed to get tables for DuckDB schema ${schemaName} in connection ${connection.name}: ${(error as Error).message}`,
510
543
  );
511
544
  }
545
+ } else if (connection.type === "motherduck") {
546
+ if (!connection.motherduckConnection) {
547
+ throw new Error("MotherDuck connection is required");
548
+ }
549
+ try {
550
+ const result = await malloyConnection.runSQL(
551
+ `SELECT table_name as row FROM information_schema.tables WHERE table_schema = '${schemaName}' ORDER BY table_name`,
552
+ { rowLimit: 1000 },
553
+ );
554
+ const rows = standardizeRunSQLResult(result);
555
+ return rows.map((row: unknown) => {
556
+ const typedRow = row as { row: string };
557
+ return typedRow.row;
558
+ });
559
+ } catch (error) {
560
+ logger.error(
561
+ `Error getting tables for MotherDuck schema ${schemaName} in connection ${connection.name}`,
562
+ { error },
563
+ );
564
+ throw new Error(
565
+ `Failed to get tables for MotherDuck schema ${schemaName} in connection ${connection.name}: ${(error as Error).message}`,
566
+ );
567
+ }
512
568
  } else {
513
- // TODO(jjs) - implement
514
- return [];
569
+ throw new Error(`Unsupported connection type: ${connection.type}`);
515
570
  }
516
571
  }