From d3c96ed66ab953627aa7224ac7de754c719ea05a Mon Sep 17 00:00:00 2001 From: maml Date: Sat, 18 Apr 2026 13:15:11 -0400 Subject: [PATCH] aperturedb: add yaml struct tags to fix config file key mismatches Aperture parses its config file with goccy/go-yaml, which falls back to the lowercased struct field name when no yaml tag is present. Two fields had a mismatch between their go-flags `long:` tag (which documents the YAML key in sample-conf.yaml) and the goccy/go-yaml fallback name derived from the field name: SqliteConfig.DatabaseFileName long:"dbfile" fallback: "databasefilename" PostgresConfig.MaxOpenConnections long:"maxconnections" fallback: "maxopenconnections" In both cases the documented yaml key in sample-conf.yaml matches the long: tag, not the fallback. So a user who follows the documentation and sets sqlite.dbfile or postgres.maxconnections in their config file has those values silently ignored. For sqlite, this causes Aperture to resolve DatabaseFileName to the hardcoded defaultSqliteDatabasePath (~/Library/Application Support/Aperture/aperture.db on macOS), a directory that typically does not exist, and SQLite fails to open the DB with "unable to open database file: out of memory (14)" (CANTOPEN). Fix: add yaml: tags matching the existing long: tags so goccy/go-yaml reads the documented keys. Also add yaml:"skipmigrations" to both SkipMigrations fields for consistency. --- aperturedb/postgres.go | 6 +++--- aperturedb/sqlite.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/aperturedb/postgres.go b/aperturedb/postgres.go index 8d955fa8..8b628e23 100644 --- a/aperturedb/postgres.go +++ b/aperturedb/postgres.go @@ -28,14 +28,14 @@ var ( // PostgresConfig holds the postgres database configuration. type PostgresConfig struct { - SkipMigrations bool `long:"skipmigrations" description:"Skip applying migrations on startup."` + SkipMigrations bool `long:"skipmigrations" yaml:"skipmigrations" description:"Skip applying migrations on startup."` Host string `long:"host" description:"Database server hostname."` Port int `long:"port" description:"Database server port."` User string `long:"user" description:"Database user."` Password string `long:"password" description:"Database user's password."` DBName string `long:"dbname" description:"Database name to use."` - MaxOpenConnections int32 `long:"maxconnections" description:"Max open connections to keep alive to the database server."` - RequireSSL bool `long:"requiressl" description:"Whether to require using SSL (mode: require) when connecting to the server."` + MaxOpenConnections int32 `long:"maxconnections" yaml:"maxconnections" description:"Max open connections to keep alive to the database server."` + RequireSSL bool `long:"requiressl" yaml:"requireSSL" description:"Whether to require using SSL (mode: require) when connecting to the server."` } // DSN returns the dns to connect to the database. diff --git a/aperturedb/sqlite.go b/aperturedb/sqlite.go index a8c0a4a7..d127a1c2 100644 --- a/aperturedb/sqlite.go +++ b/aperturedb/sqlite.go @@ -40,11 +40,11 @@ const ( type SqliteConfig struct { // SkipMigrations if true, then all the tables will be created on start // up if they don't already exist. - SkipMigrations bool `long:"skipmigrations" description:"Skip applying migrations on startup."` + SkipMigrations bool `long:"skipmigrations" yaml:"skipmigrations" description:"Skip applying migrations on startup."` // DatabaseFileName is the full file path where the database file can be // found. - DatabaseFileName string `long:"dbfile" description:"The full path to the database."` + DatabaseFileName string `long:"dbfile" yaml:"dbfile" description:"The full path to the database."` } // SqliteStore is a database store implementation that uses a sqlite backend.