Pure-MoonBit MySQL wire-protocol driver implementing @moondb.Driver — no C, like PyMySQL.
Dependencies
$ moon add Lfan-ke/moon-mysqllet db = @client.MysqlDriver::new(
user="root", password="root", database="test",
host="127.0.0.1", port=3306,
)
db.execute("CREATE TABLE t (id INT PRIMARY KEY, name TEXT)", [])
db.execute("INSERT INTO t VALUES (?, ?)", [@moondb.Int(1), @moondb.Text("a")])
let rows = db.query("SELECT id, name FROM t", [])
rows[0].int_by("id") // => 1
rows[0].text_by("name") // => "a"async fn run() -> Unit raise {
let conn = @client.MysqlConn::connect("127.0.0.1", 3306, "root", "root", "test")
conn.begin()
conn.execute("INSERT INTO t VALUES (?, ?)", [@moondb.Int(2), @moondb.Text("b")])
conn.commit()
let rows = conn.query("SELECT * FROM t", [])
conn.close()
}flowchart TD
subgraph root["Lfan-ke/moon-mysql · pure codec · target: all backends"]
sha1["sha1 — FIPS 180-4"]
packet["packet — lenenc / fixed-int / string cursor"]
handshake["handshake — parse + scramble + response"]
response["response — OK/ERR/EOF + text-row decode"]
binding["binding — ? placeholders → escaped literals"]
end
subgraph client["Lfan-ke/moon-mysql/client · native only"]
conn["MysqlConn — async transport over @socket.Tcp"]
driver["MysqlDriver — sync @moondb.Driver adapter"]
end
handshake --> conn
response --> conn
binding --> conn
packet --> handshake
packet --> response
sha1 --> handshake
conn --> driver
driver -. implements .-> moondb["@moondb.Driver"]%% root (pure, all backends) client (native)
%% sha1 ─┐ MysqlConn ── async socket transport
%% packet┼─ handshake ─┐ │
%% └─ response ──┼──────────────► │
%% binding ───┘ MysqlDriver ── impl @moondb.Driver| MySQL column type | @moondb.Value |
|---|---|
| TINYINT / SMALLINT / INT / MEDIUMINT / YEAR | Int |
| BIGINT | Int64 |
| FLOAT / DOUBLE | Double |
| binary-collation columns (BLOB, VARBINARY, …) | Blob |
| VARCHAR / TEXT / DECIMAL / JSON / temporal (ISO text) | Text |
| SQL NULL | Null |
pub(all) suberror MysqlError {
ProtocolError(String)
ServerError(Int, String, String)
UnsupportedError(String)
} derive(Eq)impl Show for MysqlErrorpub struct Handshake {
server_version : String
server_kind : ServerKind
connection_id : Int
salt : Bytes
capability : Int
mariadb_capability : Int
charset : Int
status : Int
auth_plugin : String
}pub(all) struct OkPacket {
affected_rows : Int64
last_insert_id : Int64
status : Int
warnings : Int
} derive(Eq)pub struct PacketReader {
data : Bytes
pos : Int
}impl Show for ServerKindfn build_handshake_response(handshake : Handshake, user : String, password : Bytes, database : String) -> Bytes raise MysqlErrorfn bytes_to_string(b : Bytes) -> Stringfn caching_sha2_full_auth_token(password : Bytes, nonce : Bytes, pem : String, seed : Bytes) -> Bytes raise MysqlErrorfn caching_sha2_scramble(password : Bytes, nonce : Bytes) -> Bytesfn ed25519_sign(secret : Bytes, msg : Bytes) -> Bytesfn is_auth_switch_request(payload : Bytes) -> Boolfn is_eof_packet(payload : Bytes) -> Boolfn is_err_packet(payload : Bytes) -> Boolfn is_ok_packet(payload : Bytes) -> Boolfn mariadb_ed25519_response(password : Bytes, scramble : Bytes) -> Bytesfn native_password_scramble(password : Bytes, salt : Bytes) -> Bytesfn rsa_oaep_sha1_encrypt(msg : Bytes, n : BigInt, e : BigInt, seed : Bytes) -> Bytes raise MysqlErrorfn sha1(msg : Bytes) -> Bytesfn sha512(msg : Bytes) -> BytesPure-MoonBit MySQL wire-protocol driver implementing @moondb.Driver — no C, like PyMySQL.
Dependencies