DEV Community

JaisySymuri
JaisySymuri

Posted on

"Create" dan "Upload" di Golang Postgres: Back-end

Cek file-file v2

Repository/source code: https://github.com/JaisySymuri/postgre

Buat folder baru "files" sebagai tempat untuk menampung file yang akan kita upload. Kemudian di main.go, sebelum func dbConn, buat struct Employee

main.go

type Employee struct {
    ID_Pegawai    int
    NIK           string
    Nama          string
    Username      string
    Password      string
    Alamat        string
    Tempat_Lahir  string
    Tanggal_Lahir string
    No_HP         string
    Pekerjaan     string
    Gender        string
    Email         string
    Nama_Ibu      string
    File          string
    SearchType    string
}
Enter fullscreen mode Exit fullscreen mode

Di golang, posisi variable, constants, structure, dan functions tidak masalah. Cuma agar mudah saat diingat, fungsi-fungsi diletakkan di bagian paling bawah.

Kemudiaan, setelah func dbConn, buat fungsi untuk menangani insert query. Isi dengan membuat variable db untuk membuka koneksi ke database dan cek metode POST

main.go:Insert

func Insert(w http.ResponseWriter, r *http.Request) {

    db := dbConn()
    if r.Method == "POST" {

...
Enter fullscreen mode Exit fullscreen mode

Kemudian, atur penyimpanan file yang dikirim ke folder 'files" yang kita buat sebelumnya.

main.go:Insert

...
alias := r.FormValue("alias")
        uploadedFile, handler, err := r.FormFile("file")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer uploadedFile.Close()

        dir, err := os.Getwd()
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        filename := handler.Filename
        if alias != "" {
            filename = fmt.Sprintf("%s%s", alias, filepath.Ext(handler.Filename))
        }

        fileLocation := filepath.Join(dir, "files", filename)
        targetFile, err := os.OpenFile(fileLocation, os.O_WRONLY|os.O_CREATE, 0666)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer targetFile.Close()

        if _, err := io.Copy(targetFile, uploadedFile); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
...
Enter fullscreen mode Exit fullscreen mode

Atur kode untuk menerima isi formulir yang dikirim dan mengubahnya sebagai query ke database

main.go:Insert

...
NIK := r.FormValue("NIK")
        Nama := r.FormValue("Nama")
        Username := r.FormValue("Username")
        Password := r.FormValue("Password")
        Alamat := r.FormValue("Alamat")
        Tempat_Lahir := r.FormValue("Tempat_Lahir")
        Tanggal_Lahir := r.FormValue("Tanggal_Lahir")
        No_HP := r.FormValue("No_HP")
        Pekerjaan := r.FormValue("Pekerjaan")
        Gender := r.FormValue("Gender")
        Email := r.FormValue("Email")
        Nama_Ibu := r.FormValue("Nama_Ibu")

        insertDynStmt := `insert into "employee"("nik", "nama", "username", "password", "alamat", "tempat_lahir", "tanggal_lahir", "no_hp", "pekerjaan", "gender", "email", "nama_ibu", "file") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`
        _, err = db.Exec(insertDynStmt, NIK, Nama, Username, Password, Alamat, Tempat_Lahir, Tanggal_Lahir, No_HP, Pekerjaan, Gender, Email, Nama_Ibu, filename)

        log.Println("INSERT INTO employee(NIK, Nama, Username, Password, Alamat, Tempat_Lahir, Tanggal_Lahir, No_HP, Pekerjaan, Gender, Email, Nama_Ibu, File) VALUES (" + NIK + ", " + Nama + ", " + Username + ", " + Password + ", " + Alamat + ", " + Tempat_Lahir + ", " + Tanggal_Lahir + ", " + No_HP + ", " + Pekerjaan + ", " + Gender + ", " + Email + ", " + Nama_Ibu + ", " + filename + ")")
...

Enter fullscreen mode Exit fullscreen mode

Terakhir, tutup koneksi ke database dan redirect agar user kembali ke halaman utama ketika selesai mengisi formulir.

main.go:Insert

...
defer db.Close()
    http.Redirect(w, r, "/", 301)
}

Enter fullscreen mode Exit fullscreen mode

Hasilnya adalah seperti ini:

main.go

func Insert(w http.ResponseWriter, r *http.Request) {

    db := dbConn()
    if r.Method == "POST" {
        //File Upload
        alias := r.FormValue("alias")
        uploadedFile, handler, err := r.FormFile("file")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer uploadedFile.Close()

        dir, err := os.Getwd()
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        filename := handler.Filename
        if alias != "" {
            filename = fmt.Sprintf("%s%s", alias, filepath.Ext(handler.Filename))
        }

        fileLocation := filepath.Join(dir, "files", filename)
        targetFile, err := os.OpenFile(fileLocation, os.O_WRONLY|os.O_CREATE, 0666)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer targetFile.Close()

        if _, err := io.Copy(targetFile, uploadedFile); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        NIK := r.FormValue("NIK")
        Nama := r.FormValue("Nama")
        Username := r.FormValue("Username")
        Password := r.FormValue("Password")
        Alamat := r.FormValue("Alamat")
        Tempat_Lahir := r.FormValue("Tempat_Lahir")
        Tanggal_Lahir := r.FormValue("Tanggal_Lahir")
        No_HP := r.FormValue("No_HP")
        Pekerjaan := r.FormValue("Pekerjaan")
        Gender := r.FormValue("Gender")
        Email := r.FormValue("Email")
        Nama_Ibu := r.FormValue("Nama_Ibu")

        insertDynStmt := `insert into "employee"("nik", "nama", "username", "password", "alamat", "tempat_lahir", "tanggal_lahir", "no_hp", "pekerjaan", "gender", "email", "nama_ibu", "file") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`
        _, err = db.Exec(insertDynStmt, NIK, Nama, Username, Password, Alamat, Tempat_Lahir, Tanggal_Lahir, No_HP, Pekerjaan, Gender, Email, Nama_Ibu, filename)

        log.Println("INSERT INTO employee(NIK, Nama, Username, Password, Alamat, Tempat_Lahir, Tanggal_Lahir, No_HP, Pekerjaan, Gender, Email, Nama_Ibu, File) VALUES (" + NIK + ", " + Nama + ", " + Username + ", " + Password + ", " + Alamat + ", " + Tempat_Lahir + ", " + Tanggal_Lahir + ", " + No_HP + ", " + Pekerjaan + ", " + Gender + ", " + Email + ", " + Nama_Ibu + ", " + filename + ")")
    }
    defer db.Close()
    http.Redirect(w, r, "/", 301)
}
Enter fullscreen mode Exit fullscreen mode

Ctrl+S, untuk import package yang diperlukan.

Kemudian, kita atur kode agar template kita berjalan. Buat variable tmpl sebelum func dbConn:

main.go

var tmpl = template.Must(template.ParseGlob("form/*"))

Enter fullscreen mode Exit fullscreen mode

Buat fungsi untuk menjalankan template 'New'.

main.go

func New(w http.ResponseWriter, r *http.Request) {

    tmpl.ExecuteTemplate(w, "New", nil)

}
Enter fullscreen mode Exit fullscreen mode

Akhirnya, buat fungsi utama untuk mengatur semua handler:

main.go

func main() {
    log.Println("Server started on: http://localhost:9999")
    http.HandleFunc("/new", New)
    http.HandleFunc("/insert", Insert)
    http.ListenAndServe(":9999", nil)
}

Enter fullscreen mode Exit fullscreen mode

Disini kita buat log agar saat kita jalankan aplikasi, terminal akan memberitahukan kita bahwa server berhasil berjalan di port yang kita inginkan. Atur handler dengan menetapkan alamat internetnya dan fungsi yang dipanggil. Terakhir, kode untuk menjalankan server.

Oke, jalankan server melalui perintah terminal 'go run main.go'. Jika berhasil, maka terminal akan membalas dengan log

Terminal

PS D:\Work\Tutorial\postgre> go run main.go
2023/06/15 15:44:44 Server started on: http://localhost:9999
Enter fullscreen mode Exit fullscreen mode

Buka browser, dan pergi ke alamat http://localhost:9999/new. Jika berhasil, maka hasilnya akan sama dengan tes html yang kita buat di front-end. Isi formulir dan klik 'save user'. Kita akan menemukan '404 not found'. Tapi ini kita tidak masalah, karena kita memang belum mengatur halaman home yang otomatis dituju ketika kita selesai mengisi formulir. Yang penting itu log terminal, dia akan menunjukkan database berhasil terisi atau tidak. Jika berhasil, maka dia akan membalas dengan:

Terminal

2023/06/15 15:36:23 INSERT INTO employee(NIK, Nama, Username, Password, Alamat, Tempat_Lahir, Tanggal_Lahir, No_HP, Pekerjaan, Gender, Email, Nama_Ibu, File) VALUES (33, 333, 333, 352353, 33, 33, 2023-06-11, 33, 33, 33, 33, 33, 33.jpg)

Enter fullscreen mode Exit fullscreen mode

Untuk mengecek apakah database benar-benar terisi, anda bisa cek TablePlus (refresh).

Cek insert

Masih bingung apa yang sebenarnya terjadi? Mari saya jelaskan!
Pertama, fungsi main menjalankan server dengan perintah 'ListenAndServe'. 'http.HandleFunc("/new", New)' akan membuat 'http://localhost:9999/new' bisa diakses dengan memanggil fungsi 'New'. Reaksi berantai pun terjadi:

Insert func

Demikian, fungsi 'Create' berhasil kita buat!

Terakhir, untuk mempermudah transfer knowledge dan rollback, maka main.go akan saya copy, rename menjadi main-v2.go, select all kecuali package kemudian ctrl+/ untuk merubahnya menjadi komentar. Jadi jika anda baru mempelajari tahap ini, anda tidak akan bingung saat anda mengecek repository yang sudah lengkap hingga tahap akhir. Cukup cek file-file v2. Proses rollback juga akan jadi lebih mudah

Repository/source code: https://github.com/JaisySymuri/postgre

Top comments (0)