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

feat: add support for mysql and sqlite #100

Merged
merged 18 commits into from
Sep 28, 2024

Conversation

Frank-III
Copy link
Contributor

hopefully resolve: #67

Hi there!
this is a simple hack that adds support for MySQL and sqlite, should be easy to implement for other dbs that sqlx has support for.
I haven't finished it yet, would like to discuss it before I continue working on it.

@achristmascarl
Copy link
Owner

hey @Frank-III, thanks for the PR and taking this on! i wasn't sure when i'd get to it, so this is really helpful 🙏

structure-wise, I think everything makes sense so far. there's a few specific things i'll leave comments for, but overall it makes sense.

i'll also open a separate PR for mysql and sqlite containers/test data to make the development experience smoother, hopefully in time for you to make use of them lol

src/app.rs Outdated Show resolved Hide resolved
src/cli.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
@achristmascarl
Copy link
Owner

@Frank-III i just merged #101, hopefully that will be helpful for you during development

@Frank-III
Copy link
Contributor Author

@Frank-III i just merged #101, hopefully that will be helpful for you during development

Thank you that would be very helpful, I would try to address all the issues and refer to the contribution guide!

@Frank-III
Copy link
Contributor Author

Hi @achristmascarl, some updates on this PR.
The parser for MySQL and SQLite are almost working:
For MySQL:

  • Geometry type cannot be parsed correctly, we may need to parse it as binary and use crate like geozero to parse it and represent it as String.

For SQLite:

  • types besides INTEGER, REAL, TEXT, BLOB would be interpreted as NULL by sqlx and just cast as String for representation(like DECIMAL(10,2), JSON)
  • We store geometry data as binary so casting it as binary and parsing it using geozero seems to be the solution as well.

Feel free to give it a try, and provide feedback! Thank you again for adding test data for MySQL and SQLite, super helpful!

let mut query_rows = vec![];
let mut query_rows_affected: Option<u64> = None;
let mut headers: Headers = vec![];
while !query_finished {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have to change this part as it hangs the MySQL connection. if I use 3 maximum connections, the third query will hang

@achristmascarl
Copy link
Owner

thanks @Frank-III, will take a look! we can hold off on the geometry types for now, i think i'll need to add either geozero or georust for #66 to support postgis, so we can wait until then and add it in for all the drivers together

@achristmascarl
Copy link
Owner

great work, the parsers and drivers set ups look good! two main points of feedback:

1. i don't think the mysql transactions work on drop statements

to repro:

  1. init db, start app with mysql
  2. drop table robot_parts
  3. [N] to rollback
  4. go to menu and [R] to refresh
  5. robot_parts was dropped despite rolling back
  6. however, rolling back seems to work for delete statements. if i try to delete all the rows and roll it back, the rows are not deleted
  7. rolling back the drop statement in postgres still works

i'm not sure this is actually because of your code, it could be a quirk with sqlx and mysql. i'll do some more research tmrw as well

2. we should add some tests to the mysql and sqlite drivers, similar to what's there for postgres

other

a minor suggestion, not blocking for the PR though, is to make the driver optional and get the user to input if it's missing

@achristmascarl
Copy link
Owner

it looks like drop statements can't be rolled back in mysql: https://dev.mysql.com/doc/refman/8.4/en/cannot-roll-back.html

i'll need to change the confirmation popup so that it can optionally show up before executing the query as well, you can skip this for now

@achristmascarl
Copy link
Owner

probably 'DROP' statements for all drivers can be "confirm before executing" instead of "execute in transaction"

@Frank-III
Copy link
Contributor Author

Frank-III commented Sep 27, 2024

it looks like drop statements can't be rolled back in mysql: https://dev.mysql.com/doc/refman/8.4/en/cannot-roll-back.html
probably 'DROP' statements for all drivers can be "confirm before executing" instead of "execute in transaction"

Yeah, that makes sense, I would skip this part for now then.

  1. we should add some tests to the mysql and sqlite drivers, similar to what's there for Postgres

I add the test for SQLite and MySQL, there is one SQLite query that could not get properly parsed by the sqlparser crate, and the drop table test for MySQL would fail when testing if we should use tx.

a minor suggestion, not blocking for the PR though, is to make the driver optional and get the user to input if it's missing

I thought about this too! Also, if the user passes the URL directly we don't need the driver option

@achristmascarl
Copy link
Owner

thanks for adding in the driver implementation, and the tests look good! we can leave the other tests for now, i'll first release with a warning that mysql/sqlite are unstable and i'll revisit them later.

@Frank-III was there anything else you wanted to add or is the PR finished from your end? if it's finished, i can run the tests and add a few small things for Docker before merging :)

@Frank-III Frank-III marked this pull request as ready for review September 28, 2024 00:47
@Frank-III
Copy link
Contributor Author

I think no, thank you for your prompt reply!

@achristmascarl
Copy link
Owner

great, i'm also going to have an automated review bot, but you can ignore it's feedback for now; it's just to surface things that i might need to take a second look at

@greptileai

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR adds support for MySQL and SQLite databases to the rainfrog project, significantly expanding its database compatibility. The implementation involves refactoring the codebase to use generic database types and introducing new traits to handle different database operations.

Key changes and considerations:

  • Generic implementation: The codebase now uses generics extensively, allowing for flexible support of different database types.
  • New database modules: Separate files for MySQL, PostgreSQL, and SQLite have been added in the src/database/ directory.
  • CLI improvements: The cli.rs file now includes a Driver enum to handle different database drivers.
  • Component refactoring: All components have been updated to work with generic database types.
  • Query abstraction: Database-specific queries have been replaced with more generic, abstracted methods.

Security implications:

  • The use of generics improves type safety, potentially reducing runtime errors related to database operations.
  • Care should be taken to ensure proper database access controls are maintained across different database types.
  • Input validation and sanitization should be reviewed for each database type to prevent SQL injection vulnerabilities.

Performance considerations:

  • The added abstraction layer may have some performance implications, particularly in hot paths.
  • Using generics for database types allows for compile-time optimizations specific to each database backend.
  • Connection pooling and query execution strategies may need to be optimized for each database type.

Potential improvements:

  • Implement more robust error handling, especially for database-specific errors.
  • Consider adding integration tests for each supported database type to ensure compatibility.
  • Review and optimize the generic implementations for potential performance bottlenecks.
  • Implement database-specific features where appropriate, while maintaining a common interface.

13 file(s) reviewed, 16 comment(s)
Edit PR Review Bot Settings

src/cli.rs Show resolved Hide resolved
src/components/scroll_table.rs Show resolved Hide resolved
src/database.rs Show resolved Hide resolved
src/database.rs Show resolved Hide resolved
src/database.rs Outdated Show resolved Hide resolved
src/database/postgresql.rs Show resolved Hide resolved
src/database/sqlite.rs Show resolved Hide resolved
src/database/sqlite.rs Show resolved Hide resolved
src/database/sqlite.rs Show resolved Hide resolved
src/main.rs Show resolved Hide resolved
@achristmascarl achristmascarl merged commit a015808 into achristmascarl:main Sep 28, 2024
8 checks passed
Copy link

Included in release v0.2.6

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.

support mysql and sqlite
2 participants