Context
Context adalah salah satu konkuresi pattern yang bertujuan untuk mengcancel jika menemui sebuah routine yang waktu eksekusinya lama. Karena operasi yang berjalan lama memang seharusnya diberi deadline. Jalan untuk meng-handle pembatalan adalah dengan melempar context.Context to fungsi yang mengetahui proses untuk mengecek pembatalan terminasi dini.
Tambahkan argumen context.Context ke semua fungsi di models/user.go
Passing ctx variable ke db.QueryContext, db.QueryRowContext, db.PrepareContext and stmt.ExecContext di file models/user.go
package models
import (
"context"
"database/sql"
"essentials/libraries/api"
)
// User : struct of User
type User struct {
ID uint64
Username string
Password string
Email string
IsActive bool
}
// List of users
func (u *User) List(ctx context.Context, db *sql.DB) ([]User, error) {
var list []User
const q = `SELECT id, username, password, email, is_active FROM users`
rows, err := db.QueryContext(ctx, q)
if err != nil {
return list, err
}
defer rows.Close()
for rows.Next() {
var user User
if err := rows.Scan(&user.ID, &user.Username, &user.Password, &user.Email, &user.IsActive); err != nil {
return list, err
}
list = append(list, user)
}
return list, rows.Err()
}
// Create new user
func (u *User) Create(ctx context.Context, db *sql.DB) error {
const query = `
INSERT INTO users (username, password, email, is_active, created, updated)
VALUES (?, ?, ?, 0, NOW(), NOW())
`
stmt, err := db.PrepareContext(ctx, query)
if err != nil {
return err
}
defer stmt.Close()
res, err := stmt.ExecContext(ctx, u.Username, u.Password, u.Email)
if err != nil {
return err
}
id, err := res.LastInsertId()
if err != nil {
return err
}
u.ID = uint64(id)
return nil
}
// Get user by id
func (u *User) Get(ctx context.Context, db *sql.DB) error {
const q string = `SELECT id, username, password, email, is_active FROM users`
err := db.QueryRowContext(ctx, q+" WHERE id=?", u.ID).Scan(&u.ID, &u.Username, &u.Password, &u.Email, &u.IsActive)
if err == sql.ErrNoRows {
err = api.ErrNotFound(err, "")
}
return err
}
// Update user by id
func (u *User) Update(ctx context.Context, db *sql.DB) error {
const q string = `UPDATE users SET is_active = ? WHERE id = ?`
stmt, err := db.PrepareContext(ctx, q)
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.ExecContext(ctx, u.IsActive, u.ID)
return err
}
// Delete user by id
func (u *User) Delete(ctx context.Context, db *sql.DB) error {
const q string = `DELETE FROM users WHERE id = ?`
stmt, err := db.PrepareContext(ctx, q)
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.ExecContext(ctx, u.ID)
return err
}Pass nilai dari r.Context() dari file controllers/users.go pada setiap kali memanggil method di models/user.go
Pass nilai dari r.Context() dari file usecases/user_usecase.go pada setiap kali memanggil method di models/user.go
Pada unit test, pass nilai dari context.Background() di file tests/user_tes.go setiap memanggil method di models/user.go
Kita bisa mengetesnya dengan membuat time.Sleep()
Last updated
Was this helpful?