sqlite improvements (#1965)

* use direct blocking calls for SQLite in `sqlx_macros`
    * this also ensures the database is closed properly, cleaning up tempfiles
* don't send `PRAGMA journal_mode` unless set
    * this previously defaulted to WAL mode which is a permanent setting
      on databases which doesn't necessarily apply to all use-cases
    * changing into or out of WAL mode acquires an exclusive lock on the database
      that can't be waited on by `sqlite3_busy_timeout()`
    * for consistency, `sqlx-cli` commands that create databases will still
      create SQLite databases in WAL mode; added a flag to disable this.
* in general, don't send `PRAGMA`s unless different than default
    * we were sending a bunch of `PRAGMA`s with their default values just to enforce
      an execution order on them, but we can also do this by inserting empty slots
      for their keys into the `IndexMap`
* add error code to `SqliteError` printout
* document why `u64` is not supported
This commit is contained in:
Austin Bonander
2022-07-12 13:59:37 -07:00
committed by GitHub
parent d9fd21c94e
commit bc3e70545b
14 changed files with 234 additions and 131 deletions

View File

@@ -11,6 +11,12 @@ pub async fn create(connect_opts: &ConnectOpts) -> anyhow::Result<()> {
let exists = crate::retry_connect_errors(connect_opts, Any::database_exists).await?;
if !exists {
#[cfg(feature = "sqlite")]
sqlx::sqlite::CREATE_DB_WAL.store(
connect_opts.sqlite_create_db_wal,
std::sync::atomic::Ordering::Release,
);
Any::create_database(&connect_opts.database_url).await?;
}

View File

@@ -221,6 +221,18 @@ pub struct ConnectOpts {
/// returning an error.
#[clap(long, default_value = "10")]
pub connect_timeout: u64,
/// Set whether or not to create SQLite databases in Write-Ahead Log (WAL) mode:
/// https://www.sqlite.org/wal.html
///
/// WAL mode is enabled by default for SQLite databases created by `sqlx-cli`.
///
/// However, if your application sets a `journal_mode` on `SqliteConnectOptions` to something
/// other than `Wal`, then it will have to take the database file out of WAL mode on connecting,
/// which requires an exclusive lock and may return a `database is locked` (`SQLITE_BUSY`) error.
#[cfg(feature = "sqlite")]
#[clap(long, action = clap::ArgAction::Set, default_value = "true")]
pub sqlite_create_db_wal: bool,
}
/// Argument for automatic confirmation.