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

Implement query function on connection #8

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

MitchellWeg
Copy link
Contributor

@MitchellWeg MitchellWeg commented Jul 30, 2022

Implements the query function on the connection object, so users can get results back. Fixes #3

Checklist:

  • Implement a small setup with a test.
  • Figure out how to cast the returned objects to their respective rust types.
  • Figure out how to handle multiple columns.
  • Add parameters to the function definition.

@MitchellWeg MitchellWeg marked this pull request as ready for review August 11, 2022 09:32

let response_lines = resp.lines();

let response_header: Vec<String> = response_lines.clone().skip(3).map(|x| self.sanitize(x)).collect();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly here you ignore the first 3 lines from the response. Why is that? Take a look at this: https://github.com/MonetDB/MonetDB-PHP/tree/master/protocol_doc#52-query-response---


#[inline]
fn sanitize(&self, line: &str) -> String {
line.replace(&['\t', '%', '[', ']', ' '], " ")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look correct. What happens for example if the database has the string
'[%]' stored in a column?

use mapi::errors::MonetDBError;

#[derive(Debug, PartialEq)]
pub enum MonetType {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need any more types here (e.g. dates)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. I just wanted a initial implementation out. We can add more types later.

impl MonetType {
pub fn parse(_type: &String, s: &str) -> Result<Self, MonetDBError> {
match _type.as_str() {
"double" => Ok(MonetType::Double(s.parse::<f32>().unwrap())),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use unwrap because, as we have discussed in the past, it might crash the program ("abc".parse::<i32>().unwrap).

This is a good explanation about error handling in Rust: https://blog.burntsushi.net/rust-error-handling/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It gets the type from the header, so something like "abc".parse::<i32>().unwrap() cannot happen. It always has to be one of the options. It'll otherwise return an UnimplementedError

match _type.as_str() {
"double" => Ok(MonetType::Double(s.parse::<f32>().unwrap())),
"int" => Ok(MonetType::Int(s.parse::<i32>().unwrap())),
"string" => Ok(MonetType::MapiString(String::from(s).replace('"', ""))),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not take into account legitimate uses of the quote character. See: https://github.com/MonetDB/MonetDB-PHP/tree/master/protocol_doc#61-escaping

Copy link
Collaborator

@kutsurak kutsurak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One general remark: The tests should be gathered in a separate test directory. This includes integration_tests.rs.

monetdb/src/row.rs Show resolved Hide resolved
let input1 = MonetType::parse(&String::from("clob"), "bar").unwrap();
let input2 = MonetType::parse(&String::from("clob"), "999.9").unwrap();
let input3 = MonetType::parse(&String::from("clob"), "foo bar with a lot of spaces").unwrap();
let input4 = MonetType::parse(&String::from("clob"), "'''foo bar with a lot of backticks'''").unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The single quote character ' is significant in SQL, so we probably need a couple more tests about it.

In SQL the single quote character is itself quoted by repeating it. That is, to represent the string he said, 'what a nice rust driver'. we would write: 'he said, ''what a nice rust driver''.'.

We need to see how mapi returns strings with single quotes and adjust our tests.


let metadata_header = match response_lines.next() {
Some(s) => s,
None => return Err(MonetDBError::UnimplementedError(String::from("Received no metadata")))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an unimplemented error. That implies that we will write some code to handle this in the future. If this ever happens it is probably a faulty server and we cannot do much about it.


let metadata = QueryResponse::parse_metadata_header(&metadata_header);

response_lines.next();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lines ignored?

}

#[inline]
fn sanitize(line: &str) -> String {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for? is it used anywhere?

}

#[inline]
fn remove_first_and_last_quote( line: &str) -> String {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not actually tested this, but it looks to me that it only removes the first quote, not the last. Also this function crashes if it is given an empty string.

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

Successfully merging this pull request may close these issues.

Implement query function
2 participants