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 }