mirror of
https://github.com/launchbadge/sqlx.git
synced 2026-04-21 05:56:50 +00:00
Hotfix 0.8.5 (#3824)
* fix(cli): correctly handle `.env` files again * feat(ci): add functionality tests for sqlx-cli (MySQL) * feat(ci): add functionality tests for sqlx-cli (Postgres) * feat(ci): add functionality tests for sqlx-cli (SQLite) * chore: prepare 0.8.5 release * feat(ci): run `test-attr` tests twice to catch #3825 * fix: correct bugs in MySQL implementation of `#[sqlx::test]`
This commit is contained in:
233
.github/workflows/sqlx-cli.yml
vendored
233
.github/workflows/sqlx-cli.yml
vendored
@@ -33,8 +33,8 @@ jobs:
|
||||
--manifest-path sqlx-cli/Cargo.toml
|
||||
--target-dir target/beta/
|
||||
|
||||
test:
|
||||
name: Test
|
||||
integration-test:
|
||||
name: Integration Test
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@@ -57,6 +57,235 @@ jobs:
|
||||
|
||||
- run: cargo test --manifest-path sqlx-cli/Cargo.toml
|
||||
|
||||
test-mysql:
|
||||
name: Functional Test (MySQL)
|
||||
runs-on: ubuntu-latest
|
||||
# Deliberately not using `tests/docker-compose.yml` because that sets up the database automatically.
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8
|
||||
ports:
|
||||
- 3306:3306
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
env:
|
||||
BASE_URL: mysql://root:password@localhost
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
run: rustup show active-toolchain || rustup toolchain install
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install SQLx-CLI
|
||||
run:
|
||||
cargo install --locked --debug --path sqlx-cli
|
||||
|
||||
- name: Basic Test
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test1
|
||||
run: |
|
||||
sqlx db setup --source=tests/mysql/migrations
|
||||
|
||||
sqlx mig info --source=tests/mysql/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test .env
|
||||
run: |
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test2" > .env
|
||||
|
||||
sqlx db setup --source=tests/mysql/migrations
|
||||
|
||||
sqlx mig info --source=tests/mysql/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test --no-dotenv
|
||||
run: |
|
||||
# Allow subcommands to fail
|
||||
set +e
|
||||
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test3" > .env
|
||||
|
||||
ERROR=$(sqlx db setup --no-dotenv --source=tests/mysql/migrations)
|
||||
|
||||
if [[ "$ERROR" == *"--database-url"* ]]; then
|
||||
exit 0
|
||||
else
|
||||
echo "Unexpected error from sqlx-cli: $ERROR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Reversible Migrations
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test4
|
||||
run: |
|
||||
sqlx db setup --source=tests/mysql/migrations_reversible
|
||||
|
||||
INFO_BEFORE=$(sqlx mig info --source=tests/mysql/migrations_reversible)
|
||||
|
||||
sqlx mig revert --target-version=0 --source=tests/mysql/migrations_reversible
|
||||
|
||||
INFO_AFTER=$(sqlx mig info --source=tests/mysql/migrations_reversible)
|
||||
|
||||
if [[ "$INFO_BEFORE" == "$INFO_AFTER" ]]; then
|
||||
echo "Error: migration info is identical before and after migrating: $INFO_BEFORE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test-postgres:
|
||||
name: Functional Test (PostgreSQL)
|
||||
runs-on: ubuntu-latest
|
||||
# Deliberately not using `tests/docker-compose.yml` because that sets up the database automatically.
|
||||
services:
|
||||
mysql:
|
||||
image: postgres:17
|
||||
ports:
|
||||
- 5432:5432
|
||||
env:
|
||||
POSTGRES_PASSWORD: password
|
||||
env:
|
||||
BASE_URL: postgres://postgres:password@localhost
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
run: rustup show active-toolchain || rustup toolchain install
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install SQLx-CLI
|
||||
run:
|
||||
cargo install --locked --debug --path sqlx-cli
|
||||
|
||||
- name: Basic Test
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test1
|
||||
run: |
|
||||
sqlx db setup --source=tests/postgres/migrations
|
||||
|
||||
sqlx mig info --source=tests/postgres/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test .env
|
||||
run: |
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test2" > .env
|
||||
|
||||
sqlx db setup --source=tests/postgres/migrations
|
||||
|
||||
sqlx mig info --source=tests/postgres/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test --no-dotenv
|
||||
run: |
|
||||
# Allow subcommands to fail
|
||||
set +e
|
||||
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test3" > .env
|
||||
|
||||
ERROR=$(sqlx db setup --no-dotenv --source=tests/postgres/migrations)
|
||||
|
||||
if [[ "$ERROR" == *"--database-url"* ]]; then
|
||||
exit 0
|
||||
else
|
||||
echo "Unexpected error from sqlx-cli: $ERROR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Reversible Migrations
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test4
|
||||
run: |
|
||||
sqlx db setup --source=tests/postgres/migrations_reversible
|
||||
|
||||
INFO_BEFORE=$(sqlx mig info --source=tests/postgres/migrations_reversible)
|
||||
|
||||
sqlx mig revert --target-version=0 --source=tests/postgres/migrations_reversible
|
||||
|
||||
INFO_AFTER=$(sqlx mig info --source=tests/postgres/migrations_reversible)
|
||||
|
||||
if [[ "$INFO_BEFORE" == "$INFO_AFTER" ]]; then
|
||||
echo "Error: migration info is identical before and after migrating: $INFO_BEFORE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test-sqlite:
|
||||
name: Functional Test (SQLite)
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
BASE_URL: sqlite://.
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
run: rustup show active-toolchain || rustup toolchain install
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install SQLx-CLI
|
||||
run:
|
||||
cargo install --locked --debug --path sqlx-cli
|
||||
|
||||
- name: Basic Test
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test1
|
||||
run: |
|
||||
sqlx db setup --source=tests/sqlite/migrations
|
||||
|
||||
sqlx mig info --source=tests/sqlite/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test .env
|
||||
run: |
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test2" > .env
|
||||
|
||||
sqlx db setup --source=tests/sqlite/migrations
|
||||
|
||||
sqlx mig info --source=tests/sqlite/migrations
|
||||
|
||||
sqlx db drop -y
|
||||
|
||||
- name: Test --no-dotenv
|
||||
run: |
|
||||
# Allow subcommands to fail
|
||||
set +e
|
||||
|
||||
echo "DATABASE_URL=${{ env.BASE_URL }}/test3" > .env
|
||||
|
||||
ERROR=$(sqlx db setup --no-dotenv --source=tests/sqlite/migrations)
|
||||
|
||||
if [[ "$ERROR" == *"--database-url"* ]]; then
|
||||
exit 0
|
||||
else
|
||||
echo "Unexpected error from sqlx-cli: $ERROR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Reversible Migrations
|
||||
env:
|
||||
DATABASE_URL: ${{ env.BASE_URL }}/test4
|
||||
run: |
|
||||
sqlx db setup --source=tests/sqlite/migrations_reversible
|
||||
|
||||
INFO_BEFORE=$(sqlx mig info --source=tests/sqlite/migrations_reversible)
|
||||
|
||||
sqlx mig revert --target-version=0 --source=tests/sqlite/migrations_reversible
|
||||
|
||||
INFO_AFTER=$(sqlx mig info --source=tests/sqlite/migrations_reversible)
|
||||
|
||||
if [[ "$INFO_BEFORE" == "$INFO_AFTER" ]]; then
|
||||
echo "Error: migration info is identical before and after migrating: $INFO_BEFORE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
76
.github/workflows/sqlx.yml
vendored
76
.github/workflows/sqlx.yml
vendored
@@ -144,7 +144,23 @@ jobs:
|
||||
- run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,macros,${{ matrix.linking }},${{ matrix.linking == 'sqlite' && 'sqlite-preupdate-hook,' || ''}}_unstable-all-types,runtime-${{ matrix.runtime }}
|
||||
--features any,macros,migrate,${{ matrix.linking }},_unstable-all-types,runtime-${{ matrix.runtime }},${{ matrix.linking == 'sqlite' && 'sqlite-preupdate-hook' || ''}}
|
||||
--
|
||||
--test-threads=1
|
||||
env:
|
||||
DATABASE_URL: sqlite:tests/sqlite/sqlite.db
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
RUSTFLAGS: --cfg sqlite_ipaddr --cfg sqlite_test_sqlcipher
|
||||
LD_LIBRARY_PATH: /tmp/sqlite3-lib
|
||||
|
||||
# Run the `test-attr` test again to cover cleanup.
|
||||
# The `sqlite-test-attr` test requires the `sqlite` feature.
|
||||
- if: ${{ matrix.linking == 'sqlite' }}
|
||||
run: >
|
||||
cargo test
|
||||
--test sqlite-test-attr
|
||||
--no-default-features
|
||||
--features any,macros,migrate,${{ matrix.linking }},_unstable-all-types,runtime-${{ matrix.runtime }},${{ matrix.linking == 'sqlite' && 'sqlite-preupdate-hook' || ''}}
|
||||
--
|
||||
--test-threads=1
|
||||
env:
|
||||
@@ -202,7 +218,10 @@ jobs:
|
||||
# FIXME: needed to disable `ltree` tests in Postgres 9.6
|
||||
# but `PgLTree` should just fall back to text format
|
||||
RUSTFLAGS: -D warnings --cfg postgres_${{ matrix.postgres }}
|
||||
run: cargo build --features postgres,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
run: >
|
||||
cargo build
|
||||
--no-default-features
|
||||
--features postgres,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }},macros,migrate
|
||||
|
||||
- run: |
|
||||
docker compose -f tests/docker-compose.yml run -d -p 5432:5432 --name postgres_${{ matrix.postgres }} postgres_${{ matrix.postgres }}
|
||||
@@ -222,6 +241,19 @@ jobs:
|
||||
# but `PgLTree` should just fall back to text format
|
||||
RUSTFLAGS: --cfg postgres_${{ matrix.postgres }}
|
||||
|
||||
# Run the `test-attr` test again to cover cleanup.
|
||||
- run: >
|
||||
cargo test
|
||||
--test postgres-test-attr
|
||||
--no-default-features
|
||||
--features any,postgres,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: postgres://postgres:password@localhost:5432/sqlx
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
# FIXME: needed to disable `ltree` tests in Postgres 9.6
|
||||
# but `PgLTree` should just fall back to text format
|
||||
RUSTFLAGS: --cfg postgres_${{ matrix.postgres }}
|
||||
|
||||
- if: matrix.tls != 'none'
|
||||
run: >
|
||||
cargo test
|
||||
@@ -310,7 +342,18 @@ jobs:
|
||||
- run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx?ssl-mode=disabled
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
RUSTFLAGS: --cfg mysql_${{ matrix.mysql }}
|
||||
|
||||
# Run the `test-attr` test again to cover cleanup.
|
||||
- run: >
|
||||
cargo test
|
||||
--test mysql-test-attr
|
||||
--no-default-features
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx?ssl-mode=disabled
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
@@ -321,7 +364,7 @@ jobs:
|
||||
run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
@@ -335,7 +378,7 @@ jobs:
|
||||
cargo build
|
||||
--no-default-features
|
||||
--test mysql-macros
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
SQLX_OFFLINE: true
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
@@ -347,7 +390,7 @@ jobs:
|
||||
cargo test
|
||||
--no-default-features
|
||||
--test mysql-macros
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx
|
||||
SQLX_OFFLINE: true
|
||||
@@ -366,7 +409,7 @@ jobs:
|
||||
run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root@localhost:3306/sqlx?sslmode=verify_ca&ssl-ca=.%2Ftests%2Fcerts%2Fca.crt&ssl-key=.%2Ftests%2Fkeys%2Fclient.key&ssl-cert=.%2Ftests%2Fcerts%2Fclient.crt
|
||||
RUSTFLAGS: --cfg mysql_${{ matrix.mysql }}
|
||||
@@ -399,7 +442,18 @@ jobs:
|
||||
- run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
RUSTFLAGS: --cfg mariadb_${{ matrix.mariadb }}
|
||||
|
||||
# Run the `test-attr` test again to cover cleanup.
|
||||
- run: >
|
||||
cargo test
|
||||
--test mysql-test-attr
|
||||
--no-default-features
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
@@ -413,7 +467,7 @@ jobs:
|
||||
cargo build
|
||||
--no-default-features
|
||||
--test mysql-macros
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
SQLX_OFFLINE: true
|
||||
SQLX_OFFLINE_DIR: .sqlx
|
||||
@@ -424,7 +478,7 @@ jobs:
|
||||
cargo test
|
||||
--no-default-features
|
||||
--test mysql-macros
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root:password@localhost:3306/sqlx
|
||||
SQLX_OFFLINE: true
|
||||
@@ -443,7 +497,7 @@ jobs:
|
||||
run: >
|
||||
cargo test
|
||||
--no-default-features
|
||||
--features any,mysql,macros,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
--features any,mysql,macros,migrate,_unstable-all-types,runtime-${{ matrix.runtime }},tls-${{ matrix.tls }}
|
||||
env:
|
||||
DATABASE_URL: mysql://root@localhost:3306/sqlx?sslmode=verify_ca&ssl-ca=.%2Ftests%2Fcerts%2Fca.crt&ssl-key=.%2Ftests%2Fkeys%2Fclient.key&ssl-cert=.%2Ftests%2Fcerts%2Fclient.crt
|
||||
RUSTFLAGS: --cfg mariadb_${{ matrix.mariadb }}
|
||||
|
||||
22
CHANGELOG.md
22
CHANGELOG.md
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 0.8.5 - 2025-04-14
|
||||
|
||||
Hotfix release to address two new issues:
|
||||
* [[#3823]]: `sqlx-cli@0.8.4` broke `.env` default resolution mechanism
|
||||
* [[#3825]]: `sqlx@0.8.4` broke test fixture setup
|
||||
|
||||
The `0.8.4` release will be yanked as of publishing this one.
|
||||
|
||||
# Added
|
||||
* In release PR: `sqlx-cli` now accepts `--no-dotenv` in subcommand arguments.
|
||||
* In release PR: added functionality tests for `sqlx-cli` to CI.
|
||||
* In release PR: test `#[sqlx::test]` twice in CI to cover cleanup.
|
||||
|
||||
# Fixed
|
||||
* In release PR: `sqlx-cli` correctly reads `.env` files by default again.
|
||||
* Addresses [[#3823]].
|
||||
* In release PR: fix bugs in MySQL implementation of `#[sqlx::test]`.
|
||||
* Addresses [[#3825]].
|
||||
|
||||
[#3823]: https://github.com/launchbadge/sqlx/issues/3823
|
||||
[#3825]: https://github.com/launchbadge/sqlx/issues/3825
|
||||
|
||||
## 0.8.4 - 2025-04-13
|
||||
|
||||
50 pull requests were merged this release cycle.
|
||||
|
||||
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -3374,7 +3374,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
@@ -3404,7 +3404,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-cli"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
@@ -3428,7 +3428,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-core"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"async-io 1.13.0",
|
||||
"async-std",
|
||||
@@ -3604,7 +3604,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3615,7 +3615,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros-core"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"dotenvy",
|
||||
@@ -3640,7 +3640,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-mysql"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
@@ -3686,7 +3686,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-postgres"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
@@ -3732,7 +3732,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-sqlite"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"chrono",
|
||||
|
||||
16
Cargo.toml
16
Cargo.toml
@@ -23,7 +23,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/launchbadge/sqlx"
|
||||
@@ -129,17 +129,17 @@ bstr = ["sqlx-core/bstr"]
|
||||
|
||||
[workspace.dependencies]
|
||||
# Core Crates
|
||||
sqlx-core = { version = "=0.8.4", path = "sqlx-core" }
|
||||
sqlx-macros-core = { version = "=0.8.4", path = "sqlx-macros-core" }
|
||||
sqlx-macros = { version = "=0.8.4", path = "sqlx-macros" }
|
||||
sqlx-core = { version = "=0.8.5", path = "sqlx-core" }
|
||||
sqlx-macros-core = { version = "=0.8.5", path = "sqlx-macros-core" }
|
||||
sqlx-macros = { version = "=0.8.5", path = "sqlx-macros" }
|
||||
|
||||
# Driver crates
|
||||
sqlx-mysql = { version = "=0.8.4", path = "sqlx-mysql" }
|
||||
sqlx-postgres = { version = "=0.8.4", path = "sqlx-postgres" }
|
||||
sqlx-sqlite = { version = "=0.8.4", path = "sqlx-sqlite" }
|
||||
sqlx-mysql = { version = "=0.8.5", path = "sqlx-mysql" }
|
||||
sqlx-postgres = { version = "=0.8.5", path = "sqlx-postgres" }
|
||||
sqlx-sqlite = { version = "=0.8.5", path = "sqlx-sqlite" }
|
||||
|
||||
# Facade crate (for reference from sqlx-cli)
|
||||
sqlx = { version = "=0.8.4", path = ".", default-features = false }
|
||||
sqlx = { version = "=0.8.5", path = ".", default-features = false }
|
||||
|
||||
# Common type integrations shared by multiple driver crates.
|
||||
# These are optional unless enabled in a workspace crate.
|
||||
|
||||
@@ -13,11 +13,9 @@ enum Cli {
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let Cli::Sqlx(opt) = Cli::parse();
|
||||
sqlx_cli::maybe_apply_dotenv();
|
||||
|
||||
if !opt.no_dotenv {
|
||||
dotenvy::dotenv().ok();
|
||||
}
|
||||
let Cli::Sqlx(opt) = Cli::parse();
|
||||
|
||||
if let Err(error) = sqlx_cli::run(opt).await {
|
||||
println!("{} {}", style("error:").bold().red(), error);
|
||||
|
||||
@@ -4,11 +4,10 @@ use sqlx_cli::Opt;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let opt = Opt::parse();
|
||||
// Checks for `--no-dotenv` before parsing.
|
||||
sqlx_cli::maybe_apply_dotenv();
|
||||
|
||||
if !opt.no_dotenv {
|
||||
dotenvy::dotenv().ok();
|
||||
}
|
||||
let opt = Opt::parse();
|
||||
|
||||
// no special handling here
|
||||
if let Err(error) = sqlx_cli::run(opt).await {
|
||||
|
||||
@@ -21,6 +21,15 @@ mod prepare;
|
||||
|
||||
pub use crate::opt::Opt;
|
||||
|
||||
/// Check arguments for `--no-dotenv` _before_ Clap parsing, and apply `.env` if not set.
|
||||
pub fn maybe_apply_dotenv() {
|
||||
if std::env::args().any(|arg| arg == "--no-dotenv") {
|
||||
return;
|
||||
}
|
||||
|
||||
dotenvy::dotenv().ok();
|
||||
}
|
||||
|
||||
pub async fn run(opt: Opt) -> Result<()> {
|
||||
// This `select!` is here so that when the process receives a `SIGINT` (CTRL + C),
|
||||
// the futures currently running on this task get dropped before the program exits.
|
||||
|
||||
@@ -7,9 +7,10 @@ use clap_complete::Shell;
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(version, about, author)]
|
||||
pub struct Opt {
|
||||
/// Do not automatically load `.env` files.
|
||||
#[clap(long)]
|
||||
pub no_dotenv: bool,
|
||||
// https://github.com/launchbadge/sqlx/pull/3724 placed this here,
|
||||
// but the intuitive place would be in the arguments for each subcommand.
|
||||
#[clap(flatten)]
|
||||
pub no_dotenv: NoDotenvOpt,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
@@ -245,6 +246,9 @@ impl Deref for Source {
|
||||
/// Argument for the database URL.
|
||||
#[derive(Args, Debug)]
|
||||
pub struct ConnectOpts {
|
||||
#[clap(flatten)]
|
||||
pub no_dotenv: NoDotenvOpt,
|
||||
|
||||
/// Location of the DB, by default will be read from the DATABASE_URL env var or `.env` files.
|
||||
#[clap(long, short = 'D', env)]
|
||||
pub database_url: Option<String>,
|
||||
@@ -267,6 +271,16 @@ pub struct ConnectOpts {
|
||||
pub sqlite_create_db_wal: bool,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct NoDotenvOpt {
|
||||
/// Do not automatically load `.env` files.
|
||||
#[clap(long)]
|
||||
// Parsing of this flag is actually handled _before_ calling Clap,
|
||||
// by `crate::maybe_apply_dotenv()`.
|
||||
#[allow(unused)] // TODO: switch to `#[expect]`
|
||||
pub no_dotenv: bool,
|
||||
}
|
||||
|
||||
impl ConnectOpts {
|
||||
/// Require a database URL to be provided, otherwise
|
||||
/// return an error.
|
||||
|
||||
@@ -4,18 +4,17 @@ use std::time::Duration;
|
||||
|
||||
use futures_core::future::BoxFuture;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::executor::Executor;
|
||||
use crate::pool::{Pool, PoolOptions};
|
||||
use crate::query::query;
|
||||
use crate::{MySql, MySqlConnectOptions, MySqlConnection, MySqlDatabaseError};
|
||||
use once_cell::sync::OnceCell;
|
||||
use sqlx_core::connection::Connection;
|
||||
use sqlx_core::query_builder::QueryBuilder;
|
||||
use sqlx_core::query_scalar::query_scalar;
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::executor::Executor;
|
||||
use crate::pool::{Pool, PoolOptions};
|
||||
use crate::query::query;
|
||||
use crate::{MySql, MySqlConnectOptions, MySqlConnection};
|
||||
|
||||
pub(crate) use sqlx_core::testing::*;
|
||||
|
||||
// Using a blocking `OnceCell` here because the critical sections are short.
|
||||
@@ -62,7 +61,7 @@ impl TestSupport for MySql {
|
||||
|
||||
let db_name = format!("_sqlx_test_database_{db_name}");
|
||||
|
||||
writeln!(command, "drop database if exists {db_name:?};").ok();
|
||||
writeln!(command, "drop database if exists {db_name};").ok();
|
||||
match conn.execute(&*command).await {
|
||||
Ok(_deleted) => {
|
||||
deleted_db_names.push(db_name);
|
||||
@@ -141,14 +140,19 @@ async fn test_context(args: &TestArgs) -> Result<TestContext<MySql>, Error> {
|
||||
|
||||
let mut conn = master_pool.acquire().await?;
|
||||
|
||||
cleanup_old_dbs(&mut conn).await?;
|
||||
|
||||
// language=MySQL
|
||||
conn.execute(
|
||||
r#"
|
||||
create table if not exists _sqlx_test_databases (
|
||||
db_name text primary key,
|
||||
db_name text not null,
|
||||
test_path text not null,
|
||||
created_at timestamp not null default current_timestamp
|
||||
);
|
||||
created_at timestamp not null default current_timestamp,
|
||||
-- BLOB/TEXT columns can only be used as index keys with a prefix length:
|
||||
-- https://dev.mysql.com/doc/refman/8.4/en/column-indexes.html#column-indexes-prefix
|
||||
primary key(db_name(63))
|
||||
);
|
||||
"#,
|
||||
)
|
||||
.await?;
|
||||
@@ -162,7 +166,7 @@ async fn test_context(args: &TestArgs) -> Result<TestContext<MySql>, Error> {
|
||||
.execute(&mut *conn)
|
||||
.await?;
|
||||
|
||||
conn.execute(&format!("create database {db_name:?}")[..])
|
||||
conn.execute(&format!("create database {db_name}")[..])
|
||||
.await?;
|
||||
|
||||
eprintln!("created database {db_name}");
|
||||
@@ -186,12 +190,64 @@ async fn test_context(args: &TestArgs) -> Result<TestContext<MySql>, Error> {
|
||||
}
|
||||
|
||||
async fn do_cleanup(conn: &mut MySqlConnection, db_name: &str) -> Result<(), Error> {
|
||||
let delete_db_command = format!("drop database if exists {db_name:?};");
|
||||
let delete_db_command = format!("drop database if exists {db_name};");
|
||||
conn.execute(&*delete_db_command).await?;
|
||||
query("delete from _sqlx_test.databases where db_name = $1::text")
|
||||
query("delete from _sqlx_test_databases where db_name = ?")
|
||||
.bind(db_name)
|
||||
.execute(&mut *conn)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Pre <0.8.4, test databases were stored by integer ID.
|
||||
async fn cleanup_old_dbs(conn: &mut MySqlConnection) -> Result<(), Error> {
|
||||
let res: Result<Vec<u64>, Error> = query_scalar("select db_id from _sqlx_test_databases")
|
||||
.fetch_all(&mut *conn)
|
||||
.await;
|
||||
|
||||
let db_ids = match res {
|
||||
Ok(db_ids) => db_ids,
|
||||
Err(e) => {
|
||||
if let Some(dbe) = e.as_database_error() {
|
||||
match dbe.downcast_ref::<MySqlDatabaseError>().number() {
|
||||
// Column `db_id` does not exist:
|
||||
// https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_bad_field_error
|
||||
//
|
||||
// The table has already been migrated.
|
||||
1054 => return Ok(()),
|
||||
// Table `_sqlx_test_databases` does not exist.
|
||||
// No cleanup needed.
|
||||
// https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_no_such_table
|
||||
1146 => return Ok(()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Drop old-style test databases.
|
||||
for id in db_ids {
|
||||
match conn
|
||||
.execute(&*format!(
|
||||
"drop database if exists _sqlx_test_database_{id}"
|
||||
))
|
||||
.await
|
||||
{
|
||||
Ok(_deleted) => (),
|
||||
// Assume a database error just means the DB is still in use.
|
||||
Err(Error::Database(dbe)) => {
|
||||
eprintln!("could not clean old test database _sqlx_test_database_{id}: {dbe}");
|
||||
}
|
||||
// Bubble up other errors
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
conn.execute("drop table if exists _sqlx_test_databases")
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@ async fn it_gets_a_pool(pool: MySqlPool) -> sqlx::Result<()> {
|
||||
.fetch_one(&mut *conn)
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
db_name.starts_with("_sqlx_test_database_"),
|
||||
"db_name: {:?}",
|
||||
db_name
|
||||
);
|
||||
assert!(db_name.starts_with("_sqlx_test_"), "db_name: {:?}", db_name);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user