Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In rust, mysql database is connected to mysql database. How can the query result restore the original type data #383

Open
tgy3300 opened this issue Jun 19, 2024 · 1 comment

Comments

@tgy3300
Copy link

tgy3300 commented Jun 19, 2024

I used rust's mysql library to connect to the mysql database, and the result of the query was that every data item was a character type

fn get_row<T: DeserializeOwned + Default>(r: Row) -> T {
        let mut json_obj = json!({});
        for col in r.columns_ref() {
            let col_key = col.name_str().to_string();
            let col_val = if let Value::Bytes(v) = &r[col.name_str().as_ref()] {
                std::str::from_utf8(v).unwrap()
            } else {
                ""
            };

            println!("------{}------{:#?}-----", col_key, col.column_type());

            json_obj[col_key] = col_val.into();
        }
        let res_str = serde_json::to_string_pretty(&json_obj).unwrap();
        let res: T = serde_json::from_str(&res_str).unwrap();
        res
    }

fn info<T>(conn: PooledConn) -> Result<T, std::io::Error> 
where
    T: DeserializeOwned + Default,
{
        let sql = format!("select * from company");
        let result: Option<Row> = conn.query_first(sql).expect("Data query error");

        if let Some(row) = result {
            let res: T = get_row(row);
            return Ok(res);
        }

        Ok(T::default())
}

// This is the structure passed in by calling the info method
#[derive(Deserialize, Default, Debug)]
struct Company {
    id: String,
    name: String,
    status: u32,
    err_info: String,
    account_id: String,
    create_at: String,
    update_at: String,
}

The data obtained by calling the info method is as follows, as if each data is a string, through the printing type, it should be the corresponding data of different types, how to restore the original data, ask for help

Company {
    id: "2017612633062042215",
    name: "Yangyang",
    status: "100",
    err_info: "",
    account_id: "0",
    create_at: "1710993521",
    update_at: "1711000831",
}
------id------MYSQL_TYPE_LONGLONG-----
------name------MYSQL_TYPE_VAR_STRING-----
------status------MYSQL_TYPE_SHORT-----
------err_info------MYSQL_TYPE_VAR_STRING-----
------account_id------MYSQL_TYPE_LONGLONG-----
------create_at------MYSQL_TYPE_LONGLONG-----
------update_at------MYSQL_TYPE_LONGLONG-----

The following is the data table structure
https://global.discourse-cdn.com/business5/uploads/rust_lang/original/3X/1/6/1626aaa494901a2b70aaca862aa722a9614a4d47.png

@blackbeam
Copy link
Owner

Hi. Similar question was recently asked — blackbeam/rust_mysql_common#141

All the query_* methods uses mysql so called "text protocol" (MYSQL_COM_QUERY command) — this "text protocol" works in a way that server converts all the values into their textual representation before sending them back to the client.

If you want binary values being sent to you as-is please use the so called "binary protocol" that is prepared statements.

From another perspective — if you just need properly typed values on your side without thinking about protocols then just convert them to matching rust types. In the case of your struct you can do it via an intermediate tuple or using the FromRow derive macro:

use mysql::prelude::{Queryable, FromRow};

#[derive(Debug, FromRow)]
struct Company {
    id: i64,
    name: String,
    status: i16,
    err_info: Option<String>,
    account_id: i64,
    create_at: i64,
    update_at: i64,
}

fn get_first_company(
    conn: &mut impl Queryable,
) -> Result<Option<Company>, Box<dyn std::error::Error + Send + Sync + 'static>> {
    Ok(conn.query_first("select * from company")?)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants