Pemrograman

17 Delete Flag dalam GORM untuk Soft Delete yang Efisien

Pelajari cara menggunakan delete flag dalam GORM untuk mengelola soft delete dengan metode boolean, Unix timestamp, dan mixed mode. Dilengkapi contoh kode dan unit test

Delete flag adalah metode alternatif untuk melakukan soft delete dengan cara menyimpan status penghapusan dalam bentuk flag, seperti nilai 1 atau 0, atau menggunakan timestamp Unix.

1. Delete Flag

Contoh Kode

package main

import (
    "gorm.io/gorm"
)

type User struct {
    ID         uint `gorm:"primaryKey"`
    Name       string
    IsDeleted  bool `gorm:"default:false"`
}

func deleteUserFlag(db *gorm.DB, userID uint) error {
    result := db.Model(&User{}).Where("id = ?", userID).Update("is_deleted", true)
    return result.Error
}

Penjelasan Kode

  • Menambahkan kolom IsDeleted dengan tipe bool untuk menandai data sebagai dihapus.
  • Fungsi deleteUserFlag memperbarui nilai is_deleted menjadi true tanpa menghapus data dari database.

Unit Test

func TestDeleteUserFlag(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})

    mock.ExpectExec("UPDATE users").WillReturnResult(sqlmock.NewResult(1, 1))

    err := deleteUserFlag(gormDB, 1)
    if err != nil {
        t.Errorf("Error deleting user flag: %v", err)
    }
}

Penjelasan Kode Unit Test

  • Menggunakan SQLMock untuk menguji query UPDATE users.
  • Memastikan fungsi deleteUserFlag dapat mengupdate kolom is_deleted tanpa error.

2. Unix Second

Contoh Kode

import (
    "time"
)

type UserUnix struct {
    ID         uint `gorm:"primaryKey"`
    Name       string
    DeletedAt  int64 `gorm:"default:0"`
}

func deleteUserUnix(db *gorm.DB, userID uint) error {
    result := db.Model(&UserUnix{}).Where("id = ?", userID).Update("deleted_at", time.Now().Unix())
    return result.Error
}

Penjelasan Kode

  • Menggunakan timestamp Unix untuk menandai data sebagai dihapus dengan DeletedAt.
  • Fungsi deleteUserUnix mengupdate deleted_at dengan waktu saat ini.

Unit Test

func TestDeleteUserUnix(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})

    mock.ExpectExec("UPDATE user_unixes").WillReturnResult(sqlmock.NewResult(1, 1))

    err := deleteUserUnix(gormDB, 1)
    if err != nil {
        t.Errorf("Error deleting user with unix timestamp: %v", err)
    }
}

Penjelasan Kode Unit Test

  • Menguji query UPDATE user_unixes dengan SQLMock.
  • Memastikan fungsi deleteUserUnix berjalan tanpa error.

3. Use 1 / 0 as Delete Flag

Contoh Kode

type UserFlag struct {
    ID         uint `gorm:"primaryKey"`
    Name       string
    Deleted    int `gorm:"default:0"`
}

func deleteUserIntFlag(db *gorm.DB, userID uint) error {
    result := db.Model(&UserFlag{}).Where("id = ?", userID).Update("deleted", 1)
    return result.Error
}

Penjelasan Kode

  • Menggunakan integer 1 sebagai penanda bahwa data dihapus.
  • Fungsi deleteUserIntFlag memperbarui kolom deleted menjadi 1.

Unit Test

func TestDeleteUserIntFlag(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})

    mock.ExpectExec("UPDATE user_flags").WillReturnResult(sqlmock.NewResult(1, 1))

    err := deleteUserIntFlag(gormDB, 1)
    if err != nil {
        t.Errorf("Error deleting user with integer flag: %v", err)
    }
}

Penjelasan Kode Unit Test

  • Menggunakan SQLMock untuk mengekspektasikan query UPDATE user_flags.
  • Memastikan fungsi deleteUserIntFlag bekerja sesuai harapan.

4. Mixed Mode

Contoh Kode

type UserMixed struct {
    ID         uint `gorm:"primaryKey"`
    Name       string
    DeletedAt  gorm.DeletedAt `gorm:"index"`
    IsDeleted  bool `gorm:"default:false"`
}

func deleteUserMixed(db *gorm.DB, userID uint) error {
    result := db.Model(&UserMixed{}).Where("id = ?", userID).Updates(map[string]interface{}{
        "deleted_at": gorm.DeletedAt{Time: time.Now()},
        "is_deleted": true,
    })
    return result.Error
}

Penjelasan Kode

  • Kombinasi antara soft delete bawaan GORM (DeletedAt) dan flag IsDeleted.
  • Fungsi deleteUserMixed mengupdate kedua kolom tersebut sekaligus.

Unit Test

func TestDeleteUserMixed(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})

    mock.ExpectExec("UPDATE user_mixeds").WillReturnResult(sqlmock.NewResult(1, 1))

    err := deleteUserMixed(gormDB, 1)
    if err != nil {
        t.Errorf("Error deleting user with mixed mode: %v", err)
    }
}

Penjelasan Kode Unit Test

  • Menggunakan SQLMock untuk mengekspektasikan query UPDATE user_mixeds.
  • Memastikan fungsi deleteUserMixed bekerja sesuai harapan.

Kesimpulan

  • Delete flag menggunakan nilai true/false untuk menandai penghapusan data.
  • Unix second menyimpan waktu penghapusan dalam bentuk timestamp.
  • Menggunakan angka 1/0 sebagai flag penghapusan juga umum dalam praktik database.
  • Mixed mode menggabungkan metode soft delete bawaan GORM dengan delete flag.
comments powered by Disqus