|
| 1 | +// |
| 2 | +// PluginMetadataRegistry+DuckDBDefaults.swift |
| 3 | +// TablePro |
| 4 | +// |
| 5 | + |
| 6 | +import Foundation |
| 7 | +import TableProPluginKit |
| 8 | + |
| 9 | +extension PluginMetadataRegistry { |
| 10 | + /// The curated snapshot for DuckDB, alongside its connection fields in the sibling file. |
| 11 | + func duckdbPluginDefaults( |
| 12 | + dialect: SQLDialectDescriptor, |
| 13 | + columnTypes: [String: [String]] |
| 14 | + ) -> [(typeId: String, snapshot: PluginMetadataSnapshot)] { |
| 15 | + [ |
| 16 | + ("DuckDB", PluginMetadataSnapshot( |
| 17 | + displayName: "DuckDB", iconName: "duckdb-icon", defaultPort: 9_494, |
| 18 | + requiresAuthentication: false, supportsForeignKeys: true, supportsSchemaEditing: true, |
| 19 | + isDownloadable: true, primaryUrlScheme: "duckdb", parameterStyle: .dollar, |
| 20 | + navigationModel: .standard, |
| 21 | + explainVariants: [ |
| 22 | + ExplainVariant(id: "explain", label: "EXPLAIN", sqlPrefix: "EXPLAIN", format: .indentedText), |
| 23 | + ], |
| 24 | + pathFieldRole: .database, |
| 25 | + supportsHealthMonitor: false, urlSchemes: ["duckdb", "quack"], |
| 26 | + postConnectActions: [.selectSchemaFromLastSession], |
| 27 | + brandColorHex: "#FFD900", |
| 28 | + queryLanguageName: "SQL", editorLanguage: .sql, |
| 29 | + connectionMode: .apiOnly, supportsDatabaseSwitching: true, |
| 30 | + capabilities: PluginMetadataSnapshot.CapabilityFlags( |
| 31 | + supportsSchemaSwitching: true, |
| 32 | + supportsImport: true, |
| 33 | + supportsExport: true, |
| 34 | + supportsSSH: false, |
| 35 | + supportsSSL: false, |
| 36 | + supportsCascadeDrop: false, |
| 37 | + supportsForeignKeyDisable: true, |
| 38 | + supportsReadOnlyMode: true, |
| 39 | + supportsQueryProgress: false, |
| 40 | + requiresReconnectForDatabaseSwitch: false, |
| 41 | + supportsDropDatabase: false, |
| 42 | + supportsRenameColumn: true, |
| 43 | + supportsConnectionPooling: false, |
| 44 | + localFilePathField: .additionalField("duckdbFilePath") |
| 45 | + ), |
| 46 | + schema: PluginMetadataSnapshot.SchemaInfo( |
| 47 | + defaultSchemaName: "main", |
| 48 | + defaultGroupName: "main", |
| 49 | + tableEntityName: "Tables", |
| 50 | + containerEntityName: "Database", |
| 51 | + defaultPrimaryKeyColumn: nil, |
| 52 | + immutableColumns: [], |
| 53 | + systemDatabaseNames: ["system", "temp"], |
| 54 | + systemSchemaNames: [], |
| 55 | + fileExtensions: ["duckdb", "ddb", "parquet", "csv", "tsv", "json", "ndjson"], |
| 56 | + /// Only DuckDB's own storage. The data formats above are recognised by name |
| 57 | + /// alone, because `duckdb_open` picks their reader from the extension and |
| 58 | + /// refuses a Parquet file called anything else. |
| 59 | + /// |
| 60 | + /// `DUCK` sits behind the header's eight-byte checksum, followed by the storage |
| 61 | + /// version as a little-endian `uint64`. Four bytes on their own are not enough |
| 62 | + /// to name a format, and `SELECT 'DUCK';` spells them at exactly that offset, |
| 63 | + /// so the version's high six bytes have to be zero as well. Storage versions |
| 64 | + /// are still in the sixties, and a version past 65535 would cost recognition by |
| 65 | + /// content rather than break it. |
| 66 | + fileSignatures: [.magic("DUCK", at: 8).andZeroes(at: 14, count: 6)], |
| 67 | + databaseGroupingStrategy: .bySchema, |
| 68 | + structureColumnFields: [.name, .type, .nullable, .defaultValue, .autoIncrement, .comment] |
| 69 | + ), |
| 70 | + editor: PluginMetadataSnapshot.EditorConfig( |
| 71 | + sqlDialect: dialect, |
| 72 | + statementCompletions: [], |
| 73 | + columnTypesByCategory: columnTypes |
| 74 | + ), |
| 75 | + connection: PluginMetadataSnapshot.ConnectionConfig( |
| 76 | + additionalConnectionFields: Self.duckdbConnectionFields, |
| 77 | + category: .analytical, |
| 78 | + tagline: String(localized: "Embedded and remote analytical SQL"), |
| 79 | + hidesBuiltInPassword: true, |
| 80 | + hidesBuiltInDatabase: true |
| 81 | + ) |
| 82 | + )) |
| 83 | + ] |
| 84 | + } |
| 85 | +} |
0 commit comments