From 112973e119d9ef9db5bf9fbf43d71640f1b155ad Mon Sep 17 00:00:00 2001 From: XuShuo Date: Sun, 18 Feb 2024 20:02:15 +0800 Subject: [PATCH] doc: add comment --- database.go | 11 +++++++++++ delete.go | 4 ++++ expression.go | 1 + select.go | 5 +++++ transaction.go | 7 +++++++ 5 files changed, 28 insertions(+) diff --git a/database.go b/database.go index 5a29a0f..9fdd07a 100644 --- a/database.go +++ b/database.go @@ -13,6 +13,7 @@ import ( ) const ( + // for colorful terminal print green = "\033[32m" red = "\033[31m" blue = "\033[34m" @@ -57,6 +58,11 @@ type Database interface { // Initiate a DELETE FROM statement DeleteFrom(table Table) deleteWithTable + // Begin Start a new transaction and returning a Transaction object. + // the DDL operations using the returned Transaction object will + // regard as one time transaction. + // User must manually call Commit() or Rollback() to end the transaction, + // after that, more DDL operations or TCL will return error. Begin() (Transaction, error) } @@ -78,7 +84,10 @@ func (d *database) SetLogger(logger func(sql string, durationNano int64)) { d.logger = logger } +// defaultLogger is sqlingo default logger, +// which print log to stderr and regard executing time gt 100ms as slow sql. func defaultLogger(sql string, durationNano int64) { + // for finding code position, try once is enough once.Do(func() { // $GOPATH/pkg/mod/github.com/lqs/sqlingo@vX.X.X/database.go _, file, _, _ := runtime.Caller(0) @@ -99,6 +108,7 @@ func defaultLogger(sql string, durationNano int64) { } } + // convert durationNano (int64) to time.Duration du := time.Duration(durationNano) // todo shouldn't append ';' here if !strings.HasSuffix(sql, ";") { @@ -113,6 +123,7 @@ func defaultLogger(sql string, durationNano int64) { }, " ") + // print to stderr fmt.Fprintln(os.Stderr, blue+line1+reset) if du < 100*time.Millisecond { fmt.Fprintf(os.Stderr, "%s%s%s\n", green, sql, reset) diff --git a/delete.go b/delete.go index a66a0ac..89a3d28 100644 --- a/delete.go +++ b/delete.go @@ -91,6 +91,10 @@ func (s deleteStatus) Execute() (sql.Result, error) { if err != nil { return nil, err } + + // use transaction if it exists, otherwise use database. + // this is because when s.scope.Transaction is not nil, + // it must be built by transaction. if s.scope.Transaction != nil { return s.scope.Transaction.Execute(sqlString) } diff --git a/expression.go b/expression.go index 82bf9ff..9ec6113 100644 --- a/expression.go +++ b/expression.go @@ -142,6 +142,7 @@ func (e expression) GetTable() Table { } type scope struct { + // Transaction should be nil if without transaction begin Transaction *transaction Database *database Tables []Table diff --git a/select.go b/select.go index d03018c..0d5f521 100644 --- a/select.go +++ b/select.go @@ -189,6 +189,9 @@ func (s selectStatus) RightJoin(table Table) selectWithJoin { return s.join("RIGHT ", table) } +// NaturalJoin joins the table using the NATURAL keyword. +// it automatically matches the columns in the two tables that have the same name. +// it not be needed but be provided for completeness. func (s selectStatus) NaturalJoin(table Table) selectWithJoinOn { base := activeSelectBase(&s) base.scope.lastJoin = &join{ @@ -479,6 +482,8 @@ func (s selectBase) buildSelectBase(sb *strings.Builder) error { sb.WriteString(join.prefix) sb.WriteString("JOIN ") sb.WriteString(join.table.GetSQL(s.scope)) + // cause on isn't a required part of join when using natural join, + // so move it to if statement if join.on != nil { onSql, err := join.on.GetSQL(s.scope) if err != nil { diff --git a/transaction.go b/transaction.go index 91c4acb..4ed5514 100644 --- a/transaction.go +++ b/transaction.go @@ -7,6 +7,7 @@ import ( ) // Transaction is the interface of a transaction with underlying sql.Tx object. +// It provides methods to execute DDL and TCL operations. type Transaction interface { GetTx() *sql.Tx Query(sql string) (Cursor, error) @@ -67,12 +68,18 @@ func (d *database) BeginTx(ctx context.Context, opts *sql.TxOptions, f func(tx T return nil } +// Begin starts a new transaction and returning a Transaction object. +// the DDL operations using the returned Transaction object will +// regard as one time transaction. +// User must manually call Commit() or Rollback() to end the transaction, +// after that, more DDL operations or TCL will return error. func (d *database) Begin() (Transaction, error) { var err error tx, err := d.db.Begin() if err != nil { return nil, err } + // copy extra to transaction t := &transaction{ tx: tx, logger: d.logger,