-
-
Notifications
You must be signed in to change notification settings - Fork 40
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
Sqlite schema discovery #34
Conversation
Add enum type for writer
Fix a few typos I found while digging through the source code
to allow the ` #[derive(sqlx::FromRow, Debug)]` to be used to derive an sqlx row for handling PostgreSQL enums
Move types into types files under postgres::def::Type Add documentation on types Output the result by calling `discover_enum` on `SchemaDiscovery` Add method to parse a raw SQL create query for enum creation Add missing documentation for the added types for enum creation Test case to discover all the enums in a given database schema Write into SQL and then parse the raw SQL asserting that all discovered enums are the same as their raw SQL queries Solve issues with github actions not detecting types Add feature flag for new enum type and associated functions Switch to using re-exported sqlx types within sea-schema Fix CI errors Support enums with crazy names that include special characters Add support for ordered Vecs Add tests for discovery of enums Remove redundant module postgres_enum from the tests dir Ensure a custom enum type is dropped first from the database so that CI runs successfully Refactoring Ensures the writer derives the enum name from the EnumDef
Refactoring Refactoring Testing enum column... Refactoring Refactoring Refactoring Fix test Refactoring Refactoring Refactoring Cleanup
Update dependencies for compatibility with newer versions of SeaQL ecosystem libraries Add assertion tests Ensure that the autoincrement is called only on a primary key column Ensure that the `sqlite_sequence` table is populated by inserting data. This ensures that a primary key column with autoincrement will be entered into this table Fixes foreign key actions on tests Test both default values and foreign key actions Feature gate sqlite discovery to allow allowing it when it needed Move to `runtime-async-std-native-tls` to allow CI to build Bug fixes for github actions Configure test actions for SQLite in github actions file Switch to `cargo run` Remove unnecessary databases Ensure a database is created whenever the test is run
CI run sqlite discovery & writer Typo Fixup
Move to using a `Sqlitepool` Move tests to using a `Sqlitepool` Restructure to remove unused code Removes duplicate sql statements Returns `TableCreateStatement` on table discovery Returns `IndexCreateStatement` on index discovery Add assertion tests for creating and discovering indexes Add tests for discovery of indexes Restructure tests for table discovery Write discovered schema using new methods Add tests for index discovery Modify test to use new methods
@billy1624 please give one final look on it |
src/sqlite/tabledef.rs
Outdated
new_column.auto_increment(); | ||
} | ||
|
||
new_column.custom(Alias::new(&column_info.r#type.stringify_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.
All column types are specified in terms of 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.
@billy1624 this is because the current sea-query statements don't seem to handle all sqlite types like DOUBLE PRECISION
, VARYING CHARACTER
etc. Am I wrong about this ?
fn create_bakery_table() -> TableCreateStatement { | ||
Table::create() | ||
.table(Alias::new("bakery")) | ||
.col( | ||
ColumnDef::new(Alias::new("id")) | ||
.integer() | ||
.not_null() | ||
.auto_increment() | ||
.primary_key(), | ||
) | ||
.col(ColumnDef::new(Alias::new("name")).string()) | ||
.col(ColumnDef::new(Alias::new("profit_margin")).double()) | ||
.to_owned() | ||
} |
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.
And I'm not sure why it fail to discover the AUTOINCREMENT
for the bakery table
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.
There must be at least one row inserted
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.
I think we better not depends on this assumption. We could get around it with https://stackoverflow.com/a/18694881/7059723
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.
See 3336198
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.
3336198 LGTM .Thanks for providing a fix that. I wish I would have seen that stackoverflow post earlier. But I guess it depends of one's google search 😂.
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.
Is there anything else that needs fixing?
// Creates a new test table | ||
let create_table = Table::create() | ||
.table(Alias::new("Programming_Langs")) | ||
.col( | ||
ColumnDef::new(Alias::new("Name")) | ||
.custom(Alias::new("INTEGER")) | ||
.not_null() | ||
.auto_increment() | ||
.primary_key(), | ||
) |
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.
But it can discover this AUTOINCREMENT
column
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.
My tests ensure a row is first inserted before trying to check for autoincremented columns
let insert_into_table = Query::insert() | ||
.into_table(Alias::new("Programming_Langs")) | ||
.columns(vec![Alias::new("SLOC"), Alias::new("SemVer")]) | ||
.values(vec![4.into(), "0.1.0".into()]) | ||
.unwrap() | ||
.to_owned(); |
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.
Wait... it must have at least one row in order discover the AUTOINCREMENT
column?
As it depends on the last inserted AUTOINCREMENT
value?
sea-schema/src/sqlite/tabledef.rs
Lines 35 to 54 in ccf2ee0
/// Check if the primary key in the table is set to autoincrement as a result of using query /// `SELECT COUNT(*) from sqlite_sequence where name = 'table_name'; pub async fn pk_is_autoincrement(&mut self, executor: &Executor) -> DiscoveryResult<&mut Self> { let check_autoincrement = Query::select() .expr(Expr::cust("COUNT(*)")) .from(Alias::new("sqlite_sequence")) .and_where(Expr::col(Alias::new("name")).eq(self.name.as_str())) .to_owned(); let autoincrement_enabled = executor.fetch_one(check_autoincrement).await; let autoincrement_result: &SqliteRow = &autoincrement_enabled; let autoincrement: PrimaryKeyAutoincrement = autoincrement_result.into(); if autoincrement.0 == 1_u8 { self.auto_increment = true; } Ok(self) }
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.
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.
Yes! There must be at least one row. This issue took me a while to realize because the official SQLite documentation does not mentions this AFAIK. This is an issue with SQLite and I don't think it can be solved on our end. Any suggestions ? @billy1624 @tyt2y3
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.
Any suggestions?
See my comment on the second review above.
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.
Yeah... sadly there is no official way of doing schema discovery
How to handle composite primary key for SQLite?
|
@billy1624 |
For any primary key(s) that does not contain CREATE TABLE something (
column1 INTEGER NOT NULL,
column2 INTEGER NOT NULL,
value,
PRIMARY KEY ( column1, ... )
); For any primary key that does contain CREATE TABLE something (
column1 INTEGER NOT NULL AUTOINCREMENT,
column2 INTEGER NOT NULL,
value,
); |
@billy1624 |
Opppps... Sorry |
@billy1624 It's fine. No worries. I guess all the issues are now fixed, right? |
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.
Thanks!! @charleschege
* Implement Error & Display for SQLite error * MySQL & PostgreSQL write to `TableCreateStatement` * Ignore "sqlite_sequence" table * Discover timestamp column * Map text column to string
continue from #32