Query & CRUD Database

Cara melakukan operasi Create, Read, Update, Delete (CRUD) menggunakan SQL di NusaScript dengan SQLite maupun MySQL.

Fungsi Database Utama

FungsiKeterangan
db_buka(driver, dsn)Buka koneksi database (sqlite / mysql)
db_query(db, sql, ...args)Eksekusi query tanpa kembalian data (INSERT, UPDATE, DELETE, CREATE)
db_ambil_satu(db, sql, ...args)Ambil satu baris hasil SELECT
db_ambil_semua(db, sql, ...args)Ambil semua baris hasil SELECT sebagai array
db_tutup(db)Tutup koneksi database

Membuat Tabel

Contoh — CREATE TABLE
buat db = db_buka("sqlite", "toko.db")

// Buat tabel kategori
db_query(db, "CREATE TABLE IF NOT EXISTS kategori (
    id      INTEGER PRIMARY KEY AUTOINCREMENT,
    nama    TEXT    NOT NULL UNIQUE,
    dibuat  TEXT    DEFAULT (datetime('now'))
)")

// Buat tabel produk dengan foreign key
db_query(db, "CREATE TABLE IF NOT EXISTS produk (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    kategori_id  INTEGER NOT NULL,
    nama         TEXT    NOT NULL,
    deskripsi    TEXT,
    harga        REAL    NOT NULL DEFAULT 0,
    stok         INTEGER NOT NULL DEFAULT 0,
    dibuat       TEXT    DEFAULT (datetime('now')),
    FOREIGN KEY (kategori_id) REFERENCES kategori(id)
)")

tampilkan("Tabel berhasil dibuat!")

INSERT — Menambah Data

Contoh — INSERT
buat db = db_buka("sqlite", "toko.db")

// INSERT satu baris
db_query(db, "INSERT INTO kategori (nama) VALUES (?)", "Elektronik")
db_query(db, "INSERT INTO kategori (nama) VALUES (?)", "Pakaian")
db_query(db, "INSERT INTO kategori (nama) VALUES (?)", "Makanan")

// INSERT produk dengan banyak field
db_query(db,
    "INSERT INTO produk (kategori_id, nama, deskripsi, harga, stok) VALUES (?, ?, ?, ?, ?)",
    1,
    "Laptop Gaming",
    "Laptop performa tinggi untuk gaming dan kerja",
    15000000,
    10
)

tampilkan("Data berhasil ditambahkan!")

SELECT — Membaca Data

Ambil Semua Baris

Contoh — SELECT *
buat db   = db_buka("sqlite", "toko.db")
buat data = db_ambil_semua(db, "SELECT * FROM kategori")

tampilkan("Jumlah kategori:", panjang(data))

// Loop semua baris
buat i = 0
selama i < panjang(data) {
    buat baris = data[i]
    buat id    = ambil(baris, "id")
    buat nama  = ambil(baris, "nama")
    tampilkan(id, "-", nama)
    i += 1
}
Output
Jumlah kategori: 3
1 - Elektronik
2 - Pakaian
3 - Makanan

Ambil Satu Baris

Contoh — SELECT ONE
buat db   = db_buka("sqlite", "toko.db")
buat baris = db_ambil_satu(db,
    "SELECT * FROM produk WHERE id = ?", 1)

jika baris == nihil {
    tampilkan("Produk tidak ditemukan")
} lain {
    tampilkan("Nama   :", ambil(baris, "nama"))
    tampilkan("Harga  :", format_rupiah(ambil(baris, "harga")))
    tampilkan("Stok   :", ambil(baris, "stok"))
}
Output
Nama   : Laptop Gaming
Harga  : Rp 15.000.000
Stok   : 10

SELECT dengan WHERE, ORDER, LIMIT

Contoh — Query Lanjut
buat db = db_buka("sqlite", "toko.db")

// Produk dengan harga > 1.000.000, urutkan termahal, maks 5
buat data = db_ambil_semua(db,
    "SELECT * FROM produk WHERE harga > ? ORDER BY harga DESC LIMIT ?",
    1000000, 5)

// JOIN — produk dengan nama kategorinya
buat dengan_kategori = db_ambil_semua(db, "
    SELECT p.id, p.nama, p.harga, k.nama AS kategori
    FROM   produk p
    JOIN   kategori k ON p.kategori_id = k.id
    WHERE  p.stok > 0
    ORDER  BY p.nama ASC
")

buat i = 0
selama i < panjang(dengan_kategori) {
    buat r = dengan_kategori[i]
    tampilkan(ambil(r, "nama"), "-", ambil(r, "kategori"),
          "-", format_rupiah(ambil(r, "harga")))
    i += 1
}

UPDATE — Memperbarui Data

Contoh — UPDATE
buat db = db_buka("sqlite", "toko.db")

// Update harga satu produk
db_query(db, "UPDATE produk SET harga = ? WHERE id = ?",
    12000000, 1)

// Update stok — kurangi stok setelah penjualan
buat id_produk = 1
buat jumlah    = 3
db_query(db, "UPDATE produk SET stok = stok - ? WHERE id = ?",
    jumlah, id_produk)

// Update banyak field sekaligus
db_query(db,
    "UPDATE produk SET nama=?, harga=?, stok=? WHERE id=?",
    "Laptop Gaming Pro", 18000000, 5, 1)

tampilkan("Data berhasil diperbarui!")

DELETE — Menghapus Data

Contoh — DELETE
buat db = db_buka("sqlite", "toko.db")

// Hapus satu produk berdasarkan ID
db_query(db, "DELETE FROM produk WHERE id = ?", 5)

// Hapus produk yang stoknya habis
db_query(db, "DELETE FROM produk WHERE stok <= 0")

// Hapus dengan konfirmasi
buat id_hapus = 3
buat ada = db_ambil_satu(db, "SELECT id FROM produk WHERE id=?", id_hapus)
jika ada != nihil {
    db_query(db, "DELETE FROM produk WHERE id=?", id_hapus)
    tampilkan("Produk", id_hapus, "berhasil dihapus")
} lain {
    tampilkan("Produk tidak ditemukan")
}

Transaksi Database

Gunakan transaksi untuk memastikan beberapa operasi dieksekusi secara atomik (semua berhasil atau semua dibatalkan).

Contoh — Proses Penjualan
buat db = db_buka("sqlite", "toko.db")

// Gunakan transaksi untuk proses penjualan
db_query(db, "BEGIN")

// 1. Catat transaksi penjualan
db_query(db,
    "INSERT INTO transaksi (produk_id, jumlah, total) VALUES (?, ?, ?)",
    1, 2, 24000000)

// 2. Kurangi stok
db_query(db,
    "UPDATE produk SET stok = stok - ? WHERE id = ?",
    2, 1)

// Cek stok tidak negatif
buat produk = db_ambil_satu(db, "SELECT stok FROM produk WHERE id=?", 1)
buat stok   = ambil(produk, "stok")

jika stok < 0 {
    db_query(db, "ROLLBACK")
    tampilkan("Gagal! Stok tidak mencukupi")
} lain {
    db_query(db, "COMMIT")
    tampilkan("Transaksi berhasil!")
}

Contoh Lengkap — REST API CRUD

Contoh — API Produk Lengkap
buat app = server_baru(8080)
buat db  = db_buka("sqlite", "toko.db")

// Inisialisasi tabel
db_query(db, "CREATE TABLE IF NOT EXISTS produk (
    id    INTEGER PRIMARY KEY AUTOINCREMENT,
    nama  TEXT    NOT NULL,
    harga REAL    NOT NULL,
    stok  INTEGER DEFAULT 0
)")

// GET /api/produk — ambil semua
tambah_rute(app, "GET", "/api/produk", fungsi(req) {
    buat q    = param_query(req, "cari")
    buat data = []
    jika q != "" {
        data = db_ambil_semua(db,
            "SELECT * FROM produk WHERE nama LIKE ?",
            "%" + q + "%")
    } lain {
        data = db_ambil_semua(db, "SELECT * FROM produk ORDER BY id DESC")
    }
    kembalikan ke_json({"sukses": benar, "data": data, "total": panjang(data)})
})

// GET /api/produk?id=1 — ambil satu
tambah_rute(app, "GET", "/api/produk/detail", fungsi(req) {
    buat id = param_query(req, "id")
    jika id == "" {
        kembalikan ke_json({"error": "Parameter id wajib"})
    }
    buat produk = db_ambil_satu(db,
        "SELECT * FROM produk WHERE id=?", ke_bilangan(id))
    jika produk == nihil {
        kembalikan ke_json({"error": "Produk tidak ditemukan"})
    }
    kembalikan ke_json({"sukses": benar, "data": produk})
})

// POST /api/produk — tambah baru
tambah_rute(app, "POST", "/api/produk", fungsi(req) {
    buat b     = body_json(req)
    buat nama  = ambil(b, "nama")
    buat harga = ambil(b, "harga")
    buat stok  = ambil(b, "stok")
    jika nama == nihil atau nama == "" {
        kembalikan ke_json({"error": "Nama wajib diisi"})
    }
    db_query(db,
        "INSERT INTO produk (nama, harga, stok) VALUES (?, ?, ?)",
        nama, harga, stok)
    kembalikan ke_json({"sukses": benar, "pesan": "Produk ditambahkan"})
})

// PUT /api/produk — update
tambah_rute(app, "PUT", "/api/produk", fungsi(req) {
    buat b     = body_json(req)
    buat id    = ambil(b, "id")
    buat nama  = ambil(b, "nama")
    buat harga = ambil(b, "harga")
    buat stok  = ambil(b, "stok")
    db_query(db,
        "UPDATE produk SET nama=?, harga=?, stok=? WHERE id=?",
        nama, harga, stok, id)
    kembalikan ke_json({"sukses": benar, "pesan": "Produk diperbarui"})
})

// DELETE /api/produk — hapus
tambah_rute(app, "DELETE", "/api/produk", fungsi(req) {
    buat b  = body_json(req)
    buat id = ambil(b, "id")
    jika id == nihil {
        kembalikan ke_json({"error": "ID wajib diisi"})
    }
    db_query(db, "DELETE FROM produk WHERE id=?", id)
    kembalikan ke_json({"sukses": benar, "pesan": "Produk dihapus"})
})

tampilkan("Server berjalan di http://localhost:8080")
jalankan_server(app)
📌 Selalu gunakan parameter (?) dalam query SQL untuk menghindari SQL Injection. Jangan pernah memasukkan input pengguna langsung ke dalam string SQL.

Fluent ORM (Query Builder)

Selain menulis SQL mentah, NusaScript menyediakan Query Builder untuk membangun query secara programatis. Tidak perlu menulis SQL secara langsung!

Fungsi Query Builder

FungsiOperasiDeskripsi
buat_query(tabel)Buat query builder untuk tabel
dimana(qb, kolom, op, nilai)WHERETambah kondisi filter
urut(qb, kolom, arah?)ORDER BYUrutkan hasil
batas(qb, jumlah)LIMITBatasi jumlah hasil
eksekusi_query(qb)SELECTAmbil banyak baris
cari(qb, id)SELECTAmbil satu baris by ID
hitung(qb)COUNTHitung jumlah baris
sisipkan(tabel, data)INSERTTambah data baru
perbarui(qb, data)UPDATEUpdate data yang ada
hapus_data(qb)DELETEHapus data

SELECT — Ambil Data

Contoh — Query Builder SELECT
buat db = db_buka("sqlite", "toko.db")

// Ambil semua produk
buat qb = buat_query("produk")
buat semua = eksekusi_query(qb)

// Dengan filter, urutan, dan batas
buat qb = buat_query("produk")
buat qb = dimana(qb, "harga", ">", 10000)
buat qb = dimana(qb, "stok", ">", 0)
buat qb = urut(qb, "harga", "DESC")
buat qb = batas(qb, 10)
buat data = eksekusi_query(qb)
// SQL: SELECT * FROM produk WHERE harga > ? AND stok > ? ORDER BY harga DESC LIMIT 10

FIND — Cari by ID

Contoh — Cari Satu Baris
buat qb = buat_query("produk")
buat produk = cari(qb, 1)
// SQL: SELECT * FROM produk WHERE id = ?

jika produk != nihil {
    tampilkan("Nama:", ambil(produk, "nama"))
}

COUNT — Hitung Jumlah

Contoh — Hitung Data
buat qb = buat_query("produk")
buat qb = dimana(qb, "stok", ">", 0)
buat total = hitung(qb)
// SQL: SELECT COUNT(*) FROM produk WHERE stok > ?

tampilkan("Total produk tersedia:", total)

INSERT — Tambah Data

Contoh — Sisipkan dengan Peta
// INSERT dari Peta
sisipkan("produk", peta(
    "nama", "Laptop Gaming",
    "harga", 15000000,
    "stok", 10
))
// SQL: INSERT INTO produk (nama, harga, stok) VALUES (?, ?, ?)

// INSERT dari Struct
tipe Produk {
    nama: teks
    harga: bilangan
    stok: bilangan
}

buat p = Produk {
    nama: "Monitor 4K",
    harga: 5000000,
    stok: 25
}
sisipkan("produk", p)

UPDATE — Perbarui Data

Contoh — Perbarui dengan Kondisi
// Update produk WHERE id = 1
buat qb = buat_query("produk")
buat qb = dimana(qb, "id", "=", 1)

perbarui(qb, peta(
    "harga", 12000000,
    "stok", 5
))
// SQL: UPDATE produk SET harga = ?, stok = ? WHERE id = ?

DELETE — Hapus Data

Contoh — Hapus dengan Kondisi
// Hapus produk WHERE id = 5
buat qb = buat_query("produk")
buat qb = dimana(qb, "id", "=", 5)
hapus_data(qb)
// SQL: DELETE FROM produk WHERE id = ?

// Hapus produk yang stoknya habis
buat qb = buat_query("produk")
buat qb = dimana(qb, "stok", "<=", 0)
hapus_data(qb)
// SQL: DELETE FROM produk WHERE stok <= ?
⚠️ Keamanan: Fungsi hapus_data() wajib menggunakan dimana() — tidak bisa hapus seluruh tabel tanpa kondisi WHERE.

Contoh Lengkap — REST API CRUD dengan ORM

Contoh — Full CRUD API
buat app = server_baru(8080)
buat db  = db_buka("sqlite", "toko.db")

// GET /api/produk — ambil semua
rute(app, "GET", "/api/produk", fungsi(req) {
    buat qb = buat_query("produk")
    buat qb = dimana(qb, "stok", ">", 0)
    buat qb = urut(qb, "nama", "ASC")
    buat qb = batas(qb, 20)
    buat data = eksekusi_query(qb)
    kembalikan ke_json(peta("sukses", benar, "data", data))
})

// GET /api/produk/1 — ambil satu
rute(app, "GET", "/api/produk/:id", fungsi(req) {
    buat qb = buat_query("produk")
    buat produk = cari(qb, req.params.id)
    jika produk == nihil {
        kembalikan ke_json(peta("error", "Tidak ditemukan"))
    }
    kembalikan ke_json(peta("sukses", benar, "data", produk))
})

// POST /api/produk — tambah baru
rute(app, "POST", "/api/produk", fungsi(req) {
    buat body = dari_json(req.body)
    sisipkan("produk", body)
    kembalikan ke_json(peta("sukses", benar, "pesan", "Produk ditambahkan"))
})

// PUT /api/produk — update
rute(app, "PUT", "/api/produk", fungsi(req) {
    buat body = dari_json(req.body)
    buat qb = buat_query("produk")
    buat qb = dimana(qb, "id", "=", ambil(body, "id"))
    perbarui(qb, peta(
        "nama", ambil(body, "nama"),
        "harga", ambil(body, "harga")
    ))
    kembalikan ke_json(peta("sukses", benar, "pesan", "Produk diperbarui"))
})

// DELETE /api/produk — hapus
rute(app, "DELETE", "/api/produk", fungsi(req) {
    buat body = dari_json(req.body)
    buat qb = buat_query("produk")
    buat qb = dimana(qb, "id", "=", ambil(body, "id"))
    hapus_data(qb)
    kembalikan ke_json(peta("sukses", benar, "pesan", "Produk dihapus"))
})

jalankan_server(app)
📌 Tips: Query Builder otomatis menggunakan parameterized queries (?) sehingga aman dari SQL Injection.