package migra
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A database migration tool for OCaml supporting PostgreSQL, MariaDB, and SQLite
Install
dune-project
Dependency
Authors
Maintainers
Sources
migra-1.0.0.tbz
sha256=08ceb8f21f00227f21209484ef1eb8cc326ed26a280747798ec5b0b7c5fdd678
sha512=70050833623ba7801a0a31b1700f5473903335c8db2cdf4de5bbd1876180ec0a93907444b42f7a39b6af454303e0ee5f4c3543ca51378d6324583a26b93f535c
doc/src/migra.engine/dialect.ml.html
Source file dialect.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114type t = PostgreSQL | MariaDB | SQLite module type DIALECT = sig val name : string val default_port : int option val admin_database : string option val database_exists_sql : string val create_database_sql : string -> string val drop_database_sql : string -> string val timestamp_to_string : string -> string val supports_database_lifecycle : bool end module PostgreSQL_dialect : DIALECT = struct let name = "PostgreSQL" let default_port = Some 5432 let admin_database = Some "postgres" let supports_database_lifecycle = true let database_exists_sql = "SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = $1)" let create_database_sql db_name = Printf.sprintf "CREATE DATABASE %s" db_name let drop_database_sql db_name = Printf.sprintf "DROP DATABASE IF EXISTS %s" db_name let timestamp_to_string col = Printf.sprintf "%s::text" col end module MariaDB_dialect : DIALECT = struct let name = "MariaDB" let default_port = Some 3306 let admin_database = Some "mysql" let supports_database_lifecycle = true let database_exists_sql = "SELECT EXISTS(SELECT 1 FROM information_schema.SCHEMATA WHERE SCHEMA_NAME \ = ?)" let create_database_sql db_name = (* Use backticks for identifier quoting, IF NOT EXISTS for idempotency *) Printf.sprintf "CREATE DATABASE IF NOT EXISTS `%s`" db_name let drop_database_sql db_name = Printf.sprintf "DROP DATABASE IF EXISTS `%s`" db_name let timestamp_to_string col = Printf.sprintf "CAST(%s AS CHAR)" col end module SQLite_dialect : DIALECT = struct let name = "SQLite" let default_port = None let admin_database = None let supports_database_lifecycle = false (* These are unused for SQLite but required by signature *) let database_exists_sql = "" let create_database_sql _ = "" let drop_database_sql _ = "" let timestamp_to_string col = col end (** Normalize database URL for Caqti compatibility SQLite: caqti-driver-sqlite3 expects sqlite3:path (single colon), not sqlite3://path We accept both formats for user convenience but normalize to what Caqti expects. *) let normalize_url (url : string) : string = let prefix = "sqlite3://" in if String.starts_with ~prefix url then let n = String.length prefix in "sqlite3:" ^ String.sub url n (String.length url - n) else url let detect_from_url (url : string) : (t, string) result = if String.starts_with ~prefix:"postgresql://" url then Ok PostgreSQL else if String.starts_with ~prefix:"postgres://" url then Ok PostgreSQL else if String.starts_with ~prefix:"mariadb://" url then Ok MariaDB else if String.starts_with ~prefix:"mysql://" url then Ok MariaDB else if String.starts_with ~prefix:"sqlite3://" url then Ok SQLite else if String.starts_with ~prefix:"sqlite3:" url then Ok SQLite else let scheme = match String.index_opt url ':' with (* Grab "scheme://" for the message, but clamp the length: a URL like "ht:" has no room for the "//" and would otherwise overflow String.sub. *) | Some idx -> String.sub url 0 (min (idx + 3) (String.length url)) | None -> url in Error (Printf.sprintf "Unsupported database URL scheme: '%s'\n\n\ Supported databases:\n\ - PostgreSQL: postgresql:// or postgres://\n\ - MariaDB/MySQL: mariadb:// or mysql://\n\ - SQLite: sqlite3:// or sqlite3:\n\n\ Examples:\n\ - postgresql://user@localhost:5432/mydb\n\ - mariadb://root@localhost:3306/mydb\n\ - sqlite3://./dev.db (normalized to sqlite3:./dev.db)\n\ - sqlite3::memory: (in-memory database)\n\n" scheme) let get_dialect (db_type : t) : (module DIALECT) = match db_type with | PostgreSQL -> (module PostgreSQL_dialect) | MariaDB -> (module MariaDB_dialect) | SQLite -> (module SQLite_dialect) let to_string = function | PostgreSQL -> "PostgreSQL" | MariaDB -> "MariaDB" | SQLite -> "SQLite"
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>