The create subcommand generated .up.sql files with INSERT INTO
_migrations as the FIRST statement, before the actual DDL. If the
DDL fails, the migration is incorrectly marked as applied. Move the
INSERT to be the LAST statement, matching how .down.sql already puts
DELETE FROM _migrations last.
Also fix the automatic fixup logic to append (not prepend) missing
INSERT statements to existing .up.sql files.
Fixes#86
Adds `sql-migrate sync` which outputs a shell script that refreshes
the local migrations.log from the DB by running _migrations.sql.
Uses `|| true` so a fresh DB with no _migrations table yields an
empty log (all migrations pending) rather than an error.
Usage:
sql-migrate -d ./db/migrations sync | sh
sql-migrate -d ./db/migrations up | sh
- connEntry.isIdle(now, threshold): caller supplies now instead of time.Since
- connRegistry.closeIdle(now, threshold): passes now through to isIdle
- trackingConn gains a clock func() time.Time field used in Read/Write
- handleConn takes clock func() time.Time; uses it to init lastRead/lastWrite
and passes it to trackingConn
- Call sites in main pass time.Now or time.Now() explicitly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On SIGINT/SIGTERM:
- Stop accepting new connections
- Close connections idle longer than --idle-timeout (default 5s),
determined by LastRead/LastWrite timestamps tracked per connection pair
- Wait for active connections to drain up to --shutdown-timeout (default 30s)
- Force-close any remaining connections if the timeout is exceeded
Also switches isClosedConn to use errors.Is(err, net.ErrClosed) and
exits the accept loop cleanly when a listener is closed during shutdown.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Accept any number of local-port:remote-host:remote-port forwards as
positional arguments. Backward-compatible with existing --port/--target
flags. Adds --version/-V/version and --help/help handling matching the
auth-proxy pattern, including printVersion printed to stderr at startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>