FerretDB v1 (SQLite) multi-platform binaries β ferretdb.zip. Built by release-all.yml from the wekan/FerretDB fork.
v1.25.0 (2026-07-10)
New Features π
- Implement the
replSetInitiatecommand as a compatibility no-op so that tools and drivers that bootstrap a replica set do not hard-fail: the command is accepted with or without a configuration document ({replSetInitiate: 1}or{replSetInitiate: {_id: "rs0", members: [...]}}) and returns{ok: 1}, echoing back the configuration_id(replica set name) when one is supplied. IMPORTANT: this does NOT set up real replication β FerretDB v1's oplog is tailing-only and must still be configured manually by creating a cappedlocal.oplog.rscollection and setting theFERRETDB_REPL_SET_NAMEenvironment variable; the command creates no oplog, elects no primary and does not change server topology by @xet7 in ed98fa8 . Thanks to xet7. - Implement the logical session and transaction command family as compatibility commands so MongoDB drivers (and Meteor) that rely on sessions and retryable writes work against the SQLite backend:
startSessionreturns a session record with a freshly generated UUID, andcommitTransaction,abortTransaction,endSessions,refreshSessions,killSessions,killAllSessionsandkillAllSessionsByPatternreturn{ok: 1}. The ordinary write commands (insert,update,delete,findAndModify) now also accept and ignore the retryable-write / session fieldsautocommit,startTransaction,stmtIdandstmtIdsin addition to the already-acceptedlsidandtxnNumber. IMPORTANT: these transaction commands are NO-OP compatibility commands β FerretDB v1 with the SQLite backend has no real multi-document transactions, every write auto-commits on its own, and the commands provide no atomicity or isolation across operations (abortTransactiondoes not roll back writes that already happened); logical sessions are accepted but carry no server-side state by @xet7 in c229095 . Thanks to xet7. - Track logical sessions in a real server-side session registry (ported and adapted from FerretDB v2's
internal/handler/sessionpackage) instead of treating the session commands as pure no-ops: the handler now owns asession.Registrythat creates and looks up sessions bylsid, groups them per user, records their created and last-used times, marks sessions as ended and prunes ended/expired sessions after the 30-minuteLogicalSessionTimeoutMinutes.startSessionregisters a fresh session,endSessionsmarks the referenced sessions ended,refreshSessionsbumps their last-used time (creating them implicitly if needed), andkillSessions,killAllSessionsandkillAllSessionsByPatternremove the referenced sessions from the registry β all still returning{ok: 1}. The v2 cursor-association tracking is intentionally omitted because v1's cursor registry differs, so the port keeps the session lifecycle only. IMPORTANT: this only tracks session bookkeeping β multi-document transactions remain NO-OP compatibility commands, as FerretDB v1 with the SQLite backend auto-commits every write and provides no atomicity or isolation by @xet7 in 166770d . Thanks to xet7. - Implement the
$setWindowFieldsaggregation stage together with the window operators$rank,$denseRank,$documentNumberand$shift(rank/position, requiringsortBy) and the window accumulators$sum,$avg,$min,$max,$count,$push,$first,$last,$stdDevPopand$stdDevSamp(over the default full-partition window or an explicitwindow: {documents: [lower, upper]}with integer offsets and the"unbounded"/"current"keywords). The window operators$derivative,$integral,$expMovingAvg,$covariancePop,$covarianceSamp,$linearFill,$locf,$minN/$maxNandrangewindows are deferred and return a clear not-implemented error by @xet7 in 540de30 . Thanks to xet7. - Implement the
$slice,$sortand$positionmodifiers for the$pushupdate operator (used by WeKan) by @xet7. Thanks to xet7. - Implement the
$eq,$ne,$or,$ifNull,$anyElementTrue,$objectToArrayand$mapaggregation expression operators used by WeKan by @xet7. Thanks to xet7. - Implement the
$cmp,$gt,$gte,$lt,$lte,$and,$not,$cond,$switchand$allElementsTrueaggregation expression operators by @xet7. Thanks to xet7. - Implement the arithmetic aggregation expression operators
$add,$subtract,$multiply,$divide,$mod,$abs,$ceil,$floor,$trunc,$round,$pow,$sqrt,$exp,$ln,$log,$max,$minand$avgby @xet7. Thanks to xet7. - Implement the trigonometric, hyperbolic, angle-conversion and
$log10aggregation expression operators$sin,$cos,$tan,$asin,$acos,$atan,$atan2,$sinh,$cosh,$tanh,$asinh,$acosh,$atanh,$degreesToRadians,$radiansToDegreesand$log10by @xet7 in 62a683e . Thanks to xet7. - Implement the
$bsonSizeaggregation expression operator, which returns the size in bytes of the BSON encoding of a document (null for a null argument) by @xet7 in 84d798e . Thanks to xet7. - Implement the string aggregation expression operators
$concat,$toUpper,$toLower,$strLenCP,$strLenBytes,$strcasecmp,$substr,$substrCP,$substrBytes,$split,$trim,$ltrim,$rtrim,$indexOfCP,$indexOfBytes,$replaceOne,$replaceAlland$regexMatchby @xet7. Thanks to xet7. - Implement the array aggregation expression operators
$size,$arrayElemAt,$concatArrays,$isArray,$in,$reverseArray,$slice,$range,$indexOfArray,$arrayToObject,$filter,$reduce,$sortArray,$setUnion,$setIntersection,$setDifference,$setEquals,$setIsSubsetand$zipby @xet7. Thanks to xet7. - Implement the type-conversion aggregation expression operators
$toString,$toInt,$toLong,$toDouble,$toBool,$toObjectId,$toDate,$convert,$isNumber,$literal,$let,$getField,$setField,$unsetField,$binarySizeand$randby @xet7. Thanks to xet7. - Implement the date aggregation expression operators
$year,$month,$dayOfMonth,$hour,$minute,$second,$millisecond,$dayOfWeek,$dayOfYear,$week,$isoDayOfWeek,$isoWeek,$isoWeekYear,$dateToString,$dateFromString,$dateToParts,$dateFromParts,$dateAdd,$dateSubtract,$dateDiffand$dateTruncby @xet7. Thanks to xet7. - Implement the
$lookupaggregation stage (basic equality-join form) used by WeKan by @xet7. Thanks to xet7. - Implement the
$replaceRoot,$replaceWith,$sortByCountand$sampleaggregation stages by @xet7. Thanks to xet7. - Implement the
$facetaggregation stage (multi-sub-pipeline) by @xet7. Thanks to xet7. - Implement the
$unionWithaggregation stage (with optional sub-pipeline) by @xet7. Thanks to xet7. - Implement the
$bucketand$bucketAutoaggregation stages (the$bucketAutogranularityoption is not yet supported) by @xet7. Thanks to xet7. - Implement TTL indexes (
expireAfterSecondson createIndexes, reported by listIndexes, with a background reaper that deletes expired documents) by @xet7. Thanks to xet7. - Implement the
$wherequery operator, which evaluates a JavaScript expression or function against each document (withthisbound to the document) using the embedded pure-Go goja JavaScript engine by @xet7 in dd4dafe . Thanks to xet7. - Implement the
$functionaggregation expression operator ({body, args, lang: "js"}), which runs a user-supplied JavaScript function over the evaluated argument expressions using the embedded pure-Go goja JavaScript engine by @xet7 in dd4dafe . Thanks to xet7. - Implement text indexes:
createIndexesnow accepts the"text"index key value and theweights,default_language,language_overrideandtextIndexVersionoptions, storing them so the index is created and round-tripped throughlistIndexes(weights default to 1 per field). Note that this is a pragmatic implementation for compatibility: no real inverted/full-text index is built by @xet7 in 21ed802 . Thanks to xet7. - Implement the
$textquery operator with partial, self-contained semantics: it matches the$searchterms directly against a document's string fields (recursing into sub-documents and arrays) and supports multi-term OR, case-insensitive whole-word matching,$caseSensitive, double-quoted phrases and leading-negation;$languageand$diacriticSensitiveare accepted and ignored. There is no stemming, no relevance scoring and no$meta: "textScore"projection by @xet7 in 21ed802 . Thanks to xet7. - Accept the
hidden,collation,partialFilterExpressionand2dsphereindex options oncreateIndexes:hidden(bool),collation(document) andpartialFilterExpression(document) are stored and round-tripped throughlistIndexes, and the"2dsphere"index key value together with2dsphereIndexVersionis accepted and reported (version defaulting to 3). These options are only accepted, stored and reported β FerretDB does not hide indexes from the query planner, does not apply locale-aware collation, does not restrict a partial index to matching documents and does not run geospatial queries. The remaining options (storageEngine,bits,min,max,bucketSize,wildcardProjection) still return not-implemented by @xet7 in 13e8f22 . Thanks to xet7.
Other Changes π€
- Add a
release-all.ymlGitHub Actions workflow that does a full FerretDB v1 release: it buildsferretdb.zipfor every platform withbuild.sh, publishes a GitHub Release with it at https://github.com/wekan/FerretDB/releases, and builds + pushes a multi-arch FerretDB Docker image (amd64, arm64, ppc64le, s390x, riscv64) from the source Dockerfile towekanteam/ferretdb,quay.io/wekan/ferretdbandghcr.io/wekan/ferretdbβ using the sameDOCKERHUB_AUTH/QUAY_AUTH/GHCR_AUTHbase64("user:token") secrets as wekan/wekan by @xet7 in 67262f0 .build.shgains option 13 /./build.sh release [version]to push the branch and trigger that workflow viagh, like wekan/wekan'sreleases/release-all.sh. Thanks to xet7. - Add
build.shmenu options 11 (SEQUENTIAL) and 12 (PARALLEL) β and the non-interactive./build.sh zip/zip-seq/zip-parcommands β that cross-compile FerretDB v1 (SQLite backend,CGO_ENABLED=0, no QEMU) for every platform Go andmodernc.org/sqlitesupport into a singleferretdb.zipwith the layoutferretdb/<arch>/ferretdb-<arch>(.exeonly on Windows, binaries alreadychmod +x) plusferretdb/README.md; targets that do not compile are skipped, so the zip holds exactly what builds. The build was run and all 16 targets compiled: amd64, arm64, armhf, armel, i386, ppc64le, s390x, riscv64, loong64, win64, win-arm64, win32, mac-amd64, mac-arm64, freebsd-amd64, freebsd-arm64. Go's build scratch dir (GOTMPDIR) is placed on the repo disk so a parallel build does not fill a small/tmptmpfs, and.gitignoreignores the producedferretdb.zipby @xet7 in 05fa6ee . Thanks to xet7. - Fix the SQLite backend unit tests after the
modernc.org/sqlitebump: the embedded SQLite moved from 3.46.0 to 3.53.2, so update the expectedsqlite_version()/BackendVersion(3.46.0 β 3.53.2) andsqlite_source_id()inpool_test.go,registry_test.goandbackend_test.go, and runbuild.shunit tests with-tags=ferretdb_debug(the tagtask test-unituses) so the debug-only assertions pass β e.g.TestCheckError, which assertsdebugbuild.Enabledby @xet7 in e566dee . Thanks to xet7. - Add an interactive
build.shhelper for FerretDB v1 (SQLite): a menu-driven (and non-interactive./build.sh <command>) script to install dependencies, build theferretdbbinary with the SQLite handler, run FerretDB on the SQLite backend, run the in-process SQLite integration tests (with the required-target-tlsflag), run unit tests, vet, build/run the Docker stack, and clean; it self-installs a local Go 1.25 toolchain under./.gorootwhengois not onPATH. Integration tests can be run sequentially (test-seq,-p 1 -parallel 1) or in parallel (test-par [N]/TEST_PARALLEL=N, defaulting to the CPU count) by @xet7 in adc3473d . Thanks to xet7. - Add positive and negative integration tests for the
$pullAllupdate operator, used by WeKan (already implemented upstream) by @xet7. Thanks to xet7. - Add
docker-compose.ymlandDockerfilesodocker compose up --buildbuilds FerretDB v1 (SQLite backend) and runs WeKan against it (no oplog,METEOR_REACTIVITY_ORDER=polling, attachments on filesystem); the previous FerretDB development compose is preserved asdocker-compose.dev.ymlby @xet7 in ed7a4df1 . Thanks to xet7. - Update all Go dependencies to their latest releases (grpc, protobuf, OpenTelemetry,
golang.org/x/{crypto,net,sys,text},go.mongodb.org/mongo-driver, testify and procfs) and bump thegodirective from 1.24 to 1.25 by @xet7 in 7549f63 . Thanks to xet7. - Update the SQLite backend driver
modernc.org/sqlitev1.32.0 β v1.53.0 (andmodernc.org/libcv1.55.3 β v1.74.0), which requires Go 1.25 by @xet7 in 7549f63 . Thanks to xet7. - Keep
github.com/FerretDB/wirepinned at v0.0.8, because newer releases change the internal BSON API (GetByIndex,Sections,CheckNaNs) used by this v1.24.2 codebase by @xet7 in 7549f63 . Thanks to xet7.