blackbeam / rust-mysql-simple

Mysql client library implemented in rust.
Apache License 2.0
658 stars 144 forks source link

Example Code: `mysql::Opts: std::convert::From<&str>` continued issues & password doesn't exist in OptsBuilder? #319

Closed arch-linux closed 2 years ago

arch-linux commented 2 years ago

Before I pose my question I have referenced both #314 and #296 -- specifically where @blackbeam explains error handling resources for folks like myself who are new to rust; this being said - I have spent more than a reasonable amount of time attempting to get this work and have failed to do so.

I am attempting to connect to a DB, here are the different ways I have attempted to get this module to work.

As mentioned in the example code, the image below.

image
use json::JsonValue;
use mysql::*;
use mysql::prelude::*;

pub fn report_online(config:&JsonValue) {
    //TODO* Implement Config from JSON into URL.

    let url = "mysql://root:password@localhost:3307/db_name";

    let pool = Pool::new(url);

    let mut conn = pool.get_conn();

}

I have cut most of the example code out trying to isolate the issues that I have currently before moving on with the rest. From this small excerpt I receive two errors, the first one a 'dead ringer' to #314.

the trait bound `mysql::Opts: std::convert::From<&str>` is not satisfied

the trait `std::convert::From<&str>` is not implemented for `mysql::Opts`

help: the following implementations were found:
        <mysql::Opts as std::convert::From<mysql::OptsBuilder>>
note: required because of the requirements on the impl of `std::convert::Into<mysql::Opts>` for `&str`rustc(E0277)

The second error I receive is an absence of pool.getconn() in the mysql package -- as referenced from the example code.

no method named `get_conn` found for enum `std::result::Result` in the current scope

method not found in `std::result::Result<mysql::Pool, mysql::Error>`rustc(E0599)

In an attempt to work around this issue referencing #296 I have tried utilizing a return method in that regard.

fn report_online() -> Result<(), Box<dyn std::error::Error>>

This results in the following error.

mismatched types

expected enum `std::result::Result`, found `()`

note:   expected enum `std::result::Result<(), mysql::Error>`
      found unit type `()`rustc(E0308)

As an alternative to the example code I attempted to follow OptsBuilder in mysql in order to avoid the entire connection string to start with however it does not appear that .password exists in the OptsBuilder resulting in an error when attempting to do that.

image

As I said in the beginning, I am somewhat new to Rust however I feel like I have read the necessaries and the README.md however I am suffering from no luck here.

I really do appreciate any help on this one!

blackbeam commented 2 years ago

Hi!

As mentioned in the example code, the image below. From this small excerpt I receive two errors, the first one a 'dead ringer' to https://github.com/blackbeam/rust-mysql-simple/issues/314.

Yeah, this issue is fixed by #315, but the new version is not yet released, so you have to use the following for now:

let url = "mysql://root:password@localhost:3307/db_name";
let opts = Opts::from_url(url)?;
let pool = Pool::new(opts)?;

The second error I receive is an absence of pool.get_conn() in the mysql package -- as referenced from the example code

no method named `get_conn` found for enum `std::result::Result` in the current scope

method not found in `std::result::Result<mysql::Pool, mysql::Error>`rustc(E0599)

Pool::new returns Result<mysql::Pool, mysql::Error> (as stated in its documentation), so one can't simply ignore that. You have to either unwrap the result:

use json::JsonValue;
use mysql::*;
use mysql::prelude::*;

pub fn report_online(config:&JsonValue) {
    let url = "mysql://root:password@localhost:3307/db_name";
    let opts = Opts::from_url(url).expect("Fatal error: invalid mysql URL"); 
    let pool = Pool::new(url).expect("Fatal error: unable to connect to a database");
    let mut conn = pool.get_conn().expect("Fatal error: unable to get a connection");
}

or propagate the error, assuming that the function returns a compatible one:

use json::JsonValue;
use mysql::*;
use mysql::prelude::*;

pub fn report_online(config:&JsonValue) -> Result<(), Box<dyn std::error::Error>> {
    let url = "mysql://root:password@localhost:3307/db_name";
    let opts = Opts::from_url(url)?; 
    let pool = Pool::new(url)?;
    let mut conn = pool.get_conn()?;
    todo!()
}

In an attempt to work around this issue referencing https://github.com/blackbeam/rust-mysql-simple/issues/296 I have tried utilizing a return method in that regard.

fn report_online() -> Result<(), Box<dyn std::error::Error>>

This results in the following error.

mismatched types

expected enum `std::result::Result`, found `()`

note:   expected enum `std::result::Result<(), mysql::Error>`
      found unit type `()`rustc(E0308)

It seems that you violated your own statement: first you stated that you'll return Result<(), Box<dyn std::error::Error>> from report_online, but then you returned nothing (i.e. ()). Compiler won't accept that.

You have to either follow your obligations and return the proper result instance:

use json::JsonValue;
use mysql::*;
use mysql::prelude::*;

pub fn report_online(config:&JsonValue) -> Result<(), Box<dyn std::error::Error>> {
    let url = "mysql://root:password@localhost:3307/db_name";
    let opts = Opts::from_url(url)?; 
    let pool = Pool::new(url)?;
    let mut conn = pool.get_conn()?;

    Ok(())
}

or make the function never return (say by panicking):

use json::JsonValue;
use mysql::*;
use mysql::prelude::*;

pub fn report_online(config:&JsonValue) -> Result<(), Box<dyn std::error::Error>> {
    let url = "mysql://root:password@localhost:3307/db_name";
    let opts = Opts::from_url(url)?; 
    let pool = Pool::new(url)?;
    let mut conn = pool.get_conn()?;

    todo!()
}

As an alternative to the example code I attempted to follow OptsBuilder in mysql in order to avoid the entire connection string to start with however it does not appear that .password exists in the OptsBuilder resulting in an error when attempting to do that.

Yeah. There is no OptsBuilder::password but there exists OptsBuilder::pass.

arch-linux commented 2 years ago

Thanks @blackbeam!