diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go index 1b2575f48099b42f5cad80fbf8169d34ef1dfeee..32ed66775abff749a066cf2436fa7f5556d08e71 100644 --- a/internal/sqladapter/database.go +++ b/internal/sqladapter/database.go @@ -218,19 +218,29 @@ func (d *database) Collection(name string) db.Collection { // StatementExec compiles and executes a statement that does not return any // rows. -func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (sql.Result, error) { +func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (res sql.Result, err error) { var query string - var err error if db.Conf.LoggingEnabled() { defer func(start time.Time) { - db.Log(&db.QueryStatus{ + + status := db.QueryStatus{ Query: query, Args: args, Err: err, Start: start, End: time.Now(), - }) + } + + if rowsAffected, err := res.RowsAffected(); err == nil { + status.RowsAffected = &rowsAffected + } + + if lastInsertId, err := res.LastInsertId(); err == nil { + status.LastInsertID = &lastInsertId + } + + db.Log(&status) }(time.Now()) } @@ -240,10 +250,12 @@ func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (sql } if execer, ok := d.PartialDatabase.(HasStatementExec); ok { - return execer.StatementExec(p, args...) + res, err = execer.StatementExec(p, args...) + return } - return p.Exec(args...) + res, err = p.Exec(args...) + return } // StatementQuery compiles and executes a statement that returns rows. diff --git a/logger.go b/logger.go index a29c6292ef44f831741dfb0106ef5feae07d7d9c..f1b95f56340b318abaaa52908468e5df8157c1de 100644 --- a/logger.go +++ b/logger.go @@ -8,11 +8,23 @@ import ( "time" ) +const ( + fmtLogQuery = `Query: %s` + fmtLogArgs = `Arguments: %#v` + fmtLogRowsAffected = `Rows affected: %d` + fmtLogLastInsertId = `Last insert ID: %d` + fmtLogError = `Error: %v` + fmtLogTimeTaken = `Time taken: %0.5fs` +) + // QueryStatus represents a query after being executed. type QueryStatus struct { SessID uint64 TxID uint64 + RowsAffected *int64 + LastInsertID *int64 + Query string Args []interface{} @@ -55,6 +67,10 @@ type Logger interface { // Log sends a query status report to the configured logger. func Log(m *QueryStatus) { if lg := Conf.Logger(); lg != nil { + + m.Query = reInvisibleChars.ReplaceAllString(m.Query, ` `) + m.Query = strings.TrimSpace(m.Query) + lg.Log(m) return } @@ -70,24 +86,28 @@ type defaultLogger struct { } func (lg *defaultLogger) Log(m *QueryStatus) { - m.Query = reInvisibleChars.ReplaceAllString(m.Query, ` `) - m.Query = strings.TrimSpace(m.Query) - - s := make([]string, 0, 4) + s := make([]string, 0, 6) if m.Query != "" { - s = append(s, fmt.Sprintf(`Q: %s`, m.Query)) + s = append(s, fmt.Sprintf(fmtLogQuery, m.Query)) } if len(m.Args) > 0 { - s = append(s, fmt.Sprintf(`A: %#v`, m.Args)) + s = append(s, fmt.Sprintf(fmtLogArgs, m.Args)) + } + + if m.RowsAffected != nil { + s = append(s, fmt.Sprintf(fmtLogRowsAffected, *m.RowsAffected)) + } + if m.LastInsertID != nil { + s = append(s, fmt.Sprintf(fmtLogLastInsertId, *m.LastInsertID)) } if m.Err != nil { - s = append(s, fmt.Sprintf(`E: %q`, m.Err)) + s = append(s, fmt.Sprintf(fmtLogError, m.Err)) } - s = append(s, fmt.Sprintf(`T: %0.5fs`, float64(m.End.UnixNano()-m.Start.UnixNano())/float64(1e9))) + s = append(s, fmt.Sprintf(fmtLogTimeTaken, float64(m.End.UnixNano()-m.Start.UnixNano())/float64(1e9))) log.Printf("\n\t%s\n\n", strings.Join(s, "\n\t")) }