From 648d6c213ede7c471306823b53358d596204640f Mon Sep 17 00:00:00 2001 From: RyoLeee Date: Wed, 10 Dec 2025 09:50:31 +0700 Subject: [PATCH] Add week3_answer folder --- week3_answer/addreas_api_book/addreas_book.db | 0 week3_answer/addreas_api_book/app.js | 16 +++ .../addreas_api_book/connection/connection.js | 0 .../controller/contactController.js | 54 ++++++++ .../controller/contactGroupController.js | 58 ++++++++ .../controller/groupController.js | 53 +++++++ week3_answer/addreas_api_book/database.js | 34 +++++ .../addreas_api_book/router/router.js | 26 ++++ week3_answer/addreas_api_book/testing-api.js | 62 +++++++++ .../controller/contact.controller.js | 92 +++++++++++++ .../controller/contactGroup.controller.js | 77 +++++++++++ .../controller/groups.controller.js | 65 +++++++++ week3_answer/addreas_book/main.js | 99 ++++++++++++++ .../addreas_book/mini_database/contact.db | 0 .../mini_database/groupContract.db | 0 .../addreas_book/mini_database/groups.db | 0 week3_answer/addreas_book/view.js | 31 +++++ week3_answer/design_database/chearsheet.db | 69 ++++++++++ week3_answer/design_database/cheatsheet.md | 70 ++++++++++ week3_answer/warehouseDB_Project/massage.md | 37 +++++ .../warehouseDB_Project/warehouse.sql | 101 ++++++++++++++ .../werehouseNSQL_Porject/inventory.json | 24 ++++ .../werehouseNSQL_Porject/orders.json | 34 +++++ .../werehouseNSQL_Porject/products.json | 24 ++++ week3_answer/werehouseNSQL_Porject/queries.md | 129 ++++++++++++++++++ 25 files changed, 1155 insertions(+) create mode 100644 week3_answer/addreas_api_book/addreas_book.db create mode 100644 week3_answer/addreas_api_book/app.js create mode 100644 week3_answer/addreas_api_book/connection/connection.js create mode 100644 week3_answer/addreas_api_book/controller/contactController.js create mode 100644 week3_answer/addreas_api_book/controller/contactGroupController.js create mode 100644 week3_answer/addreas_api_book/controller/groupController.js create mode 100644 week3_answer/addreas_api_book/database.js create mode 100644 week3_answer/addreas_api_book/router/router.js create mode 100644 week3_answer/addreas_api_book/testing-api.js create mode 100644 week3_answer/addreas_book/controller/contact.controller.js create mode 100644 week3_answer/addreas_book/controller/contactGroup.controller.js create mode 100644 week3_answer/addreas_book/controller/groups.controller.js create mode 100644 week3_answer/addreas_book/main.js create mode 100644 week3_answer/addreas_book/mini_database/contact.db create mode 100644 week3_answer/addreas_book/mini_database/groupContract.db create mode 100644 week3_answer/addreas_book/mini_database/groups.db create mode 100644 week3_answer/addreas_book/view.js create mode 100644 week3_answer/design_database/chearsheet.db create mode 100644 week3_answer/design_database/cheatsheet.md create mode 100644 week3_answer/warehouseDB_Project/massage.md create mode 100644 week3_answer/warehouseDB_Project/warehouse.sql create mode 100644 week3_answer/werehouseNSQL_Porject/inventory.json create mode 100644 week3_answer/werehouseNSQL_Porject/orders.json create mode 100644 week3_answer/werehouseNSQL_Porject/products.json create mode 100644 week3_answer/werehouseNSQL_Porject/queries.md diff --git a/week3_answer/addreas_api_book/addreas_book.db b/week3_answer/addreas_api_book/addreas_book.db new file mode 100644 index 00000000..e69de29b diff --git a/week3_answer/addreas_api_book/app.js b/week3_answer/addreas_api_book/app.js new file mode 100644 index 00000000..415af4f2 --- /dev/null +++ b/week3_answer/addreas_api_book/app.js @@ -0,0 +1,16 @@ +const express = require("express"); +const app = express(); +const port = 3000; +require("./db/database") +const router = require("./router/router") +app.use(express.json()); + +app.get("/", (req, res) => { + res.send("hello world"); +}); + +app.use(router) + +app.listen(port, () => { + console.log("Server is running in port: " + port); +}); \ No newline at end of file diff --git a/week3_answer/addreas_api_book/connection/connection.js b/week3_answer/addreas_api_book/connection/connection.js new file mode 100644 index 00000000..e69de29b diff --git a/week3_answer/addreas_api_book/controller/contactController.js b/week3_answer/addreas_api_book/controller/contactController.js new file mode 100644 index 00000000..1b92edcf --- /dev/null +++ b/week3_answer/addreas_api_book/controller/contactController.js @@ -0,0 +1,54 @@ +let db = require("../database"); +class ContactController { + constructor(name, phone) { + this.name = name; + this.phone = phone; + } + + static createContact(name, phone) { + return new Promise((resolve, reject) => { + db.run( + `INSERT INTO contacts (name, phone) VALUES (?, ?)`, + [name, phone], + (err) => { + if (err) reject(err); + resolve(); + } + ); + }); + } + + static updateContact(id, name, phone) { + let updateContact = new ContactController(id, name, phone); + return new Promise((resolve, reject) => { + db.run( + `UPDATE contacts SET name = ?, phone = ? WHERE id = ?`, + [updateContact.name, updateContact.phone, updateContact.id], + (err) => { + if (err) reject(err); + resolve(); + } + ); + }); + } + + static deleteContact(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM contacts WHERE id = ?`, [id], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } + + static getContacts() { + return new Promise((resolve, reject) => { + db.all(`SELECT * FROM contacts`, (err, rows) => { + if (err) reject(err); + resolve(rows); + }); + }); + } +} + +module.exports = ContactController; diff --git a/week3_answer/addreas_api_book/controller/contactGroupController.js b/week3_answer/addreas_api_book/controller/contactGroupController.js new file mode 100644 index 00000000..724d1f63 --- /dev/null +++ b/week3_answer/addreas_api_book/controller/contactGroupController.js @@ -0,0 +1,58 @@ +let db = require("../database"); +class ContactGroupController { + constructor(contactId, groupId) { + this.contactId = contactId; + this.groupId = groupId; + } + + static createContactGroup(contactId, groupId) { + return new Promise((resolve, reject) => { + db.run( + `INSERT INTO contact_group (contact_id, group_id) VALUES (?, ?)`, + [contactId, groupId], + (err) => { + if (err) reject(err); + resolve(); + } + ); + }); + } + + static updateContactGroup(id, contactId, groupId) { + let updateContactGroup = new ContactGroupController(id, contactId, groupId); + return new Promise((resolve, reject) => { + db.run( + `UPDATE contact_group SET contact_id = ?, group_id = ? WHERE id = ?`, + [ + updateContactGroup.contactId, + updateContactGroup.groupId, + updateContactGroup.id, + ], + (err) => { + if (err) reject(err); + resolve(); + } + ); + }); + } + + static deleteContactGroup(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM contact_group WHERE id = ?`, [id], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } + + static getContactGroups() { + return new Promise((resolve, reject) => { + db.all(`SELECT * FROM contact_group`, (err, rows) => { + if (err) reject(err); + resolve(rows); + }); + }); + } +} + +module.exports = ContactGroupController; diff --git a/week3_answer/addreas_api_book/controller/groupController.js b/week3_answer/addreas_api_book/controller/groupController.js new file mode 100644 index 00000000..ae48e918 --- /dev/null +++ b/week3_answer/addreas_api_book/controller/groupController.js @@ -0,0 +1,53 @@ +let db = require("../database"); +class GroupController { + constructor(name) { + this.name = name; + } + + static createGroup(name) { + return new Promise((resolve, reject) => { + db.run(`INSERT INTO groups (name) VALUES (?)`, [name], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } + + static updateGroup(id, name) { + return new Promise((resolve, reject) => { + db.run(`UPDATE groups SET name = ? WHERE id = ?`, [name, id], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } + + static deleteGroup(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM groups WHERE id = ?`, [id], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } + + static getGroups() { + return new Promise((resolve, reject) => { + db.all(`SELECT * FROM groups`, (err, rows) => { + if (err) reject(err); + resolve(rows); + }); + }); + } + + static deleteGroup(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM groups WHERE id = ?`, [id], (err) => { + if (err) reject(err); + resolve(); + }); + }); + } +} + +module.exports = GroupController; diff --git a/week3_answer/addreas_api_book/database.js b/week3_answer/addreas_api_book/database.js new file mode 100644 index 00000000..6ef15818 --- /dev/null +++ b/week3_answer/addreas_api_book/database.js @@ -0,0 +1,34 @@ +const sqlite3 = require("sqlite3").verbose(); + +const db = new sqlite3.Database("./addreas_book.db", (err) => { + if (err) { + console.log("Gagal konek DB:", err.message); + } else { + console.log("SQLite connected"); + } +}); + +db.run(` + CREATE TABLE IF NOT EXISTS contacts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + phone TEXT + ) +`); + +db.run(` + CREATE TABLE IF NOT EXISTS groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT + ) +`); + +db.run(` + CREATE TABLE IF NOT EXISTS contact_group ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + contact_id INTEGER, + group_id INTEGER + ) +`); + +module.exports = db; diff --git a/week3_answer/addreas_api_book/router/router.js b/week3_answer/addreas_api_book/router/router.js new file mode 100644 index 00000000..5a4bd37e --- /dev/null +++ b/week3_answer/addreas_api_book/router/router.js @@ -0,0 +1,26 @@ +const express = require("express"); +const router = express.Router(); +const contactController = require("../controller/contactController"); +const groupController = require("../controller/groupController"); +const contactGroupController = require("../controller/contactGroupController"); + +router + .route("/contact") + .get(contactController.getContacts) + .post(contactController.createContact); + +router.put("/contact/:id", contactController.updateContact); +router.delete("/contact/:id", contactController.deleteContact); + +router + .route("/groups") + .get(groupController.getGroups) + .post(groupController.createGroups); +router.put("/groups/:id", groupController.updateGroups); +router.delete("/groups/:id", groupController.deleteGroups); + +router.post("/contactGroup", contactGroupController.createContactGroup); +router.put("/contactGroup/:id", contactGroupController.updateContactGroup); +router.delete("/contactGroup/:id", contactGroupController.deleteContactGroup); + +module.exports = router; \ No newline at end of file diff --git a/week3_answer/addreas_api_book/testing-api.js b/week3_answer/addreas_api_book/testing-api.js new file mode 100644 index 00000000..f554ae49 --- /dev/null +++ b/week3_answer/addreas_api_book/testing-api.js @@ -0,0 +1,62 @@ +const axios = require("axios"); + +const API = "http://localhost:3000"; + + +axios.post(`${API}/contact`, { + name: "Ryo", + phone: "08123456789" +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.get(`${API}/contact`) + .then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.put(`${API}/contact/1`, { + name: "Ryo Update", + phone: "08999999" +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.delete(`${API}/contact/1`) + .then(res => console.log(res.data)) + .catch(err => console.log(err)); + + + +axios.post(`${API}/groups`, { + name: "Teman" +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.get(`${API}/groups`) + .then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.put(`${API}/groups/1`, { + name: "Keluarga" +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.delete(`${API}/groups/1`) + .then(res => console.log(res.data)) + .catch(err => console.log(err)); + + + +axios.post(`${API}/contactGroup`, { + contact_id: 1, + group_id: 2 +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.put(`${API}/contactGroup/1`, { + contact_id: 2, + group_id: 3 +}).then(res => console.log(res.data)) + .catch(err => console.log(err)); + +axios.delete(`${API}/contactGroup/1`) + .then(res => console.log(res.data)) + .catch(err => console.log(err)); diff --git a/week3_answer/addreas_book/controller/contact.controller.js b/week3_answer/addreas_book/controller/contact.controller.js new file mode 100644 index 00000000..426c606f --- /dev/null +++ b/week3_answer/addreas_book/controller/contact.controller.js @@ -0,0 +1,92 @@ +const path = require("path"); + +let db = path.join(__dirname, "../mini_database/contact.db"); +let view = require(path.join(__dirname, "../view")); + +class Contactengine { + constructor(name, phoneNumber, company, email) { + this.name = name; + this.phoneNumber = phoneNumber; + this.company = company; + this.email = email; + } + + static createContact(name, phoneNumber, company, email) { + let newContact = new Contactengine(name, phoneNumber, company, email); + return new Promise((resolve, reject) => { + db.run( + `INSERT INTO Contact VALUES (null, ?, ?, ?, ?)`, + [ + newContact.name, + newContact.phoneNumber, + newContact.company, + newContact.email, + ], + (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static updateContact(id, name, phoneNumber, company, email) { + let updateContact = new Contactengine(id, name, phoneNumber, company, email); + return new Promise((resolve, reject) => { + db.run( + `UPDATE Contact SET name = ?, phoneNumber = ?, company = ?, email = ? WHERE id ?`, + [ + updateContact.name, + updateContact.phoneNumber, + updateContact.company, + updateContact.email, + updateContact.id, + ], + (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static deleteContact(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM Contact WHERE id ?`, [id], (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + }); + }); + } + + static showContact() { + return new Promise((resolve, reject) => { + db.all(`SELECT * FROM Contact`, [], (err, rows) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.contactShow(rows); + resolve(rows); + } + }); + }); + } +} + +module.exports = Contactengine; diff --git a/week3_answer/addreas_book/controller/contactGroup.controller.js b/week3_answer/addreas_book/controller/contactGroup.controller.js new file mode 100644 index 00000000..29264a9b --- /dev/null +++ b/week3_answer/addreas_book/controller/contactGroup.controller.js @@ -0,0 +1,77 @@ +let db = require("../mini_database/contact.db"); +let view = require("../view"); + +class Cgengine { + constructor(groupName, id) { + this.name = groupName; + this.id = id; + } + + static createGroup(groupname) { + return new Promise((resolve, reject) => { + db.run( + `INSERT INTO Groups (id, groupName) VALUES (null, ?)`, + [groupName], + (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static updateGroup(id, groupName) { + let newGroup = new Cgengine(id, groupName); + return new Promise((resolve, reject) => { + db.run( + `UPDATE Groups SET groupName = ? WHERE id = ?`, + [newGroup.groupName], + [newGroup.id], + (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static deleteGroup(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM Groups WHERE id = ?`, [id], (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + }); + }); + } + + static showGroup() { + return new Promise((resolve, reject) => { + db.all(`SELECT * FROM Groups`, [], (err, rows) => { + if ((err, rows)) { + view.errView(err); + reject(err); + } else { + view.groupShow(rows); + resolve(rows); + } + }); + }); + } +} + +module.exports = Cgengine; diff --git a/week3_answer/addreas_book/controller/groups.controller.js b/week3_answer/addreas_book/controller/groups.controller.js new file mode 100644 index 00000000..33315eb1 --- /dev/null +++ b/week3_answer/addreas_book/controller/groups.controller.js @@ -0,0 +1,65 @@ +let db = require("../mini_database/groups.db"); +let view = require("../view"); + +class Groupengine { + constructor(name) { + this.name = name; + } + + static createCG(contactId, groupId) { + return new Promise((resolve, reject) => { + db.run( + `INSERT INTO GroupContact (ContactId, GroupId) + SELECT c.id, g.id + FROM Contact c, Groups g + WHERE c.id = ? + AND g.id = ?`, + [contactId, groupId], + function (err) { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static updateCG(id, contactId, groupId) { + let contactGroup = new createCG(id, contactId, groupId); + return new Promise((resolve, reject) => { + db.run( + `UPDATE GroupContact SET ContactId = ?, GroupId = ? WHERE id = ?`, + [contactGroup.contactId, contactGroup.groupId, contactGroup.id], + (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + } + ); + }); + } + + static deleteCG(id) { + return new Promise((resolve, reject) => { + db.run(`DELETE FROM GroupContact WHERE id = ?`, [id], (err) => { + if (err) { + view.errView(err); + reject(err); + } else { + view.sucessView(); + resolve(); + } + }); + }); + } +} + +module.exports = Groupengine; diff --git a/week3_answer/addreas_book/main.js b/week3_answer/addreas_book/main.js new file mode 100644 index 00000000..2c17e517 --- /dev/null +++ b/week3_answer/addreas_book/main.js @@ -0,0 +1,99 @@ +let command = process.argv[2]; +let entity = process.argv[3]; +let argument = process.argv.slice(4); +const contactController = require("./controller/contact.controller.js"); +const groupController = require("./controller/groups.controller"); +const contactGroup_Controller = require("./controller/contactGroup.controller.js"); + +if (entity === undefined) { + switch (command) { + case "help": + console.log(` + ==================== + ADDRESS BOOK COMMAND + ==================== + + > node main.js create Contact + > node main.js update Contact + > node main.js delete Contact + > node main.js showContact + + > node main.js create Groups + > node main.js update Groups + > node main.js delete Groups + > node main.js showGroups + + > node main.js create ContactGroups + > node main.js update ContactGroups + > node main.js delete ContactGroups + + > node main.js help + `); + break; + + case "showContact": + contactController.contactShow(); + break; + + case "showGroups": + groupController.groupShow(); + break; + } +} else { + let fullCommand = `${command} ${entity}`.trim(); + + switch (fullCommand) { + case "create Contact": + contactController.createContact( + argument[0], + argument[1], + argument[2], + argument[3] + ); + break; + + case "update Contact": + contactController.updateContact( + argument[0], + argument[1], + argument[2].argument[3], + argument[5] + ); + break; + + case "delete Contact": + contactController.deleteContact(argument[0]); + break; + + case "create Groups": + groupController.createGroup(argument[0]); + break; + + case "update Groups": + groupController.updateGroup(argument[0], argument[1]); + break; + + case "delete Groups": + groupController.deleteGroup(argument[0]); + break; + + case "create ContactGroups": + contactGroup_Controller.creatCG(argument[0], argument[1]); + break; + + case "update ContactGroups": + contactGroup_Controller.updateCG(argument[0], argument[1], argument[2]); + break; + + case "delete ContactGroups": + contactGroup_Controller.deleteCG(argument[0]); + break; + + default: + console.log("Command tidak dikenali"); + break; + } +} + + + diff --git a/week3_answer/addreas_book/mini_database/contact.db b/week3_answer/addreas_book/mini_database/contact.db new file mode 100644 index 00000000..e69de29b diff --git a/week3_answer/addreas_book/mini_database/groupContract.db b/week3_answer/addreas_book/mini_database/groupContract.db new file mode 100644 index 00000000..e69de29b diff --git a/week3_answer/addreas_book/mini_database/groups.db b/week3_answer/addreas_book/mini_database/groups.db new file mode 100644 index 00000000..e69de29b diff --git a/week3_answer/addreas_book/view.js b/week3_answer/addreas_book/view.js new file mode 100644 index 00000000..6df6a816 --- /dev/null +++ b/week3_answer/addreas_book/view.js @@ -0,0 +1,31 @@ +class View { + static errView(err) { + return "command failed to execute"; + } + + static sucessView() { + return "command was executed successfully"; + } + + static contactShow(rows) { + let n = rows.length; + console.log("------------"); + for (let i = 0; i < n; i++) { + let person = `${rows[i].id} - ${rows[i].name} : ${rows[i].phoneNumber} - ${rows[i].email}`; + console.log(person); + console.log("----------"); + } + return; + } + + static async showGroup(rows) { + let n = rows.length; + console.log("------------"); + for (let i = 0; i < n; i++) { + let group = `${rows[i].id} - ${rows[i].groupName}`; + console.log(group); + console.log("----------"); + } + return; + } +} diff --git a/week3_answer/design_database/chearsheet.db b/week3_answer/design_database/chearsheet.db new file mode 100644 index 00000000..d8851609 --- /dev/null +++ b/week3_answer/design_database/chearsheet.db @@ -0,0 +1,69 @@ + +CREATE TABLE Buku ( + ID_Buku INTEGER PRIMARY KEY AUTOINCREMENT, + Judul TEXT NOT NULL, + Penulis TEXT NOT NULL, + ISBN TEXT UNIQUE, + Tahun_Terbit INTEGER, + Kategori TEXT, + Jumlah_Stok INTEGER +); + +CREATE TABLE Anggota ( + ID_Anggota INTEGER PRIMARY KEY AUTOINCREMENT, + Nama TEXT NOT NULL, + Alamat TEXT, + No_Telepon TEXT, + Email TEXT UNIQUE, + Tanggal_Bergabung DATE +); + +CREATE TABLE Peminjaman ( + ID_Peminjaman INTEGER PRIMARY KEY AUTOINCREMENT, + ID_Buku INTEGER, + ID_Anggota INTEGER, + Tanggal_Pinjam DATE, + Tanggal_Kembali DATE, + Status TEXT, + FOREIGN KEY (ID_Buku) REFERENCES Buku(ID_Buku), + FOREIGN KEY (ID_Anggota) REFERENCES Anggota(ID_Anggota) +); + +INSERT INTO Buku (Judul, Penulis, ISBN, Tahun_Terbit, Kategori, Jumlah_Stok) +VALUES +('Clean Code', 'Robert C. Martin', '9780132350884', 2008, 'Programming', 10), +('Atomic Habits', 'James Clear', '9780735211292', 2018, 'Self Development', 5), +('Node.js Dasar', 'Ryo', '111222333', 2025, 'Programming', 7); + +INSERT INTO Anggota (Nama, Alamat, No_Telepon, Email, Tanggal_Bergabung) +VALUES +('Ryo', 'Jakarta', '08123', 'ryo@mail.com', '2025-01-01'), +('Budi', 'Bandung', '08222', 'budi@mail.com', '2025-01-10'); + +INSERT INTO Peminjaman (ID_Buku, ID_Anggota, Tanggal_Pinjam, Status) +VALUES +(1, 1, DATE('now'), 'Dipinjam'); + +CREATE INDEX idx_buku_judul ON Buku(Judul); +CREATE INDEX idx_anggota_nama ON Anggota(Nama); +CREATE INDEX idx_peminjaman_tanggal ON Peminjaman(Tanggal_Pinjam); + +SELECT * FROM Buku; +SELECT * FROM Anggota; + +SELECT Anggota.Nama, Buku.Judul, Peminjaman.Tanggal_Pinjam, Peminjaman.Status +FROM Peminjaman +JOIN Anggota ON Peminjaman.ID_Anggota = Anggota.ID_Anggota +JOIN Buku ON Peminjaman.ID_Buku = Buku.ID_Buku; + +UPDATE Buku SET Jumlah_Stok = Jumlah_Stok - 1 WHERE ID_Buku = 1; + +UPDATE Peminjaman +SET Tanggal_Kembali = DATE('now'), Status = 'Dikembalikan' +WHERE ID_Peminjaman = 1; + +SELECT * FROM Buku WHERE Kategori = 'Programming'; + +SELECT * FROM Buku ORDER BY Tahun_Terbit DESC LIMIT 2; + +SELECT COUNT(*) FROM Buku; diff --git a/week3_answer/design_database/cheatsheet.md b/week3_answer/design_database/cheatsheet.md new file mode 100644 index 00000000..967bf6c9 --- /dev/null +++ b/week3_answer/design_database/cheatsheet.md @@ -0,0 +1,70 @@ +-- ============================ +-- TABEL WORKER (KARYAWAN) +-- ============================ +CREATE TABLE worker ( + worker_id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + role VARCHAR(50) NOT NULL, -- contoh: Manager, Programmer, QA + daily_rate INT NOT NULL, -- gaji per hari + is_manager BOOLEAN NOT NULL DEFAULT FALSE +); + +-- ============================ +-- TABEL PROJECT +-- ============================ +CREATE TABLE project ( + project_id SERIAL PRIMARY KEY, + project_name VARCHAR(150) NOT NULL, + manager_id INT NOT NULL REFERENCES worker(worker_id), + budget INT NOT NULL, -- dana yang disediakan + revenue INT DEFAULT 0, -- pendapatan hasil project + status VARCHAR(20) NOT NULL -- contoh: ongoing, done, cancelled +); + +-- ============================ +-- TABEL PROJECT_MEMBER +-- (N:N RELATION) +-- ============================ +CREATE TABLE project_member ( + project_id INT REFERENCES project(project_id), + worker_id INT REFERENCES worker(worker_id), + role_in_project VARCHAR(100), + PRIMARY KEY (project_id, worker_id) +); + +-- ============================ +-- TABEL TASK +-- ============================ +CREATE TABLE task ( + task_id SERIAL PRIMARY KEY, + project_id INT REFERENCES project(project_id), + worker_id INT REFERENCES worker(worker_id), + title VARCHAR(200) NOT NULL, + description TEXT, + status VARCHAR(20) NOT NULL, -- todo / doing / done + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- ============================ +-- TABEL ATTENDANCE (ABSENSI) +-- ============================ +CREATE TABLE attendance ( + attendance_id SERIAL PRIMARY KEY, + worker_id INT REFERENCES worker(worker_id), + work_date DATE NOT NULL, + hours_worked INT NOT NULL, + status VARCHAR(20) NOT NULL -- present / sick / off +); + +-- ============================ +-- TABEL PROJECT_COST +-- (pengeluaran untuk project) +-- ============================ +CREATE TABLE project_cost ( + cost_id SERIAL PRIMARY KEY, + project_id INT REFERENCES project(project_id), + worker_id INT REFERENCES worker(worker_id), + work_date DATE NOT NULL, + hours_paid INT NOT NULL, + cost_amount INT NOT NULL -- daily_rate * jam kerja atau fixed +); diff --git a/week3_answer/warehouseDB_Project/massage.md b/week3_answer/warehouseDB_Project/massage.md new file mode 100644 index 00000000..648cf957 --- /dev/null +++ b/week3_answer/warehouseDB_Project/massage.md @@ -0,0 +1,37 @@ +# How to Run the SQL Project + +This guide explains how to run the `warehouse.sql` file using SQLite on Windows. + +## Requirements +- Windows PC +- SQLite installed at: `C:\sqlite` +- The SQL file is located at: + `C:\Week3-Backend-MVC-Database-By-Ryo\week3_answer\warehouseDB_Project\warehouse.sql` + +## How to Run + +1. **Open Command Prompt (CMD)** +Press **Windows + R**, type: +and press **Enter** + +2. **Navigate to SQLite Folder** +cd C:\sqlite + + +3. **Launch SQLite** +sqlite3 + +4. **Run the SQL File** +At the `sqlite>` prompt, type: +.read "C:\Week3-Backend-MVC-Database-By-Ryo\week3_answer\warehouseDB_Project\warehouse.sql" + +5. **(Optional) Make Output Display as a Table** +.headers on +.mode column + +6. **Check the Data** +Try: +SELECT * FROM Products; + +7. **Exit SQLite** +.exit \ No newline at end of file diff --git a/week3_answer/warehouseDB_Project/warehouse.sql b/week3_answer/warehouseDB_Project/warehouse.sql new file mode 100644 index 00000000..6057878e --- /dev/null +++ b/week3_answer/warehouseDB_Project/warehouse.sql @@ -0,0 +1,101 @@ +CREATE TABLE Products ( + product_id INT PRIMARY KEY, + product_name VARCHAR(100), + category VARCHAR(100), + price DECIMAL(10,2) +); + +CREATE TABLE Inventory ( + inventory_id INT PRIMARY KEY, + product_id INT, + quantity INT, + location VARCHAR(100), + FOREIGN KEY (product_id) REFERENCES Products(product_id) +); + +CREATE TABLE Orders ( + order_id INT PRIMARY KEY, + customer_id INT, + order_date DATE +); + +CREATE TABLE OrderDetails ( + order_detail_id INT PRIMARY KEY, + order_id INT, + product_id INT, + quantity INT, + FOREIGN KEY (order_id) REFERENCES Orders(order_id), + FOREIGN KEY (product_id) REFERENCES Products(product_id) +); + +INSERT INTO Products VALUES +(1, 'Laptop', 'Elektronik', 999.99), +(2, 'Desk Chair', 'Perabot', 199.99), +(3, 'Printer', 'Elektronik', 299.99), +(4, 'Bookshelf', 'Perabot', 149.99); + +SELECT product_name, price +FROM Products +ORDER BY price DESC; + +INSERT INTO Inventory VALUES +(1, 1, 50, 'Warehouse A'), +(2, 2, 30, 'Warehouse B'), +(3, 3, 20, 'Warehouse A'), +(4, 4, 40, 'Warehouse B'); + +SELECT + p.product_name, + i.quantity, + i.location +FROM Products p +JOIN Inventory i + ON p.product_id = i.product_id; + +UPDATE Products +SET price = 1099.99 +WHERE product_name = 'Laptop'; + +SELECT + i.location, + SUM(i.quantity * p.price) AS total_value +FROM Inventory i +JOIN Products p + ON i.product_id = p.product_id +GROUP BY i.location; + +INSERT INTO Orders VALUES +(1, 101, '2024-08-12'), +(2, 102, '2024-08-13'); + +INSERT INTO OrderDetails VALUES +(1, 1, 1, 2), +(2, 1, 3, 1), +(3, 2, 2, 1), +(4, 2, 4, 2); + +SELECT + o.order_id, + o.order_date, + SUM(od.quantity * p.price) AS total_amount +FROM Orders o +JOIN OrderDetails od ON o.order_id = od.order_id +JOIN Products p ON od.product_id = p.product_id +GROUP BY o.order_id, o.order_date; + +SELECT p.product_id, p.product_name +FROM Products p +LEFT JOIN OrderDetails od ON p.product_id = od.product_id +WHERE od.product_id IS NULL; + +CREATE VIEW product_stock AS +SELECT + p.product_name, + i.quantity, + i.location +FROM Products p +JOIN Inventory i + ON p.product_id = i.product_id; + + + diff --git a/week3_answer/werehouseNSQL_Porject/inventory.json b/week3_answer/werehouseNSQL_Porject/inventory.json new file mode 100644 index 00000000..059bf8e9 --- /dev/null +++ b/week3_answer/werehouseNSQL_Porject/inventory.json @@ -0,0 +1,24 @@ +[{ + "_id": 1, + "product_id": 1, + "quantity": 50, + "location": "Gudang A" +}, +{ + "_id": 2, + "product_id": 2, + "quantity": 30, + "location": "Gudang B" +}, +{ + "_id": 3, + "product_id": 3, + "quantity": 20, + "location": "Gudang A" +}, +{ + "_id": 4, + "product_id": 4, + "quantity": 40, + "location": "Gudang B" +}] \ No newline at end of file diff --git a/week3_answer/werehouseNSQL_Porject/orders.json b/week3_answer/werehouseNSQL_Porject/orders.json new file mode 100644 index 00000000..d5279d71 --- /dev/null +++ b/week3_answer/werehouseNSQL_Porject/orders.json @@ -0,0 +1,34 @@ +[{ + "_id": 1, + "customer_id": 101, + "order_date": { + "$date": "2024-08-12T00:00:00.000Z" + }, + "order_details": [ + { + "product_id": 1, + "quantity": 2 + }, + { + "product_id": 3, + "quantity": 1 + } + ] +}, +{ + "_id": 2, + "customer_id": 102, + "order_date": { + "$date": "2024-08-13T00:00:00.000Z" + }, + "order_details": [ + { + "product_id": 2, + "quantity": 1 + }, + { + "product_id": 4, + "quantity": 2 + } + ] +}] \ No newline at end of file diff --git a/week3_answer/werehouseNSQL_Porject/products.json b/week3_answer/werehouseNSQL_Porject/products.json new file mode 100644 index 00000000..ff5ad97e --- /dev/null +++ b/week3_answer/werehouseNSQL_Porject/products.json @@ -0,0 +1,24 @@ +[{ + "_id": 1, + "product_name": "Laptop", + "category": "Elektronik", + "price": 1099.99 +}, +{ + "_id": 2, + "product_name": "Meja Kursi", + "category": "Perabot", + "price": 199.99 +}, +{ + "_id": 3, + "product_name": "Printer", + "category": "Elektronik", + "price": 299.99 +}, +{ + "_id": 4, + "product_name": "Rak Buku", + "category": "Perabot", + "price": 149.99 +}] \ No newline at end of file diff --git a/week3_answer/werehouseNSQL_Porject/queries.md b/week3_answer/werehouseNSQL_Porject/queries.md new file mode 100644 index 00000000..30e4b704 --- /dev/null +++ b/week3_answer/werehouseNSQL_Porject/queries.md @@ -0,0 +1,129 @@ +use werhouse + +db.products.insertMany([ + { _id: 1, product_name: "Laptop", category: "Elektronik", price: 999.99 }, + { _id: 2, product_name: "Meja Kursi", category: "Perabot", price: 199.99 }, + { _id: 3, product_name: "Printer", category: "Elektronik", price: 299.99 }, + { _id: 4, product_name: "Rak Buku", category: "Perabot", price: 149.99 } +]) + +db.products.find( + {}, + { _id: 0, product_name: 1, price: 1 } +).sort({ price: 1 }) + +db.inventory.insertMany([ + { _id: 1, product_id: 1, quantity: 50, location: "Gudang A" }, + { _id: 2, product_id: 2, quantity: 30, location: "Gudang B" }, + { _id: 3, product_id: 3, quantity: 20, location: "Gudang A" }, + { _id: 4, product_id: 4, quantity: 40, location: "Gudang B" } +]) + +db.inventory.aggregate([ + { + $lookup: { + from: "products", + localField: "product_id", + foreignField: "_id", + as: "product" + } + }, + { $unwind: "$product" }, + { + $project: { + _id: 0, + product_name: "$product.product_name", + quantity: 1, + location: 1 + } + } +]) + +db.products.updateOne( + { product_name: "Laptop" }, + { $set: { price: 1099.99 } } +) + +db.inventory.aggregate([ + { + $lookup: { + from: "products", + localField: "product_id", + foreignField: "_id", + as: "product" + } + }, + { $unwind: "$product" }, + { + $group: { + _id: "$location", + total_value: { + $sum: { $multiply: ["$quantity", "$product.price"] } + } + } + } +]) + +db.orders.insertMany([ + { + _id: 1, + customer_id: 101, + order_date: ISODate("2024-08-12"), + order_details: [ + { product_id: 1, quantity: 2 }, + { product_id: 3, quantity: 1 } + ] + }, + { + _id: 2, + customer_id: 102, + order_date: ISODate("2024-08-13"), + order_details: [ + { product_id: 2, quantity: 1 }, + { product_id: 4, quantity: 2 } + ] + } +]) + +db.orders.aggregate([ + { $unwind: "$order_details" }, + { + $lookup: { + from: "products", + localField: "order_details.product_id", + foreignField: "_id", + as: "product" + } + }, + { $unwind: "$product" }, + { + $group: { + _id: "$_id", + order_date: { $first: "$order_date" }, + total_amount: { + $sum: { $multiply: ["$order_details.quantity", "$product.price"] } + } + } + }, + { + $project: { + _id: 0, + order_id: "$_id", + order_date: 1, + total_amount: 1 + } + } +]) + +db.products.aggregate([ + { + $lookup: { + from: "orders", + localField: "_id", + foreignField: "order_details.product_id", + as: "ordered" + } + }, + { $match: { ordered: { $size: 0 } } }, + { $project: { _id: 1, product_name: 1 } } +])