|
| 1 | +// |
| 2 | +// CloudflareD1Plugin.swift |
| 3 | +// TablePro |
| 4 | +// |
| 5 | + |
| 6 | +import Foundation |
| 7 | +import os |
| 8 | +import TableProPluginKit |
| 9 | + |
| 10 | +final class CloudflareD1Plugin: NSObject, TableProPlugin, DriverPlugin { |
| 11 | + static let pluginName = "Cloudflare D1 Driver" |
| 12 | + static let pluginVersion = "1.0.0" |
| 13 | + static let pluginDescription = "Cloudflare D1 serverless SQLite-compatible database support via REST API" |
| 14 | + static let capabilities: [PluginCapability] = [.databaseDriver] |
| 15 | + |
| 16 | + static let databaseTypeId = "Cloudflare D1" |
| 17 | + static let databaseDisplayName = "Cloudflare D1" |
| 18 | + static let iconName = "cloudflare-d1-icon" |
| 19 | + static let defaultPort = 0 |
| 20 | + |
| 21 | + // MARK: - UI/Capability Metadata |
| 22 | + |
| 23 | + static let connectionMode: ConnectionMode = .apiOnly |
| 24 | + static let supportsSSH = false |
| 25 | + static let supportsSSL = false |
| 26 | + static let isDownloadable = true |
| 27 | + static let supportsImport = false |
| 28 | + static let supportsSchemaEditing = false |
| 29 | + static let databaseGroupingStrategy: GroupingStrategy = .flat |
| 30 | + static let brandColorHex = "#F6821F" |
| 31 | + static let urlSchemes: [String] = ["d1"] |
| 32 | + |
| 33 | + static let explainVariants: [ExplainVariant] = [ |
| 34 | + ExplainVariant(id: "plan", label: "Query Plan", sqlPrefix: "EXPLAIN QUERY PLAN") |
| 35 | + ] |
| 36 | + |
| 37 | + static let structureColumnFields: [StructureColumnField] = [.name, .type, .nullable, .defaultValue] |
| 38 | + |
| 39 | + static let columnTypesByCategory: [String: [String]] = [ |
| 40 | + "Integer": ["INTEGER", "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT"], |
| 41 | + "Float": ["REAL", "DOUBLE", "FLOAT", "NUMERIC", "DECIMAL"], |
| 42 | + "String": ["TEXT", "VARCHAR", "CHARACTER", "CHAR", "CLOB", "NVARCHAR", "NCHAR"], |
| 43 | + "Date": ["DATE", "TIME", "DATETIME", "TIMESTAMP"], |
| 44 | + "Binary": ["BLOB"], |
| 45 | + "Boolean": ["BOOLEAN"] |
| 46 | + ] |
| 47 | + |
| 48 | + static let sqlDialect: SQLDialectDescriptor? = SQLDialectDescriptor( |
| 49 | + identifierQuote: "\"", |
| 50 | + keywords: [ |
| 51 | + "SELECT", "FROM", "WHERE", "JOIN", "INNER", "LEFT", "RIGHT", "OUTER", "CROSS", |
| 52 | + "ON", "AND", "OR", "NOT", "IN", "LIKE", "GLOB", "BETWEEN", "AS", |
| 53 | + "ORDER", "BY", "GROUP", "HAVING", "LIMIT", "OFFSET", |
| 54 | + "INSERT", "INTO", "VALUES", "UPDATE", "SET", "DELETE", |
| 55 | + "CREATE", "ALTER", "DROP", "TABLE", "INDEX", "VIEW", "TRIGGER", |
| 56 | + "PRIMARY", "KEY", "FOREIGN", "REFERENCES", "UNIQUE", "CONSTRAINT", |
| 57 | + "ADD", "COLUMN", "RENAME", |
| 58 | + "NULL", "IS", "ASC", "DESC", "DISTINCT", "ALL", |
| 59 | + "CASE", "WHEN", "THEN", "ELSE", "END", "COALESCE", "IFNULL", "NULLIF", |
| 60 | + "UNION", "INTERSECT", "EXCEPT", |
| 61 | + "AUTOINCREMENT", "WITHOUT", "ROWID", "PRAGMA", |
| 62 | + "REPLACE", "ABORT", "FAIL", "IGNORE", "ROLLBACK", |
| 63 | + "TEMP", "TEMPORARY", "VACUUM", "EXPLAIN", "QUERY", "PLAN" |
| 64 | + ], |
| 65 | + functions: [ |
| 66 | + "COUNT", "SUM", "AVG", "MAX", "MIN", "GROUP_CONCAT", "TOTAL", |
| 67 | + "LENGTH", "SUBSTR", "SUBSTRING", "LOWER", "UPPER", "TRIM", "LTRIM", "RTRIM", |
| 68 | + "REPLACE", "INSTR", "PRINTF", |
| 69 | + "DATE", "TIME", "DATETIME", "JULIANDAY", "STRFTIME", |
| 70 | + "ABS", "ROUND", "RANDOM", |
| 71 | + "CAST", "TYPEOF", |
| 72 | + "COALESCE", "IFNULL", "NULLIF", "HEX", "QUOTE" |
| 73 | + ], |
| 74 | + dataTypes: [ |
| 75 | + "INTEGER", "REAL", "TEXT", "BLOB", "NUMERIC", |
| 76 | + "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT", |
| 77 | + "UNSIGNED", "BIG", "INT2", "INT8", |
| 78 | + "CHARACTER", "VARCHAR", "VARYING", "NCHAR", "NATIVE", |
| 79 | + "NVARCHAR", "CLOB", |
| 80 | + "DOUBLE", "PRECISION", "FLOAT", |
| 81 | + "DECIMAL", "BOOLEAN", "DATE", "DATETIME" |
| 82 | + ], |
| 83 | + tableOptions: [ |
| 84 | + "WITHOUT ROWID", "STRICT" |
| 85 | + ], |
| 86 | + regexSyntax: .unsupported, |
| 87 | + booleanLiteralStyle: .numeric, |
| 88 | + likeEscapeStyle: .explicit, |
| 89 | + paginationStyle: .limit |
| 90 | + ) |
| 91 | + |
| 92 | + static let additionalConnectionFields: [ConnectionField] = [ |
| 93 | + ConnectionField( |
| 94 | + id: "cfAccountId", |
| 95 | + label: String(localized: "Account ID"), |
| 96 | + placeholder: "Cloudflare Account ID", |
| 97 | + required: true, |
| 98 | + section: .authentication |
| 99 | + ) |
| 100 | + ] |
| 101 | + |
| 102 | + func createDriver(config: DriverConnectionConfig) -> any PluginDatabaseDriver { |
| 103 | + CloudflareD1PluginDriver(config: config) |
| 104 | + } |
| 105 | +} |
0 commit comments