Skip to content

Commit

Permalink
Merge pull request #4071 from weiznich/prepare/2.2.1
Browse files Browse the repository at this point in the history
Prepare a diesel 2.2.1 release
  • Loading branch information
weiznich authored Jun 13, 2024
2 parents 197f06d + 8c47c6f commit 08be4f2
Show file tree
Hide file tree
Showing 24 changed files with 352 additions and 63 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,22 @@ Increasing the minimal supported Rust version will always be coupled at least wi

## Unreleased

## [2.2.1] 2024-06-12

## Fixed

* Fixed using `#[dsl::auto_type]` with functions that accept reference arguments
* Fixed using `#[derive(Queryable)]` with structs that use a type named `Row` as field type
* Fixed a regression that prevented using `mysqlclient-sys` 0.2.x with diesel 2.2
* Fixed connecting to postgres database using the scram-sha-256 authentication method on windows while using the bundled postgres builds
* Improved the error messages in diesel-cli for cases where a file/folder was not found
* Fixed several version detection bugs in mysqlclient-sys to use pre-generated bindings in more situations

## [2.2.0] 2024-05-31

### Added

* Support `[print_schema] exclude_custom_type_definitions = ["Vector"]`. If a `custom type` matches one element on the list it's skipped.
* Support `[print_schema] except_custom_type_definitions = ["Vector"]`. If a `custom type` matches one element on the list it's skipped.
* Added automatic usage of all sqlite `rowid` aliases when no explicit primary key is defined for `print-schema`
* Added a `#[dsl::auto_type]` attribute macro, allowing to infer type of query fragment functions
* Added the same type inference on `Selectable` derives, which allows skipping specifying `select_expression_type` most of the time, in turn enabling most queries to be written using just a `Selectable` derive.
Expand Down
6 changes: 3 additions & 3 deletions diesel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "diesel"
version = "2.2.0"
version = "2.2.1"
license = "MIT OR Apache-2.0"
description = "A safe, extensible ORM and Query Builder for PostgreSQL, SQLite, and MySQL"
readme = "README.md"
Expand All @@ -25,10 +25,10 @@ byteorder = { version = "1.0", optional = true }
chrono = { version = "0.4.20", optional = true, default-features = false, features = ["clock", "std"] }
libc = { version = "0.2.0", optional = true }
libsqlite3-sys = { version = ">=0.17.2, <0.29.0", optional = true, features = ["bundled_bindings"] }
mysqlclient-sys = { version = ">=0.2.5, <0.4.0", optional = true }
mysqlclient-sys = { version = ">=0.2.5, <0.5.0", optional = true }
mysqlclient-src = { version = "0.1.0", optional = true }
pq-sys = { version = ">=0.4.0, <0.7.0", optional = true }
pq-src = { version = "0.2", optional = true }
pq-src = { version = "0.3", optional = true }
quickcheck = { version = "1.0.3", optional = true }
serde_json = { version = ">=0.8.0, <2.0", optional = true }
url = { version = "2.1.0", optional = true }
Expand Down
10 changes: 6 additions & 4 deletions diesel/src/mysql/connection/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,13 @@ impl BindData {
length,
capacity,
flags,
is_null: ffi::FALSE,
is_truncated: Some(ffi::FALSE),
is_null: super::raw::ffi_false(),
is_truncated: Some(super::raw::ffi_false()),
}
}

fn is_truncated(&self) -> bool {
self.is_truncated.unwrap_or(ffi::FALSE) != ffi::FALSE
self.is_truncated.unwrap_or(super::raw::ffi_false()) != super::raw::ffi_false()
}

fn is_fixed_size_buffer(&self) -> bool {
Expand Down Expand Up @@ -711,7 +711,9 @@ impl From<(ffi::enum_field_types, Flags)> for MysqlType {
something has gone wrong. Please open an issue at \
the diesel github repo."
),

// depending on the bindings version
// there might be no unlisted field type
#[allow(unreachable_patterns)]
t => unreachable!(
"Unsupported type encountered: {t:?}. \
If you ever see this error, something has gone wrong. \
Expand Down
15 changes: 14 additions & 1 deletion diesel/src/mysql/connection/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ use crate::result::{ConnectionError, ConnectionResult, QueryResult};

pub(super) struct RawConnection(NonNull<ffi::MYSQL>);

// old versions of mysqlclient do not expose
// ffi::FALSE, so we need to have our own compatibility
// wrapper here
//
// Depending on the bindings version ffi::my_bool
// might be an actual bool or a i8. For the former
// case `default()` corresponds to `false` for the later
// to `0` which is both interpreted as false
#[inline(always)]
pub(super) fn ffi_false() -> ffi::my_bool {
Default::default()
}

impl RawConnection {
pub(super) fn new() -> Self {
perform_thread_unsafe_library_initialization();
Expand Down Expand Up @@ -175,7 +188,7 @@ impl RawConnection {
}

fn more_results(&self) -> bool {
unsafe { ffi::mysql_more_results(self.0.as_ptr()) != ffi::FALSE }
unsafe { ffi::mysql_more_results(self.0.as_ptr()) != ffi_false() }
}

fn next_result(&self) -> QueryResult<()> {
Expand Down
4 changes: 2 additions & 2 deletions diesel_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "diesel_cli"
version = "2.2.0"
version = "2.2.1"
license = "MIT OR Apache-2.0"
description = "Provides the CLI for the Diesel crate"
readme = "README.md"
Expand Down Expand Up @@ -47,7 +47,7 @@ url = { version = "2.2.2" }
libsqlite3-sys = { version = ">=0.17.2, <0.29.0", optional = true }
pq-sys = { version = ">=0.4, <0.7.0", optional = true }
openssl-sys = { version = "0.9.93", features = ["vendored"], optional = true }
mysqlclient-sys = { version = ">=0.2.5, <0.4.0", optional = true }
mysqlclient-sys = { version = "0.4.0", optional = true }
diffy = "0.3.0"
regex = "1.0.6"
serde_regex = "1.1"
Expand Down
3 changes: 2 additions & 1 deletion diesel_cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ impl Config {
let path = Self::file_path(matches);

if path.exists() {
let content = fs::read_to_string(&path)?;
let content = fs::read_to_string(&path)
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;
let mut result = toml::from_str::<Self>(&content)?;
result.set_relative_path_base(
path.parent()
Expand Down
28 changes: 19 additions & 9 deletions diesel_cli/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use diesel_migrations::FileBasedMigrations;

use std::env;
#[cfg(feature = "postgres")]
use std::fs::{self, File};
#[cfg(feature = "postgres")]
use std::io::Write;
use std::fs::{self};
use std::path::Path;

#[derive(Copy, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -242,11 +240,21 @@ fn create_default_migration_if_needed(
match Backend::for_url(database_url) {
#[cfg(feature = "postgres")]
Backend::Pg => {
fs::create_dir_all(&initial_migration_path)?;
let mut up_sql = File::create(initial_migration_path.join("up.sql"))?;
up_sql.write_all(include_bytes!("setup_sql/postgres/initial_setup/up.sql"))?;
let mut down_sql = File::create(initial_migration_path.join("down.sql"))?;
down_sql.write_all(include_bytes!("setup_sql/postgres/initial_setup/down.sql"))?;
fs::create_dir_all(&initial_migration_path).map_err(|e| {
crate::errors::Error::IoError(e, Some(initial_migration_path.clone()))
})?;
let up_sql_file = initial_migration_path.join("up.sql");
std::fs::write(
&up_sql_file,
include_bytes!("setup_sql/postgres/initial_setup/up.sql"),
)
.map_err(|e| crate::errors::Error::IoError(e, Some(up_sql_file.clone())))?;
let down_sql_file = initial_migration_path.join("down.sql");
std::fs::write(
&down_sql_file,
include_bytes!("setup_sql/postgres/initial_setup/down.sql"),
)
.map_err(|e| crate::errors::Error::IoError(e, Some(down_sql_file.clone())))?;
}
_ => {} // No default migration for this backend
}
Expand Down Expand Up @@ -296,7 +304,9 @@ fn drop_database(database_url: &str) -> Result<(), crate::errors::Error> {
Backend::Sqlite => {
if Path::new(database_url).exists() {
println!("Dropping database: {database_url}");
std::fs::remove_file(database_url)?;
std::fs::remove_file(database_url).map_err(|e| {
crate::errors::Error::IoError(e, Some(std::path::PathBuf::from(database_url)))
})?;
}
}
#[cfg(feature = "mysql")]
Expand Down
10 changes: 8 additions & 2 deletions diesel_cli/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub enum Error {
ProjectRootNotFound(PathBuf),
#[error("The --database-url argument must be passed, or the DATABASE_URL environment variable must be set.")]
DatabaseUrlMissing,
#[error("Encountered an IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Encountered an IO error: {0} {}", print_optional_path(.1))]
IoError(#[source] std::io::Error, Option<PathBuf>),
#[error("Failed to execute a database query: {0}")]
QueryError(#[from] diesel::result::Error),
#[error("Failed to run migrations: {0}")]
Expand Down Expand Up @@ -63,3 +63,9 @@ pub enum Error {
#[error("No `[print_schema.{0}]` entries in your diesel.toml")]
NoSchemaKeyFound(String),
}

fn print_optional_path(path: &Option<PathBuf>) -> String {
path.as_ref()
.map(|p| format!(" for `{}`", p.display()))
.unwrap_or_default()
}
30 changes: 15 additions & 15 deletions diesel_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,10 @@ fn create_config_file(
"dir = \"migrations\"",
&format!("dir = \"{}\"", migrations_dir_toml_string),
);
let mut file = fs::File::create(path)?;
file.write_all(modified_content.as_bytes())?;
let mut file = fs::File::create(&path)
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;
file.write_all(modified_content.as_bytes())
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;
}

Ok(())
Expand Down Expand Up @@ -193,13 +195,15 @@ fn generate_completions_command(matches: &ArgMatches) {
/// Returns a `DatabaseError::ProjectRootNotFound` if no Cargo.toml is found.
fn create_migrations_directory(path: &Path) -> Result<PathBuf, crate::errors::Error> {
println!("Creating migrations directory at: {}", path.display());
fs::create_dir_all(path)?;
fs::File::create(path.join(".keep"))?;
fs::create_dir_all(path)
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;
let keep_path = path.join(".keep");
fs::File::create(&keep_path).map_err(|e| crate::errors::Error::IoError(e, Some(keep_path)))?;
Ok(path.to_owned())
}

fn find_project_root() -> Result<PathBuf, crate::errors::Error> {
let current_dir = env::current_dir()?;
let current_dir = env::current_dir().map_err(|e| crate::errors::Error::IoError(e, None))?;
search_for_directory_containing_file(&current_dir, "diesel.toml")
.or_else(|_| search_for_directory_containing_file(&current_dir, "Cargo.toml"))
}
Expand Down Expand Up @@ -260,37 +264,33 @@ fn run_infer_schema(matches: &ArgMatches) -> Result<(), crate::errors::Error> {

#[tracing::instrument]
fn regenerate_schema_if_file_specified(matches: &ArgMatches) -> Result<(), crate::errors::Error> {
use std::io::Read;

tracing::debug!("Regenerate schema if required");

let config = Config::read(matches)?.print_schema;
for config in config.all_configs.values() {
if let Some(ref path) = config.file {
let mut connection = InferConnection::from_matches(matches)?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
fs::create_dir_all(parent)
.map_err(|e| crate::errors::Error::IoError(e, Some(parent.to_owned())))?;
}

if matches.get_flag("LOCKED_SCHEMA") {
let mut buf = Vec::new();
print_schema::run_print_schema(&mut connection, config, &mut buf)?;

let mut old_buf = Vec::new();
let mut file = fs::File::open(path)?;
file.read_to_end(&mut old_buf)?;
let old_buf = std::fs::read(path)
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;

if buf != old_buf {
return Err(crate::errors::Error::SchemaWouldChange(
path.display().to_string(),
));
}
} else {
use std::io::Write;

let mut file = fs::File::create(path)?;
let schema = print_schema::output_schema(&mut connection, config)?;
file.write_all(schema.as_bytes())?;
std::fs::write(path, schema.as_bytes())
.map_err(|e| crate::errors::Error::IoError(e, Some(path.to_owned())))?;
}
}
}
Expand Down
8 changes: 3 additions & 5 deletions diesel_cli/src/migrations/diff_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use diesel::query_builder::QueryBuilder;
use diesel::QueryResult;
use diesel_table_macro_syntax::{ColumnDef, TableDecl};
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use syn::visit::Visit;

Expand Down Expand Up @@ -37,9 +35,9 @@ pub fn generate_sql_based_on_diff_schema(
let project_root = crate::find_project_root()?;

let schema_path = project_root.join(schema_file_path);
let mut schema_file = File::open(schema_path)?;
let mut content = String::new();
schema_file.read_to_string(&mut content)?;
let content = std::fs::read_to_string(&schema_path)
.map_err(|e| crate::errors::Error::IoError(e, Some(schema_path.clone())))?;

let syn_file = syn::parse_file(&content)?;

let mut tables_from_schema = SchemaCollector::default();
Expand Down
27 changes: 18 additions & 9 deletions diesel_cli/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ pub(super) fn run_migration_command(matches: &ArgMatches) -> Result<(), crate::e
let version = migration_version(args);
let versioned_name = format!("{version}_{migration_name}");
let migration_dir = migrations_dir(matches)?.join(versioned_name);
fs::create_dir(&migration_dir)?;
fs::create_dir(&migration_dir)
.map_err(|e| crate::errors::Error::IoError(e, Some(migration_dir.clone())))?;

match args
.get_one::<String>("MIGRATION_FORMAT")
Expand Down Expand Up @@ -164,27 +165,35 @@ fn generate_sql_migration(
) -> Result<(), crate::errors::Error> {
use std::io::Write;

let migration_dir_relative =
crate::convert_absolute_path_to_relative(path, &env::current_dir()?);
let migration_dir_relative = crate::convert_absolute_path_to_relative(
path,
&env::current_dir().map_err(|e| crate::errors::Error::IoError(e, None))?,
);

let up_path = path.join("up.sql");
println!(
"Creating {}",
migration_dir_relative.join("up.sql").display()
);
let mut up = fs::File::create(up_path)?;
up.write_all(b"-- Your SQL goes here\n")?;
up.write_all(up_sql.as_bytes())?;
let mut up = fs::File::create(&up_path)
.map_err(|e| crate::errors::Error::IoError(e, Some(up_path.clone())))?;
up.write_all(b"-- Your SQL goes here\n")
.map_err(|e| crate::errors::Error::IoError(e, Some(up_path.clone())))?;
up.write_all(up_sql.as_bytes())
.map_err(|e| crate::errors::Error::IoError(e, Some(up_path.clone())))?;

if with_down {
let down_path = path.join("down.sql");
println!(
"Creating {}",
migration_dir_relative.join("down.sql").display()
);
let mut down = fs::File::create(down_path)?;
down.write_all(b"-- This file should undo anything in `up.sql`\n")?;
down.write_all(down_sql.as_bytes())?;
let mut down = fs::File::create(&down_path)
.map_err(|e| crate::errors::Error::IoError(e, Some(down_path.clone())))?;
down.write_all(b"-- This file should undo anything in `up.sql`\n")
.map_err(|e| crate::errors::Error::IoError(e, Some(up_path.clone())))?;
down.write_all(down_sql.as_bytes())
.map_err(|e| crate::errors::Error::IoError(e, Some(up_path.clone())))?;
}
Ok(())
}
Expand Down
6 changes: 4 additions & 2 deletions diesel_cli/src/print_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ pub fn run_print_schema<W: IoWrite>(
) -> Result<(), crate::errors::Error> {
let schema = output_schema(connection, config)?;

output.write_all(schema.as_bytes())?;
output
.write_all(schema.as_bytes())
.map_err(|e| crate::errors::Error::IoError(e, None))?;
Ok(())
}

Expand Down Expand Up @@ -272,7 +274,7 @@ pub fn output_schema(
patch_file.display(),
e
);
return Err(e.into());
return Err(crate::errors::Error::IoError(e, Some(patch_file.clone())));
}
};
let patch = diffy::Patch::from_str(&patch)?;
Expand Down
23 changes: 23 additions & 0 deletions diesel_compile_tests/tests/fail/auto_type_life_times.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use diesel::dsl::*;
use diesel::prelude::*;

diesel::table! {
users {
id -> Integer,
name -> Text,
}
}

#[auto_type]
fn with_lifetime(name: &'_ str) -> _ {
users::table.filter(users::name.eq(name))
}

#[auto_type]
fn with_lifetime2(name: &str) -> _ {
users::table.filter(users::name.eq(name))
}

fn main() {
println!("Hello, world!");
}
Loading

0 comments on commit 08be4f2

Please sign in to comment.