s-panferov / deuterium

Fully typed SQL query builder for Rust [deprecated]
MIT License
168 stars 12 forks source link

How to use placeholders in where clauses? #10

Open gsingh93 opened 9 years ago

gsingh93 commented 9 years ago

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 commented 9 years ago

ping @s-panferov

s-panferov commented 9 years ago

@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.

gsingh93 commented 9 years ago

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?

s-panferov commented 9 years ago

@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.

gsingh93 commented 9 years ago

@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?

s-panferov commented 9 years ago

@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

gsingh93 commented 9 years ago

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.