mirror of
https://github.com/diesel-rs/diesel.git
synced 2024-10-04 01:28:13 +03:00
Allow strings starting with env:
and dotenv:
to be used
Due to implementation details of the macros 1.1 port, we will no longer be able to take arbitrary macros as arguments to `infer_schema!` and `infer_table_from_schema!`. We can only take literal values. In practice, the only two useful things to take here are `env!` and `dotenv!`. We can special case those and represent them as strings instead. We cannot detect whether people are attempting to use `env!` here, as it is opaque to us by the time we reach our code in the old procedural macros. However, the string form will be the only form that works in the macros 1.1 implementation, and it will be deprecated along with the syntex crate when macros 1.1 is stable.
This commit is contained in:
parent
f4cbb2accd
commit
f954369e92
@ -20,6 +20,13 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
|
||||
* Diesel CLI can now generate bash completion. See [the readme][bash completion]
|
||||
for details.
|
||||
|
||||
* `infer_schema!` and `infer_table_from_schema!` can now take `"env:foo"`
|
||||
instead of `env!("foo")` and `"dotenv:foo"` instead of `dotenv!("foo")`. The
|
||||
use of `dotenv` requires the `dotenv` feature on `diesel_codegen`, which is
|
||||
included by default. Using `env!` and `dotenv!` will no longer work with
|
||||
`diesel_codegen`. They continue to work with `diesel_codgen_syntex`, but that
|
||||
crate will be deprecated when Macros 1.1 is in the beta channel for Rust.
|
||||
|
||||
[bash completion]: https://github.com/diesel-rs/diesel/blob/b1a0d9901f0f2a8c8d530ccba8173b57f332b891/diesel_cli/README.md#bash-completion
|
||||
|
||||
### Changed
|
||||
|
@ -10,10 +10,11 @@ repository = "https://github.com/diesel-rs/diesel/tree/master/diesel_codegen"
|
||||
keywords = ["orm", "database", "postgres", "sql", "codegen"]
|
||||
|
||||
[dependencies]
|
||||
diesel_codegen_syntex = { version = "0.7.0", default-features = false }
|
||||
diesel_codegen_syntex = { path = "../diesel_codegen_syntex", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["postgres"]
|
||||
default = ["postgres", "dotenv"]
|
||||
dotenv = ["diesel_codegen_syntex/dotenv"]
|
||||
postgres = ["diesel_codegen_syntex/postgres"]
|
||||
sqlite = ["diesel_codegen_syntex/sqlite"]
|
||||
|
||||
|
@ -18,13 +18,14 @@ syntex_syntax = { version = "0.44.0", optional = true }
|
||||
syntex = { version = "0.44.0", optional = true }
|
||||
syntex_syntax = { version = "0.44.0", optional = true }
|
||||
diesel = { version = "0.7.0", default-features = false }
|
||||
dotenv = { version = "0.8.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3.4"
|
||||
dotenv = "0.8.0"
|
||||
|
||||
[features]
|
||||
default = ["with-syntex", "postgres"]
|
||||
default = ["with-syntex", "postgres", "dotenv"]
|
||||
with-syntex = ["syntex", "syntex_syntax"]
|
||||
postgres = ["diesel/postgres"]
|
||||
sqlite = ["diesel/sqlite"]
|
||||
|
@ -17,6 +17,9 @@ extern crate syntax;
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
extern crate rustc_plugin;
|
||||
|
||||
#[cfg(feature = "dotenv")]
|
||||
extern crate dotenv;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
|
||||
|
||||
|
54
diesel_codegen_syntex/src/schema_inference/database_url.rs
Normal file
54
diesel_codegen_syntex/src/schema_inference/database_url.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn extract_database_url<'a>(url: &'a str) -> Result<Cow<'a, str>, String> {
|
||||
if url.starts_with("dotenv:") {
|
||||
try!(load_dotenv_file());
|
||||
return extract_database_url(&url[3..]);
|
||||
} else if url.starts_with("env:") {
|
||||
let var_name = &url[4..];
|
||||
env::var(var_name)
|
||||
.map(Cow::Owned)
|
||||
.map_err(|e| {
|
||||
format!("Failed to load environment variable {}: {}",
|
||||
var_name, e.description())
|
||||
})
|
||||
} else {
|
||||
Ok(Cow::Borrowed(url))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "dotenv")]
|
||||
fn load_dotenv_file() -> Result<(), String> {
|
||||
use dotenv::dotenv;
|
||||
|
||||
dotenv().ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dotenv"))]
|
||||
fn load_dotenv_file() -> Result<(), String> {
|
||||
Err(String::from("The dotenv feature is required to use strings starting \
|
||||
with `dotenv:`"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_database_url_returns_the_given_string() {
|
||||
assert_eq!("foo", extract_database_url("foo").unwrap());
|
||||
assert_eq!("bar", extract_database_url("bar").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_database_url_returns_env_vars() {
|
||||
env::set_var("foo", "lololol");
|
||||
env::set_var("bar", "trolololol");
|
||||
assert_eq!("lololol", extract_database_url("env:foo").unwrap());
|
||||
assert_eq!("trolololol", extract_database_url("env:bar").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_database_url_errors_if_env_var_is_unset() {
|
||||
env::remove_var("foo");
|
||||
assert!(extract_database_url("env:foo").is_err());
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
mod data_structures;
|
||||
mod database_url;
|
||||
#[cfg(feature = "postgres")]
|
||||
mod pg;
|
||||
#[cfg(feature = "sqlite")]
|
||||
@ -14,6 +15,7 @@ use syntax::util::small_vector::SmallVector;
|
||||
use syntax::tokenstream::TokenTree;
|
||||
|
||||
use self::data_structures::*;
|
||||
use self::database_url::extract_database_url;
|
||||
use util::comma_delimited_tokens;
|
||||
|
||||
pub fn expand_load_table<'cx>(
|
||||
@ -41,7 +43,7 @@ pub fn load_table_body<T: Iterator<Item=P<ast::Expr>>>(
|
||||
sp: Span,
|
||||
exprs: &mut T,
|
||||
) -> Result<Box<MacResult>, Box<MacResult>> {
|
||||
let database_url = try!(next_str_lit(cx, sp, exprs));
|
||||
let database_url = try!(database_url(cx, sp, exprs));
|
||||
let table_name = try!(next_str_lit(cx, sp, exprs));
|
||||
let connection = try!(establish_connection(cx, sp, &database_url));
|
||||
table_macro_call(cx, sp, &connection, &table_name)
|
||||
@ -69,7 +71,7 @@ pub fn infer_schema_body<T: Iterator<Item=P<ast::Expr>>>(
|
||||
sp: Span,
|
||||
exprs: &mut T,
|
||||
) -> Result<Box<MacResult>, Box<MacResult>> {
|
||||
let database_url = try!(next_str_lit(cx, sp, exprs));
|
||||
let database_url = try!(database_url(cx, sp, exprs));
|
||||
let connection = try!(establish_connection(cx, sp, &database_url));
|
||||
let table_names = load_table_names(&connection).unwrap();
|
||||
let impls = table_names.into_iter()
|
||||
@ -226,3 +228,18 @@ fn get_primary_keys(conn: &InferConnection, table_name: &str) -> QueryResult<Vec
|
||||
InferConnection::Pg(ref c) => pg::get_primary_keys(c, table_name),
|
||||
}
|
||||
}
|
||||
|
||||
fn database_url<T: Iterator<Item=P<ast::Expr>>>(
|
||||
cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
exprs: &mut T,
|
||||
) -> Result<String, Box<MacResult>> {
|
||||
let database_url = try!(next_str_lit(cx, sp, exprs));
|
||||
match extract_database_url(&database_url) {
|
||||
Ok(s) => Ok(s.into_owned()),
|
||||
Err(msg) => {
|
||||
cx.span_err(sp, &msg);
|
||||
Err(DummyResult::any(sp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ assert_matches = "1.0.1"
|
||||
chrono = { version = "^0.2.17" }
|
||||
diesel = { path = "../diesel", default-features = false, features = ["quickcheck", "chrono", "uuid"] }
|
||||
diesel_codegen = { version = "0.7.2", optional = true }
|
||||
diesel_codegen_old = { path = "../diesel_codegen_old", default-features = false, optional = true }
|
||||
diesel_codegen_old = { path = "../diesel_codegen_old", default-features = false, features = ["dotenv"], optional = true }
|
||||
dotenv_macros = { version = "0.9.0", optional = true }
|
||||
quickcheck = { version = "0.3.1", features = ["unstable"] }
|
||||
uuid = { version = ">=0.2.0, <0.4.0" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
use diesel::*;
|
||||
|
||||
infer_schema!(dotenv!("DATABASE_URL"));
|
||||
infer_schema!("dotenv:DATABASE_URL");
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Queryable, Identifiable, Insertable, AsChangeset, Associations)]
|
||||
#[has_many(posts)]
|
||||
|
Loading…
Reference in New Issue
Block a user