package exec import ( "database/sql" "errors" "reflect" "git.gdulai.com/gdulai/simpleorm" "git.gdulai.com/gdulai/simpleorm/schema" log "gitlab.com/gdulai/simpleloglvl" ) type Count[T any] struct { target schema.Table whereStmt string args []any result int64 } func CreateCount[T any](orm *simpleorm.ORM, whereStmt string, args ...any) (Count[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { return Count[T]{}, errors.New("Failed to get table from schema cache") } return Count[T]{target: *table, whereStmt: whereStmt, args: args}, nil } func (c *Count[T]) Result() int64 { return c.result } func (c *Count[T]) Execute(conn *simpleorm.DBConnection) error { return c.execute(conn, nil) } func (c *Count[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { // Reinit the results, new execution c.result = -1 dml := c.target.GetCountDML() if c.whereStmt != "" { dml += " WHERE " + c.whereStmt } log.LogDebug("Preparing sql: %s, with args: %s", dml, c.args) var stmt *sql.Stmt var err error if tx != nil { stmt, err = tx.Prepare(dml) } else { stmt, err = conn.Prepare(dml) } if err != nil { return err } defer stmt.Close() log.LogDebug("Executing statement: %s", stmt) if len(c.args) == 0 { err = stmt.QueryRow().Scan(&c.result) } else { // Flattent args to make sure it can be parsed correctly var flatArgs []any for _, a := range c.args { if s, ok := a.([]any); ok { flatArgs = append(flatArgs, s...) } else { flatArgs = append(flatArgs, a) } } err = stmt.QueryRow(flatArgs...).Scan(&c.result) } if err != nil { return err } return nil }