0.2.4
RustBox CI / rustbox (push) Canceled after 0s

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-31 22:36:28 +01:00
1 parent 2c98b8f925
commit e4aa787e06
27 files changed
+179 -110

No files matched your search

+2 -35
View File
@@ -20,8 +20,6 @@ const SQLITE_SCHEMA: &str = include_str!("../../migrations/sqlite/schema.sql");
const MYSQL_SCHEMA: &str = include_str!("../../migrations/mysql/schema.sql");
const PGSQL_SCHEMA: &str = include_str!("../../migrations/pgsql/schema.sql");
// The squashed legacy baseline is V046. Runtime migrations start at V047 and
// are stored as real files for every supported SQL engine.
const SQLITE_MIGRATIONS: &[(u32, &str)] = &[(
47,
include_str!("../../migrations/sqlite/V047__blob_keys_and_search_outbox.sql"),
@@ -65,7 +63,6 @@ const TENANT_TABLES: &[&str] = &[
"user_meta",
];
// Parent tables precede children so legacy SQLite data can be copied with foreign keys enabled.
const IMPORT_TABLES: &[&str] = &[
"calendar_events",
"calendar_settings",
@@ -229,12 +226,6 @@ pub async fn configure(config: &AppConfig) -> Result<(), String> {
conn.execute_batch(&global_schema(SQLITE_SCHEMA)?)
.map_err(|e| format!("SQLite global schema initialization failed: {e}"))?;
// Unit tests create many independent temporary data directories in one
// process. Pinning the first SQLite path in the process-wide OnceLock
// makes later tests reuse a TempDir that may already have been deleted,
// causing a cascade of "unable to open database file" failures.
// Initialize the requested test database, but let open_user_db() resolve
// each test's own data_dir instead of publishing this path globally.
#[cfg(test)]
{
return Ok(());
@@ -287,9 +278,6 @@ pub async fn configure(config: &AppConfig) -> Result<(), String> {
let schema = global_schema(PGSQL_SCHEMA)?;
let init_pool = pool.clone();
runtime_wait(&runtime, async move {
// PostgreSQL emits NOTICE for every CREATE ... IF NOT EXISTS that
// already exists. Keep expected idempotent startup DDL quiet without
// changing application-wide logging or server settings.
let mut tx = init_pool
.begin()
.await
@@ -298,11 +286,6 @@ pub async fn configure(config: &AppConfig) -> Result<(), String> {
.execute(&mut *tx)
.await
.map_err(|e| format!("failed to quiet PostgreSQL schema notices: {e}"))?;
// `raw_sql(...).execute(&mut PgConnection)` can trigger SQLx's
// "Executor is not general enough" lifetime error when this
// future is spawned onto the dedicated database runtime. Execute
// the unprepared multi-statement DDL directly through `Executor`
// instead; this is SQLx's supported path for raw DDL batches.
(&mut *tx)
.execute(schema.as_str())
.await
@@ -460,7 +443,6 @@ pub trait ToDbValue {
}
}
// Kept explicit rather than clever: the macro above intentionally stays simple for rustfmt/parser compatibility.
impl ToDbValue for i64 {
fn to_db_value(&self) -> DbValue {
DbValue::I64(Some(*self))
@@ -601,10 +583,6 @@ impl IntoDbParams for [(); 0] {
}
}
// Do not use a const-generic array implementation here. For an empty array (`[]`)
// Rust cannot infer the element type and sees both `[(); 0]` and `[T; 0]` as valid
// `IntoDbParams` candidates. Implement only non-empty array lengths explicitly so
// legacy/rusqlite-style `[]` call sites remain unambiguous.
macro_rules! impl_into_db_params_array {
($($n:expr),+ $(,)?) => {
$(
@@ -1457,8 +1435,6 @@ fn adapt_sql_params(
return (sql, params);
}
// Dynamic query builders in the application use SQLite-style ?N placeholders.
// Normalize them here so the same higher-level logic can target all engines.
let chars: Vec<char> = sql.chars().collect();
let mut output = String::with_capacity(sql.len() + 16);
let mut reordered = Vec::new();
@@ -1522,8 +1498,6 @@ fn adapt_sql_params(
sql = output;
if backend == DatabaseBackend::Mysql && !reordered.is_empty() {
// If numbered placeholders were expanded, bind in occurrence order.
// Plain MySQL catalog queries already use '?' and are handled the same way.
return (adapt_dialect_sql(backend, sql), reordered);
}
(adapt_dialect_sql(backend, sql), params)
@@ -1855,9 +1829,6 @@ fn tenant_prefix(user_hash: &str) -> Result<String, String> {
return Err("empty user hash for database isolation".to_string());
}
// Production user hashes are SHA-256 hex strings. Tests and legacy callers may
// use symbolic identifiers; hash those first so table prefixes remain safe,
// deterministic and restricted to ASCII hex without weakening isolation.
let normalized = if user_hash.len() >= 24 && user_hash.chars().all(|c| c.is_ascii_hexdigit()) {
user_hash.to_ascii_lowercase()
} else {
@@ -2060,8 +2031,6 @@ fn ensure_server_tenant(
let tenant = tenant_schema(MYSQL_SCHEMA, &prefix)?;
let legacy_path = legacy_path.clone();
runtime_wait(runtime, async move {
// Serialize first-time provisioning per account across cluster nodes.
// MySQL named locks are session-scoped and are released automatically if the connection dies.
let lock_name = format!("rustbox:{prefix}");
let mut lock_conn = pool
.acquire()
@@ -2210,10 +2179,8 @@ fn ensure_server_tenant(
ConfiguredDatabase::Sqlite { .. } => false,
};
if imported_legacy {
if let Some(path) = legacy_path.as_ref() {
backup_legacy_sqlite(path);
}
if imported_legacy && let Some(path) = legacy_path.as_ref() {
backup_legacy_sqlite(path);
}
Ok(())
}