Add optimized doctor search endpoint
This commit is contained in:
137
internal/repository/dokter.go
Normal file
137
internal/repository/dokter.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DokterListParams struct {
|
||||
Search string
|
||||
DoctorIDs []string
|
||||
Page int
|
||||
PerPage int
|
||||
}
|
||||
|
||||
type DokterPage struct {
|
||||
Items []Dokter
|
||||
Total int
|
||||
}
|
||||
|
||||
type Dokter struct {
|
||||
KodeRS *string `json:"KodeRs"`
|
||||
NamaRS *string `json:"NamaRs"`
|
||||
DokterID string `json:"DokterID"`
|
||||
Nama *string `json:"Nama"`
|
||||
Sapaan *string `json:"Sapaan"`
|
||||
Inisial *string `json:"Inisial"`
|
||||
Gelar *string `json:"Gelar"`
|
||||
GelarBelakang *string `json:"Gelar_belakang"`
|
||||
JenisKaryawanID *string `json:"JenisKaryawanID"`
|
||||
Kelamin *string `json:"Kelamin"`
|
||||
GolonganDarah *string `json:"GolonganDarah"`
|
||||
TempatLahir *string `json:"TempatLahir"`
|
||||
TanggalLahir *string `json:"TanggalLahir"`
|
||||
NIK *string `json:"NIK"`
|
||||
Telepon *string `json:"Telepon"`
|
||||
Ponsel *string `json:"Ponsel"`
|
||||
Email *string `json:"Email"`
|
||||
Alamat *string `json:"Alamat"`
|
||||
Kota *string `json:"Kota"`
|
||||
KodePos *string `json:"KodePos"`
|
||||
Propinsi *string `json:"Propinsi"`
|
||||
Negara *string `json:"Negara"`
|
||||
TanggalMulai *string `json:"TanggalMulai"`
|
||||
Keilmuan *string `json:"Keilmuan"`
|
||||
SpesialisasiID *string `json:"SpesialisasiID"`
|
||||
KodeSpesialisasiID *string `json:"KodeSpesialisasiID"`
|
||||
KodeSubSpesialisasiID *string `json:"KodeSubSpesialisasiID"`
|
||||
Tipe *string `json:"Tipe"`
|
||||
NA *string `json:"NA"`
|
||||
}
|
||||
|
||||
func (r MySQLLayananRepository) ListDokter(ctx context.Context, params DokterListParams) (DokterPage, error) {
|
||||
where, args := dokterListWhere(params)
|
||||
|
||||
var total int
|
||||
if err := r.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dokter d "+where, args...).Scan(&total); err != nil {
|
||||
return DokterPage{}, err
|
||||
}
|
||||
|
||||
queryArgs := append(append([]any{}, args...), params.PerPage, (params.Page-1)*params.PerPage)
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT
|
||||
d.DokterID, d.Nama, d.Sapaan, d.Inisial, d.Gelar, d.Gelar_belakang,
|
||||
d.JenisKaryawanID, d.Kelamin, d.GolonganDarah, d.TempatLahir,
|
||||
d.TanggalLahir, d.NIK, d.Telepon, d.Ponsel, d.Email, d.Alamat,
|
||||
d.Kota, d.KodePos, d.Propinsi, d.Negara, d.TanggalMulai, d.Keilmuan,
|
||||
d.SpesialisasiID, d.KodeSpesialisasiID, d.KodeSubSpesialisasiID,
|
||||
d.Tipe, d.NA,
|
||||
(SELECT rs.KodeRS FROM rs ORDER BY rs.RSID LIMIT 1),
|
||||
(SELECT rs.Nama FROM rs ORDER BY rs.RSID LIMIT 1)
|
||||
FROM dokter d
|
||||
`+where+`
|
||||
ORDER BY d.Nama, d.DokterID
|
||||
LIMIT ? OFFSET ?`, queryArgs...)
|
||||
if err != nil {
|
||||
return DokterPage{}, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
items := make([]Dokter, 0)
|
||||
for rows.Next() {
|
||||
item, err := scanDokter(rows)
|
||||
if err != nil {
|
||||
return DokterPage{}, err
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return DokterPage{}, err
|
||||
}
|
||||
|
||||
return DokterPage{Items: items, Total: total}, nil
|
||||
}
|
||||
|
||||
func dokterListWhere(params DokterListParams) (string, []any) {
|
||||
conditions := []string{"d.NA = 'N'"}
|
||||
args := make([]any, 0, 2+len(params.DoctorIDs))
|
||||
|
||||
if params.Search != "" {
|
||||
conditions = append(conditions, "(d.DokterID LIKE ? OR d.Nama LIKE ?)")
|
||||
like := "%" + params.Search + "%"
|
||||
args = append(args, like, like)
|
||||
}
|
||||
if len(params.DoctorIDs) > 0 {
|
||||
placeholders := make([]string, len(params.DoctorIDs))
|
||||
for i, id := range params.DoctorIDs {
|
||||
placeholders[i] = "?"
|
||||
args = append(args, id)
|
||||
}
|
||||
conditions = append(conditions, "d.DokterID IN ("+strings.Join(placeholders, ",")+")")
|
||||
}
|
||||
|
||||
return "WHERE " + strings.Join(conditions, " AND "), args
|
||||
}
|
||||
|
||||
func scanDokter(rows *sql.Rows) (Dokter, error) {
|
||||
var item Dokter
|
||||
var kodeRS, namaRS sql.NullString
|
||||
|
||||
err := rows.Scan(
|
||||
&item.DokterID, &item.Nama, &item.Sapaan, &item.Inisial, &item.Gelar, &item.GelarBelakang,
|
||||
&item.JenisKaryawanID, &item.Kelamin, &item.GolonganDarah, &item.TempatLahir,
|
||||
&item.TanggalLahir, &item.NIK, &item.Telepon, &item.Ponsel, &item.Email, &item.Alamat,
|
||||
&item.Kota, &item.KodePos, &item.Propinsi, &item.Negara, &item.TanggalMulai, &item.Keilmuan,
|
||||
&item.SpesialisasiID, &item.KodeSpesialisasiID, &item.KodeSubSpesialisasiID,
|
||||
&item.Tipe, &item.NA, &kodeRS, &namaRS,
|
||||
)
|
||||
if err != nil {
|
||||
return Dokter{}, fmt.Errorf("scan dokter: %w", err)
|
||||
}
|
||||
|
||||
item.KodeRS = nullStringPtr(kodeRS)
|
||||
item.NamaRS = nullStringPtr(namaRS)
|
||||
return item, nil
|
||||
}
|
||||
Reference in New Issue
Block a user