Pemrograman

10 Advance Query Data Gorm Library (Bagian 2)

Pelajari teknik query lanjutan di GORM dengan Golang, termasuk Find To Map, FirstOrInit, Query Hooks, Iteration, dan lainnya, lengkap dengan contoh kode dan unit test.

Artikel ini merupakan lanjutan dari pembahasan sebelumnya tentang Advanced Query dengan GORM. Kali ini, kita akan membahas berbagai teknik lanjutan lainnya seperti FindInBatches, Query Hooks, Pluck, Scopes, dan Count, lengkap dengan contoh kode dan unit test.


13. FindInBatches

Metode FindInBatches digunakan untuk menangani dataset dalam jumlah besar dengan membagi proses pengambilan data menjadi batch kecil untuk menghindari penggunaan memori yang berlebihan.

Fungsi

func BatchProcessUsers(db *gorm.DB) error {
    batchSize := 100 // Menentukan ukuran batch
    return db.Model(&User{}).FindInBatches(&[]User{}, batchSize, func(tx *gorm.DB, batch []User) error {
        return nil // Menjalankan operasi pada setiap batch
    }).Error
}

Penjelasan Kode

  1. batchSize := 100 → Menentukan jumlah record yang diambil dalam satu batch.
  2. db.Model(&User{}) → Menentukan model yang digunakan dalam query.
  3. .FindInBatches(&[]User{}, batchSize, func(tx *gorm.DB, batch []User) error { ... }) → Mengambil data dalam batch kecil dan menerapkan operasi pada setiap batch.
  4. return nil → Tidak melakukan operasi tambahan pada batch.
  5. return db.FindInBatches(...).Error → Mengembalikan error jika ada masalah saat proses batch berlangsung.

Unit Test

func TestBatchProcessUsers_Success(t *testing.T) {
    err := BatchProcessUsers(db)
    assert.Nil(t, err) // Memastikan tidak ada error saat proses batch berhasil
}

func TestBatchProcessUsers_Error(t *testing.T) {
    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
    err := BatchProcessUsers(db)
    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
}

Penjelasan Unit Test

  1. Memanggil BatchProcessUsers(db) untuk menguji eksekusi batch.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Menguji skenario error dengan database tanpa tabel User untuk memastikan error terjadi.

14. Query Hooks

Metode Query Hooks digunakan untuk memproses data sebelum atau setelah eksekusi query, misalnya untuk memformat data sebelum disimpan ke database.

Fungsi

type User struct {
    gorm.Model
    Name string
}

func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
    u.Name = strings.ToUpper(u.Name) // Mengubah nama menjadi huruf besar sebelum disimpan
    return
}

Penjelasan Kode

  1. type User struct { ... } → Mendefinisikan model User.
  2. BeforeCreate(tx *gorm.DB) → Hook yang akan dijalankan sebelum record dibuat.
  3. u.Name = strings.ToUpper(u.Name) → Mengubah nama user menjadi huruf kapital sebelum disimpan ke database.

Unit Test

func TestQueryHook_Success(t *testing.T) {
    user := User{Name: "charlie"}
    db.Create(&user)
    assert.Equal(t, "CHARLIE", user.Name) // Memastikan nama telah dikonversi ke huruf besar
}

func TestQueryHook_Error(t *testing.T) {
    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
    user := User{Name: "charlie"}
    err := db.Create(&user).Error
    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
}

Penjelasan Unit Test

  1. Membuat user dengan nama “charlie”.
  2. Menyimpan user ke database dan memastikan bahwa nama telah dikonversi menjadi “CHARLIE”.
  3. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

15. Pluck

Metode Pluck digunakan untuk mengambil nilai dari satu kolom tertentu dan menyimpannya dalam slice.

Fungsi

func GetUserNames(db *gorm.DB) ([]string, error) {
    var names []string // Slice untuk menyimpan hasil query
    result := db.Model(&User{}).Pluck("name", &names)
    return names, result.Error // Mengembalikan daftar nama dan error jika ada
}

Penjelasan Kode

  1. var names []string → Deklarasi slice untuk menyimpan hasil query.
  2. db.Model(&User{}) → Menentukan model yang digunakan.
  3. .Pluck("name", &names) → Mengambil nilai dari kolom name dan menyimpannya dalam slice names.

Unit Test

func TestGetUserNames_Success(t *testing.T) {
    names, err := GetUserNames(db)
    assert.Nil(t, err) // Memastikan tidak ada error
    assert.Greater(t, len(names), 0) // Memastikan hasil query tidak kosong
}

func TestGetUserNames_Error(t *testing.T) {
    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
    names, err := GetUserNames(db)
    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
}

Penjelasan Unit Test

  1. Memanggil GetUserNames(db) untuk mengambil daftar nama.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

16. Scopes

Metode Scopes digunakan untuk mendefinisikan query yang dapat digunakan kembali, sehingga query lebih bersih dan mudah dibaca.

Fungsi

func ActiveUsers(db *gorm.DB) *gorm.DB {
    return db.Where("active = ?", true) // Filter hanya user yang aktif
}

func GetActiveUsers(db *gorm.DB) ([]User, error) {
    var users []User
    result := db.Scopes(ActiveUsers).Find(&users) // Menggunakan scope yang telah didefinisikan
    return users, result.Error
}

Penjelasan Kode

  1. func ActiveUsers(db *gorm.DB) *gorm.DB → Mendefinisikan fungsi scope yang mengembalikan query hanya untuk user yang aktif.
  2. db.Where("active = ?", true) → Filter hanya user yang memiliki atribut active = true.
  3. func GetActiveUsers(db *gorm.DB) ([]User, error) → Fungsi untuk mengambil daftar user yang aktif dengan menggunakan scope ActiveUsers.
  4. db.Scopes(ActiveUsers).Find(&users) → Menerapkan scope ActiveUsers untuk mendapatkan daftar user yang aktif.

Unit Test

func TestGetActiveUsers_Success(t *testing.T) {
    users, err := GetActiveUsers(db)
    assert.Nil(t, err) // Memastikan tidak ada error
    assert.Greater(t, len(users), 0) // Memastikan ada user aktif
}

func TestGetActiveUsers_Error(t *testing.T) {
    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
    users, err := GetActiveUsers(db)
    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
}

Penjelasan Unit Test

  1. Memanggil GetActiveUsers(db) untuk mengambil daftar user yang aktif.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Memeriksa jumlah user aktif lebih dari nol menggunakan assert.Greater(t, len(users), 0).
  4. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

(Tambahkan kode, penjelasan, dan unit test di sini)


17. Count

Metode Count digunakan untuk menghitung jumlah record dalam suatu tabel.

Fungsi

func CountUsers(db *gorm.DB) (int64, error) {
    var count int64 // Variabel untuk menyimpan hasil hitungan
    result := db.Model(&User{}).Count(&count)
    return count, result.Error // Mengembalikan jumlah user dan error jika ada
}

Penjelasan Kode

  1. var count int64 → Deklarasi variabel count untuk menyimpan jumlah record yang dihitung.
  2. db.Model(&User{}) → Menentukan model yang digunakan untuk query count.
  3. .Count(&count) → Menghitung jumlah record dalam tabel users dan menyimpannya dalam variabel count.
  4. return count, result.Error → Mengembalikan jumlah user dan error jika ada.

Unit Test

func TestCountUsers_Success(t *testing.T) {
    count, err := CountUsers(db)
    assert.Nil(t, err) // Memastikan tidak ada error
    assert.Greater(t, count, int64(0)) // Memastikan jumlah user lebih dari 0
}

func TestCountUsers_Error(t *testing.T) {
    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
    count, err := CountUsers(db)
    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
}

Penjelasan Unit Test

  1. Memanggil CountUsers(db) untuk menghitung jumlah user dalam database.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Memeriksa jumlah user lebih dari nol menggunakan assert.Greater(t, count, int64(0)).
  4. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

Untuk informasi lebih lanjut, kunjungi:


comments powered by Disqus

Topik Terhangat

pemrograman
152
jaringan
28
tips-dan-trik
27
tutorial
20
hardware
11
linux
4
kubernetes
1
trik-and-tips
1