milestone 13 discrepancies: redact credentials from urls in logs, metrics and cli output
This commit is contained in:
@@ -31,6 +31,9 @@ const ddl_v2: [:0]const u8 =
|
||||
\\ALTER TABLE upstreams ADD COLUMN tls_name TEXT NOT NULL DEFAULT '';
|
||||
;
|
||||
|
||||
/// The schema version this binary expects. A database `readVersion` reports
|
||||
/// below this needs `nxdns run` to migrate it; above it is `error.SchemaTooNew`
|
||||
/// and needs a newer nxdns.
|
||||
pub const target_version: u32 = steps[steps.len - 1].version;
|
||||
|
||||
comptime {
|
||||
@@ -102,9 +105,16 @@ pub fn migrateSteps(database: *db.Db, list: []const Step) Error!u32 {
|
||||
return target;
|
||||
}
|
||||
|
||||
/// The schema version stamped in `database`, compared against `target_version`.
|
||||
///
|
||||
/// `0` when `schema_version` does not exist yet. Zero rows or more than one row
|
||||
/// is `error.SchemaCorrupt` — the version of a database is never guessed.
|
||||
fn readVersion(database: *db.Db) Error!u32 {
|
||||
///
|
||||
/// Reads only, so it works on a connection opened `.read_only` or
|
||||
/// `.immutable`. That is what it is public for: `nxdns check` may not migrate
|
||||
/// (ruling F-c), and "at version 1, this binary expects 2" tells an operator
|
||||
/// what to do where a bare SQLite error message does not.
|
||||
pub fn readVersion(database: *db.Db) Error!u32 {
|
||||
const present = try database.queryInt(
|
||||
"SELECT count(*) FROM sqlite_schema WHERE type='table' AND name='schema_version'",
|
||||
);
|
||||
@@ -302,6 +312,47 @@ test "a failing step after step 2 rolls back the whole upgrade from version 1" {
|
||||
try testing.expectEqual(@as(u32, 1), try readVersion(&database));
|
||||
}
|
||||
|
||||
test "readVersion reports 0 before a migration and target_version after it" {
|
||||
var database = try openMigrated();
|
||||
defer database.close();
|
||||
|
||||
try testing.expectEqual(@as(u32, 0), try readVersion(&database));
|
||||
_ = try migrate(&database);
|
||||
try testing.expectEqual(target_version, try readVersion(&database));
|
||||
}
|
||||
|
||||
/// `.zig-cache/tmp/` is where `std.testing.tmpDir` puts its directories, and
|
||||
/// SQLite's VFS resolves filenames against the same working directory
|
||||
/// (`db.zig`'s immutable tests).
|
||||
const tmp_prefix = ".zig-cache/tmp/";
|
||||
const sub_path_len = @typeInfo(@FieldType(testing.TmpDir, "sub_path")).array.len;
|
||||
|
||||
test "readVersion reads a file database through an immutable open, writing nothing" {
|
||||
var tmp = testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
var path_buf: [tmp_prefix.len + sub_path_len + 32]u8 = undefined;
|
||||
const path = try std.fmt.bufPrintZ(&path_buf, "{s}{s}/config.db", .{ tmp_prefix, &tmp.sub_path });
|
||||
|
||||
// A database an older nxdns left at version 1. `check` must report that, not
|
||||
// migrate it (ruling F-c).
|
||||
{
|
||||
var database = try db.Db.open(path, .{ .mode = .read_write_create });
|
||||
defer database.close();
|
||||
try db.applyPragmas(&database, .{});
|
||||
const first = [_]Step{.{ .version = 1, .sql = config_schema.ddl_v1 }};
|
||||
try testing.expectEqual(@as(u32, 1), try migrateSteps(&database, &first));
|
||||
}
|
||||
|
||||
var database = try db.Db.open(path, .{ .mode = .{ .immutable = testing.io } });
|
||||
defer database.close();
|
||||
try testing.expectEqual(@as(u32, 1), try readVersion(&database));
|
||||
try testing.expectEqual(@as(u32, 2), target_version);
|
||||
|
||||
// A write through this connection is refused by SQLite, not by convention.
|
||||
try testing.expectError(error.ReadOnly, database.exec("DELETE FROM schema_version;"));
|
||||
try testing.expectEqual(@as(u32, 1), try readVersion(&database));
|
||||
}
|
||||
|
||||
test "delete_order and content_tables name exactly the tables the schema creates" {
|
||||
var database = try openMigrated();
|
||||
defer database.close();
|
||||
|
||||
Reference in New Issue
Block a user