deuterium icon indicating copy to clipboard operation
deuterium copied to clipboard

How to use placeholders in where clauses?

Open gsingh93 opened this issue 9 years ago • 7 comments

Looking at some examples, I can see how to build a query with placeholders, but I don't see how to actually fill in those place holders. It looks like I need to make a new SqlContext that wraps an SqlAdapter, and I can construct new, empty ones, but can I use the values I already supplied in the where clause?

Unrelated question, does this only work for postgres or should this work for any SQL implementation?

gsingh93 avatar May 04 '15 01:05 gsingh93

ping @s-panferov

gsingh93 avatar May 13 '15 19:05 gsingh93

@gsingh93 hello. sorry for the delay with answer. you can't actually fill placeholders in a SQL Query itself. Instead, you need to pass your query to your database adapter and receive a prepared statement. See https://github.com/sfackler/rust-postgres for examples.

s-panferov avatar May 15 '15 06:05 s-panferov

Ok, that's what I thought. I don't have experience with databases other than MySQL, will the SQL generated by deuterium be compatible with MySQL? What about other databases like SQLite?

If not, do you have plans to create a backend independent query builder?

gsingh93 avatar May 15 '15 18:05 gsingh93

@gsingh93 mysql has another placeholder format, so it needs its own adapter. I have no time right now to make it, but it's quite simple. See example in https://github.com/deuterium-orm/deuterium/blob/master/src/sql/adapter/mod.rs. All outer stuff in deuterium is standard for all the databases.

s-panferov avatar May 16 '15 10:05 s-panferov

@s-panferov I added a mysql adapter in #11, take a look. Also, why do the predicates take values if the values aren't used when building the SQL statement?

gsingh93 avatar May 27 '15 20:05 gsingh93

@gsingh93

The idea was to hold them until they can be used at the final stage. Look at the file:

https://github.com/deuterium-orm/deuterium-orm/blob/master/src/adapter/postgres.rs https://github.com/deuterium-orm/deuterium-orm/blob/master/src/adapter/postgres.rs#L92

You can extract them and pass to the placeholders:

https://github.com/deuterium-orm/deuterium-orm/blob/master/src/adapter/postgres.rs#L38-L58

s-panferov avatar Jun 03 '15 05:06 s-panferov

Ok, I think I finally understand what's going on. I think a simple example like this should be added to the README:

extern crate deuterium;

use deuterium::*;

fn main() {
    let table = TableDef::new("Person");
    let mut query = table.select_all();
    let name_column = NamedField::<String>::field_of("name", &table);
    let age_column = NamedField::<i32>::field_of("age", &table);
    query = query.where_(name_column.is("Joe".to_owned()));
    query = query.where_(age_column.is(22));

    // sql::MysqlAdapter is also available
    let mut postgres_context = SqlContext::new(Box::new(sql::PostgreSqlAdapter));
    println!("{}", query.to_final_sql(&mut postgres_context));
    println!("arguments: {:?}", postgres_context.data());
}

But now even though I can print out the arguments, I can't actually convert them into types other libraries can use to actually execute the statements (assuming I'm not using the postgres adapter). Is there a way to convert the context data into primitive types, like strings and integers (for the case when the postgres features is enabled and disabled)? If so, I can add that to this example.

gsingh93 avatar Jun 03 '15 17:06 gsingh93