-
Notifications
You must be signed in to change notification settings - Fork 7
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
Mysql integration in Canyon #45
Conversation
I am happy to see you contributing for the very first time to the Canyon's codebase. I am looking forward to see how the implementation of |
…d implement solution
…r and chrono:Date<OffSet>
Good morning, In the last commit is changed the format of columns of the update, since I was testing. But it should not exist and I understand that it is not a solution to support postgresql. Greetings. |
I don't understand what's the problem with posgres. Can you post the errores, problems or related code? By the way, I am probably not understanding correctly your problem, but you not be messing up with posgres code. Whatever alternative you need in MySQL, should be completly independent from postgresql code. Are you maybe talking about the query macros? The approach is typically that postgre SQL is our base crate, so, whenever you need to do something with the queries, you must replace the problematic syntax in the executor, like we did in sqlserver. This solution is far from perfect in terms of performance, but is the good one ATM to keep the queries code completly decoupled from one driver vendor to another, si people can come and implement new drivers, like your case with MySQL. By the way, we're open to upgrade our codebase, so we will appreciate any idea |
@gbm25 by the way, you looked the upper-lower case standarization within Canyon for the queries. Can you help @0nSystem with its problem? |
If I remember correctly, by default we used the lowercase name for both table and column names, unless specified otherwise by the user. Of course, to support both cases, the queries have to be prepared to search for those names taking into account that the names can contain uppercase letters because the table was created that way. As I don't know what is the concrete problem of @0nSystem I will expose a small summary of the things related to table and column names in the different databases. Identifier Behavior in Different DatabasesPostgreSQL:
Click to see examplesTable Creation:CREATE TABLE "TEST" (
"COLUMN1" VARCHAR(255),
"COLUMN2" INT,
"COLUMN3" DATE,
"COLUMN4" BOOLEAN
); Sample Query:INSERT INTO "TEST" ("COLUMN1", "COLUMN2", "COLUMN3", "COLUMN4") VALUES ('Sample', 123, '2023-08-14', TRUE);
SELECT * FROM "TEST" WHERE "COLUMN1" = 'Sample'; Microsoft SQL Server:
Click to see examplesTable Creation:CREATE TABLE `TEST` (
`COLUMN1` VARCHAR(255),
`COLUMN2` INT,
`COLUMN3` DATE,
`COLUMN4` BOOLEAN
); Sample Query:INSERT INTO `TEST` (`COLUMN1`, `COLUMN2`, `COLUMN3`, `COLUMN4`) VALUES ('Sample', 123, '2023-08-14', TRUE);
SELECT * FROM `TEST` WHERE `COLUMN1` = 'Sample'; MySQL:
Click to see examplesTable Creation:SET QUOTED_IDENTIFIER ON;
CREATE TABLE "TEST" (
"COLUMN1" VARCHAR(255),
"COLUMN2" INT,
"COLUMN3" DATE,
"COLUMN4" BIT
); Sample Query:INSERT INTO "TEST" ("COLUMN1", "COLUMN2", "COLUMN3", "COLUMN4") VALUES ('Sample', 123, '2023-08-14', 1);
SELECT * FROM "TEST" WHERE "COLUMN1" = 'Sample'; Given the above, it is clear that we were able to use the same standard with PostgreSQL and Microsoft SQL Server, but it is not going to be possible for MySQL. It can also be that not all queries follow this format in Canyon-SQL, because when it was implemented in Microsoft SQL Server it gave a lot of problems and many times we did things a little bit blindly. Anyway, if you have any doubt with the queries, let me know which one is failing or which part of the code is giving you problems and we will see it. |
Hello @gbm25 @Pyzyryab, |
…and investigate get last insert in mysql_async
… pattern in crud.rs
…tialization mssql
@0nSystem is there any progress on this? I have a personal project in mind with some friends and we would like to do some testing with this innovative implementation. Great job! |
Hello @damibazarra , Thanks In principle everything is almost ready, currently the implementation is functional and you can start using it, I have to fix MysqlOperator and clippy errors. |
Hey @0nSystem I reviewed briefly your changes, and except some minor things, everything looks fine. Even more, you cleaned some parts of the cfg macros that I liked. Please, consider to carefully read the comments left as notes, and implement the changes whenever you feel ready. And by the way, you can change the PR mode to open, since we are already preparing for the next release, that will include the Thanks for your job :) |
Hey @Pyzyryab later today, I'll check the comments, and let you know when I'm ready to merge. |
@@ -43,6 +45,8 @@ tokio = { version = "1.27.0", features = ["full"] } | |||
tokio-util = { version = "0.7.4", features = ["compat"] } | |||
tokio-postgres = { version = "0.7.2", features = ["with-chrono-0_4"] } | |||
tiberius = { version = "0.12.1", features = ["tds73", "chrono", "integrated-auth-gssapi"] } | |||
mysql_async = { version = "0.32.2" } | |||
mysql_common = { version = "0.30.6", features = [ "chrono" ]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure that we need the two dependencies? Why do we need mysql_common
? I guess that you've said because the format of the rows returned by the library, but we need to review if there's an approach that only need to rely on having the async crate
}, | ||
}; | ||
|
||
//TODO add options to optionals params in url |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
options to optionals?
@@ -12,11 +12,17 @@ description.workspace = true | |||
[dependencies] | |||
tokio-postgres = { workspace = true, optional = true } | |||
tiberius = { workspace = true, optional = true } | |||
mysql_async = { workspace = true, optional = true } | |||
mysql_common = { workspace = true, optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as comment one, just to be sure
pub fn name(&self) -> &'_ str { | ||
self.name | ||
pub fn name(&self) -> &str { | ||
&self.name | ||
} | ||
pub fn column_type(&self) -> &ColumnType { | ||
&self.type_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to remove the comments below, since they are there left by mistake
type_: ColumnType, | ||
} | ||
impl<'a> Column<'a> { | ||
pub fn name(&self) -> &'_ str { | ||
self.name | ||
pub fn name(&self) -> &str { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't change things that aren't meant to be changed in this kind of PR.
The anonymous lifetime there is for one purpose, literally, to indicate an anonymous lifetime.
&'_
let pp: &str = positional_param.as_str(); | ||
let pp_index = pp[1..] // param $1 -> get 1 | ||
.parse::<usize>() | ||
.expect("Error parse mapped parameter to usized.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review English please
stmt: &str, | ||
params: &[&'_ dyn QueryParameter<'_>], | ||
fn_parser: impl Fn(&&dyn QueryParameter<'_>) -> T, | ||
) -> Vec<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is "unwrapping" (.expect(msg)), which leads to panic the process, instead of return with an error. And is made in a lot of places.
Please, implement a more curated version that handles properly the Result or Optional types, and return a Result<Vec, _> with the _ as a placeholder for the error that you need to return if it's the case
@@ -20,7 +22,7 @@ pub enum Comp { | |||
} | |||
|
|||
impl Operator for Comp { | |||
fn as_str(&self, placeholder_counter: usize) -> String { | |||
fn as_str(&self, placeholder_counter: usize, _datasource_type: &DatabaseType) -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_datasource_type: &DatabaseType
isn't being used in the code, nor expected to be used
#(#init_field_values_sqlserver),* | ||
} | ||
let tokens = quote! { | ||
impl canyon_sql::crud::RowMapper<Self> for #ty { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job. You solved this implementation issue elegantly!
Hi guys, I am opening this PR as I want to do mysql integration. I open the PR in draft mode to be able to consult details and to be able to make a periodical follow-up of my progress.
Greetings ZeroDayCode.