Skip to content

xftp-server: support postgresql backend#1755

Open
shumvgolove wants to merge 47 commits intomasterfrom
sh/xftp-pg
Open

xftp-server: support postgresql backend#1755
shumvgolove wants to merge 47 commits intomasterfrom
sh/xftp-pg

Conversation

@shumvgolove
Copy link
Copy Markdown
Collaborator

No description provided.

@shumvgolove shumvgolove force-pushed the sh/xftp-pg branch 3 times, most recently from 00ed151 to e63e0be Compare April 8, 2026 06:15
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres/Migrations.hs
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres/Migrations.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres.hs
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres.hs
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres/Migrations.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres/Migrations.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store/Postgres.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Env.hs
Comment thread src/Simplex/FileTransfer/Server/Env.hs
Comment thread src/Simplex/FileTransfer/Server/Env.hs
Comment thread src/Simplex/FileTransfer/Server/Store.hs Outdated
Comment thread src/Simplex/FileTransfer/Server/Store.hs
Comment thread src/Simplex/FileTransfer/Server.hs Outdated
Comment thread src/Simplex/FileTransfer/Server.hs Outdated
Comment thread src/Simplex/FileTransfer/Server.hs Outdated
Comment thread tests/XFTPAgent.hs Outdated
Comment thread tests/XFTPServerTests.hs
Comment thread tests/XFTPServerTests.hs Outdated
Comment thread tests/Test.hs Outdated
Comment thread tests/Test.hs Outdated
Comment thread tests/XFTPAgent.hs Outdated
Comment thread tests/XFTPClient.hs Outdated
In Postgres mode, getFile returns a snapshot TVar for fileStatus. If a
file is blocked between getFile and setFilePath, the stale status check
passes but the upload should be rejected. Added status = 'active' to
the UPDATE WHERE clause so blocked files cannot receive uploads.
Prevents negative or zero file_size values at the database level.
Without this, corrupted data from import or direct DB access could
cause incorrect storage accounting (getUsedStorage sums file_size,
and expiredFiles casts to Word32 which wraps negative values).
importFileStore now checks if the target database already contains
files and aborts with an error. Previously, importing into a non-empty
database would fail mid-COPY on duplicate primary keys, leaving the
database in a partially imported state.
When setFilePath fails (file deleted or blocked concurrently, or
duplicate upload), the uploaded file was left orphaned on disk with
no DB record pointing to it. Now the file is removed on failure,
matching the cleanup in the receiveChunk error path.
The store action result (deleteFile/blockFile) was discarded with void.
If the DB row was already deleted by a concurrent operation, the
function still decremented usedStorage, causing drift. Now the error
propagates via ExceptT, skipping the usedStorage adjustment.
deleteFile result was discarded with void. If a concurrent delete
already removed the file, deleteFile returned AUTH but usedStorage
was still decremented — causing double-decrement drift. Now the
usedStorage adjustment and filesExpired stat only run on success.
- Move STMFileStore and its FileStoreClass instance from Store/STM.hs
  back into Store.hs — the separate file was unnecessary indirection
  for the always-present default implementation.

- Parameterize xftpFileTests over store backend using HSpec SpecWith
  pattern (following SMP's serverTests approach). The same 11 tests
  now run against both memory and PostgreSQL backends via a bracket
  parameter, eliminating all *Pg test duplicates.

- Extract shared run* functions (runTestFileChunkDeliveryAddRecipients,
  runTestWrongChunkSize, runTestFileChunkExpiration, runTestFileStorageQuota)
  from inlined test bodies.
- Remove internal helpers from Postgres.hs export list (withDB, withDB',
  handleDuplicate, assertUpdated, withLog are not imported externally)
- Replace local isNothing_ with Data.Maybe.isNothing in Env.hs
- Consolidate duplicate/unused imports in XFTPStoreTests.hs
- Add file_path IS NULL and status guards to STM setFilePath, matching
  the Postgres implementation semantics
- xftpTest/xftpTest2/xftpTest4/xftpTestN now take XFTPTestBracket as
  first argument, enabling the same test to run against both memory
  and PostgreSQL backends.

- xftpFileTests (server tests), xftpAgentFileTests (agent tests), and
  xftpCLIFileTests (CLI tests) are SpecWith-parameterized suites that
  receive the bracket from HSpec's before combinator.

- Test.hs runs each parameterized suite twice: once with
  xftpMemoryBracket, once with xftpPostgresBracket (CPP-guarded).

- STM-specific tests (store log restore/replay) stay in memory-only
  xftpAgentTests. SNI/CORS tests stay in memory-only xftpServerTests.
Remove old non-parameterized test wrapper functions that were
superseded by the store-backend-parameterized test suites.
All test bodies (run* and _ functions) are preserved and called
from the parameterized specs. Clean up unused imports.
Embed XFTPStoreConfig s as serverStoreCfg field, matching SMP's
ServerConfig. runXFTPServer and newXFTPServerEnv now take a single
XFTPServerConfig s. Restore verifyCmd local helper structure.
Restore xftpServerTests and xftpAgentTests bodies to match master
byte-for-byte (only type signatures change for XFTPTestBracket
parameterization); inline the runTestXXX helpers that were split
on this branch.
Move STM store log close responsibility into closeFileStore to
match PostgresFileStore, removing the asymmetry where only PG's
close was self-contained.

STMFileStore holds the log in a TVar populated by newXFTPServerEnv
after readWriteFileStore; stopServer no longer needs the explicit
withFileLog closeStoreLog call. Writes still go through XFTPEnv.storeLog
via withFileLog (unchanged).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants