summaryrefslogtreecommitdiff
path: root/_content/doc/tutorial/database-access/data-access
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2025-11-26 10:36:23 +0700
committerShulhan <ms@kilabit.info>2025-12-05 01:07:27 +0700
commitb6009906d0359cfc44e7a8ef67371ab52f30aa00 (patch)
tree69fa4fdc5793f5d1ecaf9f750def4b3dd5f6a238 /_content/doc/tutorial/database-access/data-access
parenta7c3ec9685f01663bd0ddeabec85842b7fad4a4a (diff)
downloadgolang-id-web-b6009906d0359cfc44e7a8ef67371ab52f30aa00.tar.xz
tutorial: terjemahkan "Tutorial: Accessing a relational database"
Tutorial asli ada di https://go.dev/doc/tutorial/database-access .
Diffstat (limited to '_content/doc/tutorial/database-access/data-access')
-rw-r--r--_content/doc/tutorial/database-access/data-access/create-tables.sql16
-rw-r--r--_content/doc/tutorial/database-access/data-access/go.mod5
-rw-r--r--_content/doc/tutorial/database-access/data-access/go.sum2
-rw-r--r--_content/doc/tutorial/database-access/data-access/main.go124
4 files changed, 147 insertions, 0 deletions
diff --git a/_content/doc/tutorial/database-access/data-access/create-tables.sql b/_content/doc/tutorial/database-access/data-access/create-tables.sql
new file mode 100644
index 0000000..63290a0
--- /dev/null
+++ b/_content/doc/tutorial/database-access/data-access/create-tables.sql
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS album;
+CREATE TABLE album (
+ id SERIAL,
+ title VARCHAR(128) NOT NULL,
+ artist VARCHAR(255) NOT NULL,
+ price DECIMAL(5,2) NOT NULL,
+ PRIMARY KEY (id)
+);
+
+INSERT INTO album
+ (title, artist, price)
+VALUES
+ ('Blue Train', 'John Coltrane', 56.99),
+ ('Giant Steps', 'John Coltrane', 63.99),
+ ('Jeru', 'Gerry Mulligan', 17.99),
+ ('Sarah Vaughan', 'Sarah Vaughan', 34.98);
diff --git a/_content/doc/tutorial/database-access/data-access/go.mod b/_content/doc/tutorial/database-access/data-access/go.mod
new file mode 100644
index 0000000..e33ed8d
--- /dev/null
+++ b/_content/doc/tutorial/database-access/data-access/go.mod
@@ -0,0 +1,5 @@
+module github.com/golang-id/web/data-access
+
+go 1.24.0
+
+require github.com/lib/pq v1.10.9
diff --git a/_content/doc/tutorial/database-access/data-access/go.sum b/_content/doc/tutorial/database-access/data-access/go.sum
new file mode 100644
index 0000000..aeddeae
--- /dev/null
+++ b/_content/doc/tutorial/database-access/data-access/go.sum
@@ -0,0 +1,2 @@
+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
diff --git a/_content/doc/tutorial/database-access/data-access/main.go b/_content/doc/tutorial/database-access/data-access/main.go
new file mode 100644
index 0000000..588422c
--- /dev/null
+++ b/_content/doc/tutorial/database-access/data-access/main.go
@@ -0,0 +1,124 @@
+package main
+
+import (
+ "database/sql"
+ "fmt"
+ "log"
+ "os"
+
+ "github.com/lib/pq"
+)
+
+type Album struct {
+ ID int64
+ Title string
+ Artist string
+ Price float32
+}
+
+// albumsByArtist mengambil album-album berdasarkan nama artis.
+func albumsByArtist(db *sql.DB, name string) ([]Album, error) {
+ // albums adalah slice yang menyimpan data dari hasil kueri.
+ var albums []Album
+
+ rows, err := db.Query(`
+ SELECT id, title, artist, price
+ FROM album
+ WHERE artist = $1`, name)
+ if err != nil {
+ return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
+ }
+ defer rows.Close()
+
+ // Iterasi pada rows, menggunakan Scan untuk menyimpan data ke dalam
+ // struct Album.
+ for rows.Next() {
+ var alb Album
+ err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price)
+ if err != nil {
+ return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
+ }
+ albums = append(albums, alb)
+ }
+ if err := rows.Err(); err != nil {
+ return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
+ }
+ return albums, nil
+}
+
+// albumByID kueri album berdasarkan ID.
+func albumByID(db *sql.DB, id int64) (Album, error) {
+ // Variabel yang menyimpan baris kembalian dari basis-data.
+ var alb Album
+
+ row := db.QueryRow(`
+ SELECT id, title, artist, price
+ FROM album WHERE id = $1", id)
+ err := row.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price)
+ if err != nil {
+ if err == sql.ErrNoRows {
+ return alb, fmt.Errorf("albumsById %d: album tidak ditemukan", id)
+ }
+ return alb, fmt.Errorf("albumsById %d: %v", id, err)
+ }
+ return alb, nil
+}
+
+// addAlbum menambahkan sebuah album baru ke dalam basis-data dan
+// mengembalikan ID album yang baru.
+func addAlbum(db *sql.DB, alb Album) (int64, error) {
+ var id int64
+ err := db.QueryRow(`
+ INSERT INTO album (title, artist, price)
+ VALUES ($1, $2, $3)
+ RETURNING id`,
+ alb.Title, alb.Artist, alb.Price).Scan(&id)
+ if err != nil {
+ return 0, fmt.Errorf("addAlbum: %v", err)
+ }
+ return id, nil
+}
+
+func main() {
+ // Contoh DATABASE_URL = "postgres://username:password@localhost:5432/database_name"
+ databaseUrl := os.Getenv("DATABASE_URL")
+ var connector *pq.Connector
+ var err error
+ connector, err = pq.NewConnector(databaseUrl)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var db *sql.DB
+ db = sql.OpenDB(connector)
+ defer db.Close()
+
+ err = db.Ping()
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println("Terhubung!")
+
+ albums, err := albumsByArtist(db, "John Coltrane")
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("Albums ditemukan: %v\n", albums)
+
+ // Tulis langsung ID 2 untuk menguji kueri.
+ alb, err := albumByID(db, 2)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("Album ditemukan: %v\n", alb)
+
+ albID, err := addAlbum(db, Album{
+ Title: "The Modern Sound of Betty Carter",
+ Artist: "Betty Carter",
+ Price: 49.99,
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("ID dari album baru: %v\n", albID)
+}