š¬ Golang Ticket Booking System from Scratch ā No Framework (Part 1)
Pada part pertama ini, kita akan memulai dari nol:
- Membuat struktur folder project
- Setup database MySQL
- Install dependency driver SQL
- Membuat repository awal
- Menulis unit test untuk function
GetSeatStatus, termasuk test error case
š§± Step 1: Inisialisasi Proyek
mkdir ticket-booking
cd ticket-booking
go mod init github.com/fardannozami/ticket-bookingš¢ļø Step 2: Setup Database (MySQL)
Masuk ke MySQL dan jalankan query berikut:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
);
CREATE TABLE events(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
quota INT NOT NULL
);
CREATE TABLE seats(
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT NOT NULL,
seat_number VARCHAR(30) NOT NULL,
status ENUM('AVAILABLE', 'BOOKED') DEFAULT 'AVAILABLE',
FOREIGN KEY(event_id) REFERENCES events(id) ON DELETE CASCADE
);
CREATE TABLE bookings(
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT NOT NULL,
seat_id INT NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_booking(event_id, seat_id, user_id),
FOREIGN KEY(event_id) REFERENCES events(id) ON DELETE CASCADE,
FOREIGN KEY(seat_id) REFERENCES seats(id) ON DELETE CASCADE,
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);š¦ Step 3: Install Dependency Driver MySQL
go get github.com/go-sql-driver/mysqlš Step 4: Struktur Folder dan Booking Repository
Buat folder:
mkdir repositoryFile: repository/booking_repository.go
package repository
import (
"context"
"database/sql"
"github.com/fardannozami/ticket-booking/helper"
)
type BookingRepository interface {
GetSeatStatus(ctx context.Context, tx *sql.Tx, seatId int) string
}
type BookingRepositoryImpl struct{}
func NewBookingRepository() BookingRepository {
return &BookingRepositoryImpl{}
}
func (repo *BookingRepositoryImpl) GetSeatStatus(ctx context.Context, tx *sql.Tx, seatId int) string {
var status string
SQL := `SELECT status FROM seats WHERE id = ?`
err := tx.QueryRowContext(ctx, SQL, seatId).Scan(&status)
helper.PanicIfError(err)
return status
}š°ļø Step 5: Buat Helper helper/error.go
package helper
func PanicIfError(err error) {
if err != nil {
panic(err)
}
}š°ļø Step 6: Unit Test untuk GetSeatStatus
sebelumnya install dependency untuk testing dulu
go get github.com/stretchr/testify/assertFile: repository/booking_repository_test.go
package repository
import (
"context"
"database/sql"
"os"
"testing"
"github.com/fardannozami/ticket-booking/helper"
"github.com/stretchr/testify/assert"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
func TestMain(m *testing.M) {
var err error
db, err = sql.Open("mysql", "root@tcp(127.0.0.1:3306)/ticket-booking?charset=utf8mb4&parseTime=True&loc=Local")
helper.PanicIfError(err)
exitCode := m.Run()
db.Close()
os.Exit(exitCode)
}
func insertEvent(id, quota int, name string) {
SQL := `INSERT INTO events (id, quota, name) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE quota = VALUES(quota), name = VALUES(name)`
_, err := db.Exec(SQL, id, quota, name)
helper.PanicIfError(err)
}
func insertSeat(id, eventId int, status, seatNumber string) {
SQL := `INSERT INTO seats (id, event_id, status, seat_number) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE status = VALUES(status), seat_number = VALUES(seat_number)`
_, err := db.Exec(SQL, id, eventId, status, seatNumber)
helper.PanicIfError(err)
}
func TestGetSeatStatus(t *testing.T) {
insertEvent(1, 100, "Event 1")
insertSeat(9, 1, "AVAILABLE", "A1")
repo := NewBookingRepository()
ctx := context.Background()
tx, err := db.BeginTx(ctx, nil)
helper.PanicIfError(err)
defer tx.Rollback()
status := repo.GetSeatStatus(ctx, tx, 9)
assert.Equal(t, "AVAILABLE", status)
}More Articles
You might also like
Package testing di Golang
š§ Pendahuluan Testing adalah bagian penting dari pengembangan software. Dengan menulis test, kita bisa memastikan kode berjalan sesuai harapan, menghindari bug, dan memudahkan refactoring. Golang punya package testing bawaan yang powerful, mudah dig...
Memulai Program dengan Hello World
Dalam seri Golang Basic ini, kita akan memulai dengan program Hello World. Program ini adalah gerbang pertama dalam mempelajari bahasa pemrograman dan telah menjadi tradisi sejak diinisiasi oleh Brian Kernighan bertahun-tahun yang lalu. Struktur Prog...
Mengenal Package io dan bufio di Golang
Selamat datang di tutorial keempat dari seri Golang Standard Library! Pada tutorial ini, kita akan membahas dua package penting dalam Golang, yaitu io dan bufio. Kedua package ini sangat berguna untuk operasi input/output (I/O) yang efisien dan mudah...