From 37e3cc0e721f88a4227d9f28d15915b13b6fe618 Mon Sep 17 00:00:00 2001 From: Don Alfons Nisnoni Date: Mon, 1 Jun 2020 17:26:39 +0800 Subject: [PATCH] mysql: simplify, add more functionality & documentation --- vlib/mysql/_cdefs.c.v | 2 + vlib/mysql/mysql.v | 89 ++++++++++++++++++++++++++++++------------- vlib/mysql/result.v | 58 ++++++++++++++++------------ 3 files changed, 98 insertions(+), 51 deletions(-) diff --git a/vlib/mysql/_cdefs.c.v b/vlib/mysql/_cdefs.c.v index 326f21fb48..ceefcbed85 100644 --- a/vlib/mysql/_cdefs.c.v +++ b/vlib/mysql/_cdefs.c.v @@ -33,7 +33,9 @@ fn C.mysql_change_user(mysql &C.MYSQL, user byteptr, password byteptr, db bytept fn C.mysql_affected_rows(mysql &C.MYSQL) u64 fn C.mysql_options(mysql &C.MYSQL, option int, arg voidptr) int fn C.mysql_get_option(mysql &C.MYSQL, option int, arg voidptr) int +fn C.mysql_list_tables(mysql &C.MYSQL, wild byteptr) &C.MYSQL_RES fn C.mysql_num_fields(res &C.MYSQL_RES) int +fn C.mysql_num_rows(res &C.MYSQL_RES) u64 fn C.mysql_autocommit(mysql MYSQL, mode bool) fn C.mysql_refresh(mysql MYSQL, options u32) int fn C.mysql_reset_connection(mysql MYSQL) int diff --git a/vlib/mysql/mysql.v b/vlib/mysql/mysql.v index e9461677a4..9e1c46b216 100644 --- a/vlib/mysql/mysql.v +++ b/vlib/mysql/mysql.v @@ -4,35 +4,24 @@ module mysql #flag linux -I/usr/include/mysql #include +// TODO: Documentation pub struct Connection { - host string - port u32 +mut: + conn &C.MYSQL = C.mysql_init(0) +pub mut: + host string = '127.0.0.1' + port u32 = 3306 username string password string dbname string flag int -mut: - conn &C.MYSQL -} - -pub fn new_connection(host, username, password, dbname string) ?Connection { - instance := C.mysql_init(0) - if isnil(instance) { - return error_with_code(get_error_msg(instance), get_errno(instance)) - } - return Connection{ host, 0, username, password, dbname, 0, instance } } +// connect Connects to a MySQL server pub fn (mut conn Connection) connect() ?bool { - mut instance := C.mysql_init(0) - if !isnil(conn.conn) { - instance = conn.conn - } - if isnil(instance) { - return error_with_code(get_error_msg(instance), get_errno(instance)) - } + instance := C.mysql_init(conn.conn) conn.conn = C.mysql_real_connect( - instance, + conn.conn, conn.host.str, conn.username.str, conn.password.str, @@ -47,6 +36,7 @@ pub fn (mut conn Connection) connect() ?bool { return true } +// query Performs a query on the database pub fn (conn Connection) query(q string) ?Result { if C.mysql_query(conn.conn, q.str) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -55,6 +45,7 @@ pub fn (conn Connection) query(q string) ?Result { return Result{res} } +// select_db Selects the default database for database queries pub fn (conn Connection) select_db(dbname string) ?bool { if C.mysql_select_db(conn.conn, dbname.str) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -62,6 +53,9 @@ pub fn (conn Connection) select_db(dbname string) ?bool { return true } +// change_user Changes the user of the specified database connection. +// If desired, the empty string value can be passed to the `dbname` parameter +// resulting in only changing the user and not selecting a database pub fn (conn Connection) change_user(username, password, dbname string) ?bool { mut ret := true if dbname != '' { @@ -75,15 +69,34 @@ pub fn (conn Connection) change_user(username, password, dbname string) ?bool { return ret } +// affected_rows Returns the number of rows changed/deleted/inserted +// by the last UPDATE, DELETE, or INSERT query pub fn (conn Connection) affected_rows() u64 { return C.mysql_affected_rows(conn.conn) } +// autocommit Turns on or off auto-committing database modifications pub fn (conn Connection) autocommit(mode bool) { C.mysql_autocommit(conn.conn, mode) } +// tables Returns list of tables that match the `wildcard` parameter. +// If empty string is passed, will return all tables +pub fn (conn Connection) tables(wildcard string) ?[]string { + cres := C.mysql_list_tables(conn.conn, wildcard.str) + if isnil(cres) { + return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) + } + res := Result{cres} + mut tables := []string{} + for row in res.rows() { + tables << row.vals[0] + } + res.free() + return tables +} +// escape_string Creates a legal SQL string for use in an SQL statement pub fn (conn Connection) escape_string(s string) string { len := C.strlen(s.str) to := malloc(2 * len + 1) @@ -93,10 +106,15 @@ pub fn (conn Connection) escape_string(s string) string { return string(to) } +// set_option Can be used to set extra connect options and affect behavior for a connection. +// This function may be called multiple times to set several options. +// To retrieve option values, use `get_option()` pub fn (conn Connection) set_option(option_type int, val voidptr) { C.mysql_options(conn.conn, option_type, val) } +// get_option Returns the current value of an option settable `set_option`. +// The value should be treated as read only pub fn (conn Connection) get_option(option_type int) ?voidptr { ret := voidptr(0) if C.mysql_get_option(conn.conn, option_type, &ret) != 0 { @@ -105,6 +123,8 @@ pub fn (conn Connection) get_option(option_type int) ?voidptr { return ret } +// refresh Flushes tables or caches, or resets replication server information. +// The connected user must have the `RELOAD` privilege pub fn (conn Connection) refresh(options u32) ?bool { if C.mysql_refresh(conn.conn, options) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -112,6 +132,7 @@ pub fn (conn Connection) refresh(options u32) ?bool { return true } +// reset_connection Resets the connection to clear the session state pub fn (conn Connection) reset_connection() ?bool { if C.mysql_reset_connection(conn.conn) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -119,6 +140,7 @@ pub fn (conn Connection) reset_connection() ?bool { return true } +// ping Pings a server connection, or tries to reconnect if the connection has gone down pub fn (conn Connection) ping() ?bool { if C.mysql_ping(conn.conn) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -126,37 +148,48 @@ pub fn (conn Connection) ping() ?bool { return true } -pub fn (conn Connection) close() { +// close Closes a previously opened database connection +pub fn (conn &Connection) close() { C.mysql_close(conn.conn) } -/* MYSQL INFO & VERSION */ +/* -------------------------- MYSQL INFO & VERSION -------------------------- */ +// info Returns information about the most recently executed query pub fn (conn Connection) info() string { - return string(C.mysql_info(conn.conn)) + return resolve_nil_str(C.mysql_info(conn.conn)) } +// get_host_info Returns a string describing the connection pub fn (conn Connection) get_host_info() string { return string(C.mysql_get_host_info(conn.conn)) } +// get_server_info Returns the server version number as a string pub fn (conn Connection) get_server_info() string { return string(C.mysql_get_server_info(conn.conn)) } +// get_server_version Returns the server version number as an integer pub fn (conn Connection) get_server_version() u64 { return C.mysql_get_server_version(conn.conn) } -pub fn get_client_version() u64 { - return C.mysql_get_client_version() -} +/* --------------------------------- CLIENT --------------------------------- */ +// get_client_info Returns client version information as a string pub fn get_client_info() string { return string(C.mysql_get_client_info()) } -/* MYSQL DEBUG */ +// get_client_version Returns client version information as an integer +pub fn get_client_version() u64 { + return C.mysql_get_client_version() +} + +/* ------------------------------- MYSQL DEBUG ------------------------------ */ + +// dump_debug_info Causes the server to write debug information to the log pub fn (conn Connection) dump_debug_info() ?bool { if C.mysql_dump_debug_info(conn.conn) != 0 { return error_with_code(get_error_msg(conn.conn), get_errno(conn.conn)) @@ -164,6 +197,8 @@ pub fn (conn Connection) dump_debug_info() ?bool { return true } +// debug Does a `DBUG_PUSH` with the given string. +// See https://dev.mysql.com/doc/refman/5.7/en/mysql-debug.html pub fn debug(debug string) { C.mysql_debug(debug.str) } diff --git a/vlib/mysql/result.v b/vlib/mysql/result.v index 9d941b5513..7a7ff82c79 100644 --- a/vlib/mysql/result.v +++ b/vlib/mysql/result.v @@ -9,37 +9,22 @@ pub mut: vals []string } -pub struct Field { - name string - org_name string - table string - org_table string - db string - catalog string - def string - length int - max_length int - name_length u32 - org_name_length u32 - table_length u32 - org_table_length u32 - db_length u32 - catalog_length u32 - def_length u32 - flags u32 - decimals u32 - charsetnr u32 - type_ FieldType -} - +// Fetches the next row from the result set pub fn (r Result) fetch_row() &byteptr { return C.mysql_fetch_row(r.result) } +// num_rows Returns the number of rows in the result set +pub fn (r Result) num_rows() u64 { + return C.mysql_num_rows(r.result) +} + +// num_fields Returns the number of columns in a result set pub fn (r Result) num_fields() int { return C.mysql_num_fields(r.result) } +// rows Returns rows with `array` of columns pub fn (r Result) rows() []Row { mut rows := []Row{} nr_cols := r.num_fields() @@ -57,7 +42,7 @@ pub fn (r Result) rows() []Row { return rows } -// maps return rows with `map` of columns instead `array` of columns +// maps Returns rows with `map` of columns instead `array` of columns pub fn (r Result) maps() []map[string]string { mut array_map := []map[string]string{} rows := r.rows() @@ -72,6 +57,7 @@ pub fn (r Result) maps() []map[string]string { return array_map } +// fetch_fields Returns an array of all field structures pub fn (r Result) fetch_fields() []Field { mut fields := []Field{} nr_cols := r.num_fields() @@ -103,6 +89,29 @@ pub fn (r Result) fetch_fields() []Field { return fields } +pub struct Field { + name string + org_name string + table string + org_table string + db string + catalog string + def string + length int + max_length int + name_length u32 + org_name_length u32 + table_length u32 + org_table_length u32 + db_length u32 + catalog_length u32 + def_length u32 + flags u32 + decimals u32 + charsetnr u32 + type_ FieldType +} + pub fn (f Field) str() string { return ' { @@ -130,6 +139,7 @@ pub fn (f Field) str() string { ' } +// free Frees memory used by a result set pub fn (r Result) free() { C.mysql_free_result(r.result) }