SeaQL / sea-query

🔱 A dynamic SQL query builder for MySQL, Postgres and SQLite
https://www.sea-ql.org
Other
1.18k stars 195 forks source link

Query `Insert` does not work well with Rusqlite `prepare()` #801

Closed XHanL closed 2 months ago

XHanL commented 3 months ago

Description

The Rusqlite prepare() + execute() method need format like:

INSERT INTO \"virtual_file\" (\"path\", \"name\") VALUES (?, ?)

However, if we use Query::insert() without values_panic(), the build string look like this:

INSERT INTO \"virtual_file\" (\"path\", \"name\") /* NO VALUE PART */

If we execute this prepared stmt, the DB return error

SqliteFailure(Error { code: Unknown, extended_code: 1 }, Some("incomplete input"))

We have to add empty values manually like this, It's unfriendly and confusing():

.values_panic(["".into(), "".into(), ...])

Steps to Reproduce

#[derive(Iden)]
pub enum VirtualFile {
    Table,
    Id,
    Path,
    Name,
}

fn test_insert() {
    let conn = Connection::open("../sqlite.db").unwrap();

    let sql = [Table::create()
        .table(VirtualFile::Table)
        .if_not_exists()
        .col(
            ColumnDef::new(VirtualFile::Id)
                .integer()
                .primary_key()
                .auto_increment(),
        )
        .col(ColumnDef::new(VirtualFile::Path).string().not_null())
        .col(ColumnDef::new(VirtualFile::Name).string().not_null())
        .build(SqliteQueryBuilder)];

    conn.execute_batch(&sql.join("; ")).unwrap();

    let (sql, _) = Query::insert()
        .into_table(VirtualFile::Table)
        .columns([VirtualFile::Path, VirtualFile::Name])
        //.values_panic(["".into(), "".into()]) // need to add this manually for insert stmt prepare
        .build(SqliteQueryBuilder);

    println!(">>> {:?}", &sql);

    let mut stmt = conn.prepare(&sql).unwrap();
    stmt.execute(("path", "name")).unwrap();
}

Expected Behavior

When we use Query::insert() without values_panic(), the builder will generate VALUES (?, ?, ...) based on columns,

INSERT INTO \"virtual_file\" (\"path\", \"name\") VALUES (?, ?)

Actual Behavior

When we use Query::insert() without values_panic(), the builder generate

INSERT INTO \"virtual_file\" (\"path\", \"name\")

Reproduces How Often

Versions