🎉 We are pleased to release SeaQuery 0.28.0
! Here are some feature highlights 🌟:
New IdenStatic
trait for static identifier
[#508] Representing a identifier with &'static str
. The IdenStatic
trait looks like this:
pub trait IdenStatic: Iden + Copy + 'static {
fn as_str(&self) -> &'static str;
}
You can derive it easily for your existing Iden
. Just changing the #[derive(Iden)]
into #[derive(IdenStatic)]
.
#[derive(IdenStatic)]
enum User {
Table,
Id,
FirstName,
LastName,
#[iden = "_email"]
Email,
}
assert_eq!(User::Email.as_str(), "_email");
New PgExpr
and SqliteExpr
traits for backend specific expressions
[#519] Postgres specific and SQLite specific expressions are being moved into its corresponding trait. You need to import the trait into scope before construct the expression with those backend specific methods.
// Importing `PgExpr` trait before constructing Postgres expression
use sea_query::{extension::postgres::PgExpr, tests_cfg::*, *};
let query = Query::select()
.columns([Font::Name, Font::Variant, Font::Language])
.from(Font::Table)
.and_where(Expr::val("a").concatenate("b").concat("c").concat("d"))
.to_owned();
assert_eq!(
query.to_string(PostgresQueryBuilder),
r#"SELECT "name", "variant", "language" FROM "font" WHERE 'a' || 'b' || 'c' || 'd'"#
);
// Importing `SqliteExpr` trait before constructing SQLite expression
use sea_query::{extension::sqlite::SqliteExpr, tests_cfg::*, *};
let query = Query::select()
.column(Font::Name)
.from(Font::Table)
.and_where(Expr::col(Font::Name).matches("a"))
.to_owned();
assert_eq!(
query.to_string(SqliteQueryBuilder),
r#"SELECT "name" FROM "font" WHERE "name" MATCH 'a'"#
);
Bug Fixes
- Wrap unions into parenthesis https://github.com/SeaQL/sea-query/pull/498
- Syntax error on empty condition https://github.com/SeaQL/sea-query/pull/505
// given
let (statement, values) = sea_query::Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(Cond::any()
.add(Cond::all()) // empty all() => TRUE
.add(Cond::any()) // empty any() => FALSE
)
.build(sea_query::MysqlQueryBuilder);
// old behavior
assert_eq!(statement, r#"SELECT `id` FROM `glyph`"#);
// new behavior
assert_eq!(
statement,
r#"SELECT `id` FROM `glyph` WHERE (TRUE) OR (FALSE)"#
);
// a complex example
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::all()
.add(Cond::all().not())
.add(Cond::any().not())
.not(),
)
.build(MysqlQueryBuilder);
assert_eq!(
statement,
r#"SELECT `id` FROM `glyph` WHERE NOT ((NOT TRUE) AND (NOT FALSE))"#
);
Breaking Changes
- [#535] MSRV is up to 1.62
# Make sure you're running SeaQuery with Rust 1.62+ 🦀
$ rustup update
- [#492]
ColumnType::Array
definition changed fromArray(SeaRc<Box<ColumnType>>)
toArray(SeaRc<ColumnType>)
- [#475]
Func::*
now returnsFunctionCall
instead ofSimpleExpr
- [#475]
Func::coalesce
now acceptsIntoIterator<Item = SimpleExpr>
instead ofIntoIterator<Item = Into<SimpleExpr>
- [#475] Removed
Expr::arg
andExpr::args
- these functions are no longer needed - [#507] Moved all Postgres specific operators to
PgBinOper
- [#476]
Expr
methods used to acceptsInto<Value>
now acceptsInto<SimpleExpr>
- [#476]
Expr::is_in
,Expr::is_not_in
now acceptsInto<SimpleExpr>
instead ofInto<Value>
and convert it toSimpleExpr::Tuple
instead ofSimpleExpr::Values
- [#475]
Expr::expr
now acceptsInto<SimpleExpr>
instead ofSimpleExpr
- [#519] Moved Postgres specific
Expr
methods to new traitPgExpr
- [#528]
Expr::equals
now acceptsC: IntoColumnRef
instead ofT: IntoIden, C: IntoIden
use sea_query::{*, tests_cfg::*};
let query = Query::select()
.columns([Char::Character, Char::SizeW, Char::SizeH])
.from(Char::Table)
.and_where(
Expr::col((Char::Table, Char::FontId))
- .equals(Font::Table, Font::Id)
+ .equals((Font::Table, Font::Id))
)
.to_owned();
assert_eq!(
query.to_string(MysqlQueryBuilder),
r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`font_id` = `font`.`id`"#
);
- [#525] Removed integer and date time column types' display length / precision option
API Additions
- [#475] Added
SelectStatement::from_function
use sea_query::{tests_cfg::*, *};
let query = Query::select()
.column(ColumnRef::Asterisk)
.from_function(Func::random(), Alias::new("func"))
.to_owned();
assert_eq!(
query.to_string(MysqlQueryBuilder),
r#"SELECT * FROM RAND() AS `func`"#
);
- [#486] Added binary operators from the Postgres
pg_trgm
extension
use sea_query::extension::postgres::PgBinOper;
assert_eq!(
Query::select()
.expr(Expr::col(Font::Name).binary(PgBinOper::WordSimilarity, Expr::value("serif")))
.from(Font::Table)
.to_string(PostgresQueryBuilder),
r#"SELECT "name" <% 'serif' FROM "font""#
);
- [#473] Added
ILIKE
andNOT ILIKE
operators - [#510] Added the
mul
anddiv
methods forSimpleExpr
- [#513] Added the
MATCH
,->
and->>
operators for SQLite
use sea_query::extension::sqlite::SqliteBinOper;
assert_eq!(
Query::select()
.column(Char::Character)
.from(Char::Table)
.and_where(Expr::col(Char::Character).binary(SqliteBinOper::Match, Expr::val("test")))
.build(SqliteQueryBuilder),
(
r#"SELECT "character" FROM "character" WHERE "character" MATCH ?"#.to_owned(),
Values(vec!["test".into()])
)
);
- [#497] Added the
FULL OUTER JOIN
- [#530] Added
PgFunc::get_random_uuid
- [#528] Added
SimpleExpr::eq
,SimpleExpr::ne
,Expr::not_equals
- [#529] Added
PgFunc::starts_with
- [#535] Added
Expr::custom_keyword
andSimpleExpr::not
use sea_query::*;
let query = Query::select()
.expr(Expr::custom_keyword(Alias::new("test")))
.to_owned();
assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT test"#);
assert_eq!(query.to_string(PostgresQueryBuilder), r#"SELECT test"#);
assert_eq!(query.to_string(SqliteQueryBuilder), r#"SELECT test"#);
- [#539] Added
SimpleExpr::like
,SimpleExpr::not_like
andExpr::cast_as
- [#532] Added support for
NULLS NOT DISTINCT
clause for Postgres - [#531] Added
Expr::cust_with_expr
andExpr::cust_with_exprs
use sea_query::{tests_cfg::*, *};
let query = Query::select()
.expr(Expr::cust_with_expr("data @? ($1::JSONPATH)", "hello"))
.to_owned();
assert_eq!(
query.to_string(PostgresQueryBuilder),
r#"SELECT data @? ('hello'::JSONPATH)"#
);
- [#538] Added support for converting
&String
to Value
Miscellaneous Enhancements
- [#475] New struct
FunctionCall
which hold function and arguments - [#503] Support
BigDecimal
,IpNetwork
andMacAddress
forsea-query-postgres
- [#511] Made
value::with_array
module public and therefore makingNotU8
trait public - [#524] Drop the
Sized
requirement on implementers ofSchemaBuilders
Integration Examples
SeaQuery plays well with the other crates in the rust ecosystem.
- Postgres Example
- Rusqlite Example
- SQLx Any Example
- SQLx Postgres Example
- SQLx MySql Example
- SQLx Sqlite Example
Community
SeaQL is a community driven project. We welcome you to participate, contribute and together build for Rust's future.
Top comments (0)