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

Prior code to get SQLite version using sqlite_version() works. Now broken. [Solved Manually. See comments] #503

Open
ptdecker opened this issue Mar 19, 2024 · 2 comments
Labels
help wanted Extra attention is needed

Comments

@ptdecker
Copy link

The following code used to work to get the SQLite version:

                match rb.query_decode("SELECT sqlite_version()", vec![]).await? {
                    Some(v) => {
                        eprintln!("b");
                        Ok(v)
                    }
                    None => Err(anyhow!("Unable to obtain database version")),
                }

It fails with the following error: "Database error: Sqlite: invalid type: map, expected a string"

To get more information, I used the following code extracted from query_decode():

                let conn = rb.acquire().await?;
                let v = conn.query("SELECT sqlite_version()", vec![]).await?;
                eprintln!("v: {:?}", v);

What I get for v is:

v: Array([Map({String("sqlite_version()"): String("3.45.0")})])

So, apparently decode() [which is what is called next in query_decode] cannot handle that return structure from SQLite.

Any ideas on how to resolve?

@ptdecker
Copy link
Author

This code works. It manually decodes it properly step by step. I'm sure you probably have a better way of doing this in the libraries but I'm not familiar enough with how your library works internally. Hopefully this code will help and there is an easier way to solve this.

                let conn = rb.acquire().await?;
                let encoded_value = conn.query("SELECT sqlite_version()", vec![]).await;
                let array_value = match encoded_value {
                    Ok(rbs::Value::Array(array_value)) => array_value,
                    Ok(_) => return Err(anyhow!("Expected array but got something else")),
                    Err(e) => return Err(anyhow!("Query error: {}", e)),
                };
                let first_array_value = match array_value.len() {
                    1 => array_value[0].clone(),
                    _ => {
                        return Err(anyhow!(
                            "Expected only one element in the array--got {}",
                            array_value.len()
                        ))
                    }
                };
                let map_value = match first_array_value {
                    rbs::Value::Map(map_value) => map_value,
                    _ => return Err(anyhow!("Expected map but got something else")),
                };
                let first_map_element_value = match map_value.into_iter().next() {
                    Some(value) => value.1,
                    None => return Err(anyhow!("Expected map to contain one element it has none")),
                };
                let version = match first_map_element_value {
                    rbs::Value::String(decoded_version) => decoded_version,
                    _ => return Err(anyhow!("Expected string but got something else")),
                };

@ptdecker ptdecker changed the title Prior code works. Now broken. Prior code to get SQLite version using sqlite_version() works. Now broken. [Solved Manually. See comments] Mar 19, 2024
@zhuxiujia
Copy link
Member

zhuxiujia commented Mar 22, 2024

The following code used to work to get the SQLite version:

                match rb.query_decode("SELECT sqlite_version()", vec![]).await? {
                    Some(v) => {
                        eprintln!("b");
                        Ok(v)
                    }
                    None => Err(anyhow!("Unable to obtain database version")),
                }

It fails with the following error: "Database error: Sqlite: invalid type: map, expected a string"

To get more information, I used the following code extracted from query_decode():

                let conn = rb.acquire().await?;
                let v = conn.query("SELECT sqlite_version()", vec![]).await?;
                eprintln!("v: {:?}", v);

What I get for v is:

v: Array([Map({String("sqlite_version()"): String("3.45.0")})])

So, apparently decode() [which is what is called next in query_decode] cannot handle that return structure from SQLite.

Any ideas on how to resolve?

  • this unit test work's well, did you delete Cargo.lock and run command cargo update to update rbatis version?
    #[test]
    fn test_decode_string() {
        let v: String = rbatis::decode(Value::Array(vec![to_value!{
            "a":"a",
        }])).unwrap();
        assert_eq!(v, "a");
    }
Testing started at 10:29 ...
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.10s
     Running tests/decode_test.rs (target/debug/deps/decode_test-96029c5cf93b50f4)

image

@zhuxiujia zhuxiujia added the help wanted Extra attention is needed label Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants