defaultDBURL kept the empty host only when state_dir started with //, but SQLite reads the path written into the URL, state_dir followed by /state.sqlite3. For a state_dir of / that path is //state.sqlite3, the URL started file:// and SQLite read state.sqlite3 as a host, so pixa failed to start. The decision now looks at that path: a state_dir of / gives file:////state.sqlite3. Every other state_dir gives the same URL as before. Model: opus-5-5
This commit is contained in:
@@ -726,13 +726,13 @@ Key settings in more detail:
|
|||||||
- `db_url` — the SQLite database to open; omitted, it is
|
- `db_url` — the SQLite database to open; omitted, it is
|
||||||
`file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the
|
`file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the
|
||||||
database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or
|
database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or
|
||||||
`#` in the name is written as `%25`, `%3F` or `%23`. For a `state_dir`
|
`#` in the name is written as `%25`, `%3F` or `%23`. For a `state_dir` of `/`
|
||||||
starting with `//` it starts `file:////`, so SQLite does not read the first
|
or one starting with `//` it starts `file:////`, so SQLite does not read the
|
||||||
directory name as a host. pixa opens one connection to it, so its own reads
|
first name in the path as a host. pixa opens one connection to it, so its own
|
||||||
and writes run one at a time. pixa adds `_pragma=busy_timeout(5000)` to any
|
reads and writes run one at a time. pixa adds `_pragma=busy_timeout(5000)` to
|
||||||
`db_url`, so a write that finds another program writing to the file waits up
|
any `db_url`, so a write that finds another program writing to the file waits
|
||||||
to five seconds for it instead of failing. WAL mode comes only from the URL:
|
up to five seconds for it instead of failing. WAL mode comes only from the
|
||||||
keep `_pragma=journal_mode(WAL)` in one you set
|
URL: keep `_pragma=journal_mode(WAL)` in one you set
|
||||||
- `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk
|
- `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk
|
||||||
cache entirely; omitted defaults to 75% of the sum of the free space on the
|
cache entirely; omitted defaults to 75% of the sum of the free space on the
|
||||||
filesystem containing `<state_dir>/cache/` and the bytes of source and
|
filesystem containing `<state_dir>/cache/` and the bytes of source and
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ P2: security: per-origin rate limiting
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-16 a `state_dir` whose name holds `%`, `?` or `#` keeps its database
|
||||||
|
at `state.sqlite3` in that directory (closes #290): the `db_url` derived from
|
||||||
|
it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a
|
||||||
|
`?` or `#` ended the path early, and the journal mode parameter was lost. The
|
||||||
|
derived `db_url` is now built with Go's `net/url`, which writes those
|
||||||
|
characters as `%25`, `%3F` and `%23`. For a `state_dir` of `/` or one starting
|
||||||
|
with `//` it starts `file:////`, so SQLite no longer reads the first name in
|
||||||
|
the path as a host.
|
||||||
- 2026-10-16 a size with one side `0` keeps the side computed from the source's
|
- 2026-10-16 a size with one side `0` keeps the side computed from the source's
|
||||||
proportions at 1 or more (closes #283): it was rounded down, so for a thin
|
proportions at 1 or more (closes #283): it was rounded down, so for a thin
|
||||||
source it came out at 0, and libvips then made the size square. An 8192x1
|
source it came out at 0, and libvips then made the size square. An 8192x1
|
||||||
@@ -62,14 +70,6 @@ P2: security: per-origin rate limiting
|
|||||||
another way, such as with `%2F` in the path, whatever else the path holds, or
|
another way, such as with `%2F` in the path, whatever else the path holds, or
|
||||||
with a user name and password. It also answers 400 for a source path holding a
|
with a user name and password. It also answers 400 for a source path holding a
|
||||||
`..` segment, as `/v1/image/` refuses one.
|
`..` segment, as `/v1/image/` refuses one.
|
||||||
- 2026-10-16 a `state_dir` whose name holds `%`, `?` or `#` keeps its database
|
|
||||||
at `state.sqlite3` in that directory (closes #290): the `db_url` derived from
|
|
||||||
it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a
|
|
||||||
`?` or `#` ended the path early, and the journal mode parameter was lost. The
|
|
||||||
derived `db_url` is now built with Go's `net/url`, which writes those
|
|
||||||
characters as `%25`, `%3F` and `%23`. For a `state_dir` starting with `//` it
|
|
||||||
starts `file:////`, so SQLite no longer reads the first directory name as a
|
|
||||||
host.
|
|
||||||
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
|
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
|
||||||
build a huge image (closes #282): libvips' thumbnail scaled the whole source
|
build a huge image (closes #282): libvips' thumbnail scaled the whole source
|
||||||
to cover the requested size and copied that into memory before it cut out the
|
to cover the requested size and copied that into memory before it cut out the
|
||||||
|
|||||||
@@ -359,14 +359,18 @@ func newFromSmartConfig(sc *smartconfig.Config) (*Config, error) {
|
|||||||
// the directory name, which SQLite decodes back, so the URL names exactly
|
// the directory name, which SQLite decodes back, so the URL names exactly
|
||||||
// this file. OmitHost writes file:/var/lib/pixa/... instead of
|
// this file. OmitHost writes file:/var/lib/pixa/... instead of
|
||||||
// file:///var/lib/pixa/..., and keeps a relative stateDir from being read
|
// file:///var/lib/pixa/..., and keeps a relative stateDir from being read
|
||||||
// as a host name. A stateDir starting with // keeps the empty host, so the
|
// as a host name. The path written into the URL is stateDir followed by
|
||||||
// URL starts file://// and SQLite does not read the first directory name
|
// /state.sqlite3; when it starts with //, as it does for a stateDir of /
|
||||||
// as a host.
|
// or one starting with //, the empty host is kept, so the URL starts
|
||||||
|
// file://// and SQLite does not read the first name in the path as a
|
||||||
|
// host.
|
||||||
func defaultDBURL(stateDir string) string {
|
func defaultDBURL(stateDir string) string {
|
||||||
|
dbPath := stateDir + "/state.sqlite3"
|
||||||
|
|
||||||
dbURL := url.URL{
|
dbURL := url.URL{
|
||||||
Scheme: "file",
|
Scheme: "file",
|
||||||
OmitHost: !strings.HasPrefix(stateDir, "//"),
|
OmitHost: !strings.HasPrefix(dbPath, "//"),
|
||||||
Path: stateDir + "/state.sqlite3",
|
Path: dbPath,
|
||||||
RawQuery: "_pragma=journal_mode(WAL)",
|
RawQuery: "_pragma=journal_mode(WAL)",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user