এখন পর্যন্ত আমরা সব ডেটা JSON ফাইলে রেখেছি। এটা শেখার জন্য দারুণ ছিল, কিন্তু বাস্তব অ্যাপ্লিকেশনে JSON ফাইল ম্যানুয়ালি পড়া-লেখা ধীরগতির এবং জটিল। আজ আমরা SQLite ডাটাবেস ব্যবহার করা শিখবো—যেটা বাস্তব জগতের অ্যাপ্লিকেশনের জন্য স্ট্যান্ডার্ড, হালকা, এবং দ্রুত।
JSON vs SQLite — কেন SQLite শিখব?
| ব্যাপার | JSON | SQLite |
|---|---|---|
| গতি | ধীর (পুরো ফাইল পড়তে হয়) | দ্রুত (SQL ইঞ্জিন) |
| সার্চ | JavaScript দিয়ে ম্যানুয়ালি | SQL কোয়েরি — SELECT, WHERE |
| একসাথে অনেক কাজ | কঠিন, ডেটা নষ্ট হতে পারে | Transaction সাপোর্ট |
| প্রফেশনাল | শেখার জন্য ভালো | ইন্ডাস্ট্রি স্ট্যান্ডার্ড |
| মোবাইলে | ঠিক আছে | একেবারে পারফেক্ট |
ঐচ্ছিক: npm ও sql.js ইন্সটল
Note: Termux-এর কিছু পুরোনো Node.js ভার্সনে country-code সমস্যার জন্য sql.js ইন্সটল নাও হতে পারে। সেক্ষেত্রে আমরা better-sqlite3 ইউজ করব।
# প্রথমে sql.js ট্রাই করি:
npm install sql.js
# যদি কাজ না করে, তাহলে:
npm install better-sqlite3
ধাপ ১: database.js মডিউল তৈরি করো
cd ~/shop-api
micro database.js
নিচের সম্পূর্ণ কোড পেস্ট করো—এটি ডাটাবেস ইন্সটল, টেবিল তৈরি ও সেভ করার সব কাজ করবে:
const initSqlJs = require('sql.js');
const fs = require('fs');
const path = require('path');
const dbPath = path.join(__dirname, 'shop.db');
async function setupDatabase() {
const SQL = await initSqlJs();
let db;
if (fs.existsSync(dbPath)) {
db = new SQL.Database(fs.readFileSync(dbPath));
} else {
db = new SQL.Database();
}
// পণ্যের টেবিল
db.run(`CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL,
stock INTEGER DEFAULT 0,
unit TEXT DEFAULT 'পিস'
)`);
// ইউজার টেবিল
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
role TEXT DEFAULT 'admin'
)`);
// সেলস টেবিল
db.run(`CREATE TABLE IF NOT EXISTS sales (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
total REAL NOT NULL,
payment_method TEXT DEFAULT 'cash'
)`);
// সেলস আইটেম টেবিল
db.run(`CREATE TABLE IF NOT EXISTS sale_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sale_id INTEGER,
product_id INTEGER,
product_name TEXT,
price REAL,
qty INTEGER,
subtotal REAL
)`);
// একেবারে প্রথমবারের জন্য ডিফল্ট ইউজার
const users = db.exec('SELECT COUNT(*) as count FROM users');
if (users[0].values[0][0] === 0) {
db.run("INSERT INTO users (username, password, role) VALUES ('admin', 'admin123', 'admin')");
}
return db;
}
function saveDatabase(db) {
const data = db.export();
const buffer = Buffer.from(data);
fs.writeFileSync(dbPath, buffer);
}
module.exports = { setupDatabase, saveDatabase };
ধাপ ২: server.js আপডেট করো (SQLite ভার্সন)
cd ~/shop-api
micro server.js
সবার উপরে require গুলোতে এটি যোগ করো:
const { setupDatabase, saveDatabase } = require('./database');
let db;
এখন app.listen-এর জায়গায় এটি দাও:
setupDatabase().then(database => {
db = database;
console.log('✅ SQLite ডাটাবেস প্রস্তুত');
app.listen(PORT, () => {
console.log(`✅ সার্ভার চালু হয়েছে: http://localhost:${PORT}`);
});
});
এখন GET ও POST রাউট এভাবে বদলাও:
// GET /products (SQLite)
app.get('/products', (req, res) => {
const results = db.exec('SELECT * FROM products ORDER BY id');
if (!results.length) return res.json([]);
const cols = results[0].columns;
const rows = results[0].values.map(row => {
const obj = {};
cols.forEach((c, i) => { obj[c] = row[i]; });
return obj;
});
res.json(rows);
});
// POST /products (SQLite, প্রটেক্টেড)
app.post('/products', authMiddleware, (req, res) => {
const { name, price, stock, unit } = req.body;
if (!name || !price) {
return res.status(400).json({ message: 'নাম ও মূল্য আবশ্যক' });
}
db.run('INSERT INTO products (name, price, stock, unit) VALUES (?, ?, ?, ?)',
[name, price, stock || 0, unit || 'পিস']);
saveDatabase(db);
res.status(201).json({ message: 'প্রোডাক্ট যোগ হয়েছে' });
});
SQL বেসিক কমান্ড — তুমি এখন যা পারবে
| কাজ | SQL কোয়েরি | সহজ ভাষায় |
|---|---|---|
| সব প্রোডাক্ট | SELECT * FROM products | "সব জিনিস দাও" |
| নির্দিষ্ট প্রোডাক্ট | SELECT * FROM products WHERE id = 1 | "শুধু ১ নম্বরটা দাও" |
| নতুন যোগ | INSERT INTO products (name, price) VALUES ('a', 10) | "এটা রাখো" |
| আপডেট | UPDATE products SET price = 20 WHERE id = 1 | "দাম বদলাও" |
| ডিলিট | DELETE FROM products WHERE id = 1 | "এটা সরাও" |
| গণনা | SELECT COUNT(*) FROM products | "কয়টা জিনিস আছে?" |
আজ তুমি কী শিখলে
- SQLite — ফাইল-ভিত্তিক, হালকা ও দ্রুত ডাটাবেস
- sql.js — জাভাস্ক্রিপ্টে SQLite চালানোর প্যাকেজ
- db.run() — INSERT, UPDATE, DELETE চালানো
- db.exec() — SELECT চালানো এবং ডেটা পড়া
- saveDatabase() — ডাটাবেস ফাইলে স্থায়ীভাবে সেভ
- SQL বেসিক — SELECT, INSERT, UPDATE, DELETE, WHERE, COUNT
- টেবিল রিলেশন — sales ও sale_items টেবিলের ধারণা
শেষ পর্ব পর্ব ১৩: রিভিশন ও মাইন্ড ম্যাপ — যেখানে পুরো সিরিজের একটি সংক্ষিপ্ত রিভিশন টেবিল ও মাইন্ড ম্যাপ দিয়ে আমরা শেষ করব। 🎉
So far we've stored all data in JSON files. Today we'll learn SQLite — a real database that's faster, more reliable, and used in real-world applications.
JSON vs SQLite
| Aspect | JSON | SQLite |
|---|---|---|
| Speed | Slow (reads whole file) | Fast (SQL engine) |
| Search | Manual JavaScript | SQL Queries |
| Professional | Good for learning | Industry Standard |
Step 1: Install sql.js or better-sqlite3
npm install sql.js
# or if that fails:
npm install better-sqlite3
Step 2: Create database.js module
const initSqlJs = require('sql.js');
// setupDatabase() and saveDatabase() functions
Step 3: Update server.js for SQLite
const { setupDatabase, saveDatabase } = require('./database');
// Use db.run() for INSERT, UPDATE, DELETE
// Use db.exec() for SELECT
Basic SQL Commands
| Task | SQL Query |
|---|---|
| All products | SELECT * FROM products |
| Insert | INSERT INTO products (name, price) VALUES ('a', 10) |
| Update | UPDATE products SET price = 20 WHERE id = 1 |
| Delete | DELETE FROM products WHERE id = 1 |
Final episode Part 13: Revision & Mind Map — where we'll summarize the entire series with a visual revision table and mind map. 🎉
💬 মন্তব্য / Comments