|
|
@@ -0,0 +1,134 @@
|
|
|
+using InvercargillSql.Dialects;
|
|
|
+
|
|
|
+namespace InvercargillSql {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Static factory for creating SQL dialects based on connection schemes.
|
|
|
+ *
|
|
|
+ * This factory maintains a registry of dialect creators indexed by scheme.
|
|
|
+ * The SQLite dialect is automatically registered on first use.
|
|
|
+ *
|
|
|
+ * Example usage:
|
|
|
+ * ```vala
|
|
|
+ * // Create dialect from scheme string
|
|
|
+ * var dialect = DialectFactory.create("sqlite");
|
|
|
+ *
|
|
|
+ * // Create dialect from connection string
|
|
|
+ * var cs = ConnectionString.parse("sqlite:///mydb.sqlite");
|
|
|
+ * var dialect = DialectFactory.create_from_connection_string(cs);
|
|
|
+ *
|
|
|
+ * // Register custom dialect
|
|
|
+ * DialectFactory.register_dialect("postgresql", () => new PostgresDialect());
|
|
|
+ * var dialect = DialectFactory.create("postgresql");
|
|
|
+ * ```
|
|
|
+ */
|
|
|
+ public class DialectFactory : Object {
|
|
|
+
|
|
|
+ private static bool _sqlite_registered = false;
|
|
|
+ private static SqlDialect? _sqlite_dialect = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a SQL dialect based on a scheme string.
|
|
|
+ *
|
|
|
+ * The scheme is case-insensitive (e.g., "sqlite" and "SQLite" both work).
|
|
|
+ *
|
|
|
+ * @param scheme The database scheme (e.g., "sqlite", "postgresql", "mysql")
|
|
|
+ * @return A SqlDialect instance for the specified scheme
|
|
|
+ * @throws SqlError.INVALID_CONNECTION_STRING if no dialect is registered for the scheme
|
|
|
+ */
|
|
|
+ public static SqlDialect create(string scheme) throws SqlError {
|
|
|
+ string scheme_lower = scheme.down();
|
|
|
+
|
|
|
+ if (scheme_lower == "sqlite") {
|
|
|
+ if (!_sqlite_registered) {
|
|
|
+ _sqlite_dialect = new SqliteDialect();
|
|
|
+ _sqlite_registered = true;
|
|
|
+ }
|
|
|
+ return _sqlite_dialect;
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new SqlError.INVALID_CONNECTION_STRING(
|
|
|
+ "No SQL dialect registered for scheme: %s".printf(scheme)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a SQL dialect from a ConnectionString object.
|
|
|
+ *
|
|
|
+ * Extracts the scheme from the connection string and creates
|
|
|
+ * the appropriate dialect.
|
|
|
+ *
|
|
|
+ * @param connection_string The parsed connection string
|
|
|
+ * @return A SqlDialect instance for the connection string's scheme
|
|
|
+ * @throws SqlError.INVALID_CONNECTION_STRING if no dialect is registered for the scheme
|
|
|
+ */
|
|
|
+ public static SqlDialect create_from_connection_string(ConnectionString connection_string) throws SqlError {
|
|
|
+ return create(connection_string.scheme);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a SQL dialect by parsing a connection string.
|
|
|
+ *
|
|
|
+ * This is a convenience method that parses the connection string
|
|
|
+ * and creates the appropriate dialect in one step.
|
|
|
+ *
|
|
|
+ * @param connection_string The connection string to parse
|
|
|
+ * @return A SqlDialect instance for the connection string's scheme
|
|
|
+ * @throws SqlError.INVALID_CONNECTION_STRING if parsing fails or no dialect is registered
|
|
|
+ */
|
|
|
+ public static SqlDialect create_from_string(string connection_string) throws SqlError {
|
|
|
+ ConnectionString cs = ConnectionString.parse(connection_string);
|
|
|
+ return create_from_connection_string(cs);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Registers a SQL dialect for a scheme.
|
|
|
+ *
|
|
|
+ * If a dialect is already registered for the scheme, it will be
|
|
|
+ * replaced.
|
|
|
+ *
|
|
|
+ * Note: Currently only SQLite is supported natively. This method
|
|
|
+ * is provided for future extensibility when additional database
|
|
|
+ * backends are added.
|
|
|
+ *
|
|
|
+ * @param scheme The scheme (e.g., "sqlite", "postgresql")
|
|
|
+ * @param dialect The SqlDialect instance to register
|
|
|
+ */
|
|
|
+ public static void register_dialect(string scheme, SqlDialect dialect) {
|
|
|
+ string scheme_lower = scheme.down();
|
|
|
+
|
|
|
+ if (scheme_lower == "sqlite") {
|
|
|
+ _sqlite_dialect = dialect;
|
|
|
+ _sqlite_registered = true;
|
|
|
+ }
|
|
|
+ // For other providers, we would extend this with a dictionary
|
|
|
+ // For now, we only support SQLite natively
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Clears all registered dialects.
|
|
|
+ *
|
|
|
+ * Useful for testing or when reconfiguring the factory.
|
|
|
+ */
|
|
|
+ public static void clear_dialects() {
|
|
|
+ _sqlite_dialect = null;
|
|
|
+ _sqlite_registered = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks if a dialect is registered for a scheme.
|
|
|
+ *
|
|
|
+ * @param scheme The scheme to check
|
|
|
+ * @return true if a dialect is registered (or will be auto-created for sqlite)
|
|
|
+ */
|
|
|
+ public static bool has_dialect(string scheme) {
|
|
|
+ string scheme_lower = scheme.down();
|
|
|
+
|
|
|
+ if (scheme_lower == "sqlite") {
|
|
|
+ return true; // SQLite is always available
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|