From 4386e52264854f5dbe723d51bc2cba6b8a0da6bd Mon Sep 17 00:00:00 2001 From: moein Date: Mon, 5 May 2025 14:16:22 +0330 Subject: [PATCH] feat: add Only --- finisher_api.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/finisher_api.go b/finisher_api.go index 6802945c..5bf91af6 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -159,6 +159,34 @@ func (db *DB) Last(dest interface{}, conds ...interface{}) (tx *DB) { return tx.callbacks.Query().Execute(tx) } +// Only finds the single record and asserts that it was the only record that matched the query +func (db *DB) Only(dest interface{}, conds ...interface{}) (tx *DB) { + baseTx := db.Session(&Session{NewDB: true}) + if len(conds) > 0 { + if exprs := baseTx.Statement.BuildCondition(conds[0], conds[1:]...); len(exprs) > 0 { + baseTx.Statement.AddClause(clause.Where{Exprs: exprs}) + } + } + + findTx := baseTx.Limit(1).Find(dest) + if findTx.Error != nil { + return findTx + } + + // Check total matches (with fresh session) + var count int64 + countTx := baseTx.Session(&Session{}).Count(&count) + if countTx.Error != nil { + return countTx + } + + if count > 1 { + findTx.AddError(fmt.Errorf("expected exactly one record, but found %d", count)) + } + + return findTx +} + // Find finds all records matching given conditions conds func (db *DB) Find(dest interface{}, conds ...interface{}) (tx *DB) { tx = db.getInstance()