Mundarija (26)
- Bu darsda
- 1. Nega bu kerak?
- 2. Tagged template ichidan
- 2.1 O'zimizning sql tegi
- 2.2 postgres.js'ning haqiqiy so'rovi
- 3. Dinamik qismlar: sql(…)
- 4. Tranzaksiya va xatolar
- 4.1 sql.begin
- 4.2 Xato obyekti
- 5. sql.unsafe: eshik ochiq qoladi
- 6. Tezlik: kanon o'lchovi
- 6.1 Raqamlar
- 6.2 Nega: pipelining
- 6.3 Raqamni to'g'ri o'qish
- 7. Boshqa drayverlar xaritasi
- 7.1 Jadval
- 7.2 node:sqlite — o'zimiz sinab ko'ramiz
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): moslashtiring
- 2-mashq (o'rta): tegni kengaytiring
- 3-mashq (qiyin): node:sqlite da kichik repository
- 10. Node qadami
- 11. Real ishda
- Xulosa
- Manbalar
postgres.js va boshqa driverlar: tagged template, pipelining va tanlov
Qisqacha: postgres.js — Postgres uchun ikkinchi mashhur Node drayveri. Unda so'rov tagged template bilan yoziladi:
sql`SELECT … WHERE id = ${id}`—${id}matnga yopishmaydi, avtomatik$1parametr bo'ladi. Kanon o'lchovi: ketma-ket so'rovlardapgbilan deyarli teng (2 667 va 2 822 ms). Lekin 2 000 ta parallel so'rovda postgres.js 40 ms,pg— 685 ms: postgres.js bitta ulanishda so'rovlarni kutmasdan ketma-ket jo'natadi (pipelining). Uningsql.unsafeeshigi esa injection'ni qaytaradi.
Bu darsda
- postgres.js'da so'rov, dinamik nom, obyekt va ro'yxat qo'yishni yozasiz.
- Tagged template qanday qilib parametrga aylanishini o'zingiz kichik
sqlfunksiyasi bilan ko'rsatasiz. sql.beginbilan tranzaksiya vasql.unsafexavfini tushuntirasiz.- Kanon o'lchovi bo'yicha
pgva postgres.js farqini (pipelining) izohlaysiz. - Boshqa ma'lumotlar bazalari drayverlari xaritasini bilasiz: mysql2, better-sqlite3,
node:sqlite,mongodb, Bunsql.
Oldin bilishingiz kerak: Parametrli so'rovlar va SQL injection, Tagged template literals, node-postgres (pg) asoslari.
1. Nega bu kerak?
Oldingi darsda qoida o'rnatdik: qiymat — faqat $1, $2 bilan. Lekin qo'lda raqamlash zerikarli va xatoga moyil: o'nta filtrda $7 ni $8 bilan almashtirib yuborish oson. Dinamik WHERE uchun shartlar va qiymatlar massivlarini yig'dik — ishlaydi, lekin kod ko'payadi.
JavaScript'da shu muammoni yechadigan sintaksis bor — tagged template (Tagged template literals). Teg funksiyasi shablonning matn bo'laklarini va ${} qiymatlarini alohida oladi. Demak u qiymatlarni matnga yopishtirmay, parametrga aylantira oladi. postgres.js (muallifi Rasmus Porsager, shuning uchun "porsager/postgres" deb ham ataladi) aynan shu g'oyaga qurilgan.
O'xshatish: anketa. pg da siz anketani o'zingiz chizasiz: "1-maydon: ___, 2-maydon: ___", javoblarni alohida qog'ozda tartib bilan yozasiz. postgres.js da gapni odatdagidek yozasiz — "Ism: ${ism}" — u esa o'zi maydonlarni ajratib, anketani to'ldiradi.
Bu dars ekotizim darsi: kursning asosiy drayveri pg bo'lib qoladi (25-qism API'si va 27-qismdagi vositalar shunga tayanadi). postgres.js'ni bilish esa boshqa loyihalarda uni ko'rganda o'qiy olish va tanlov qila olish uchun.
2. Tagged template ichidan
2.1 O'zimizning sql tegi
postgres.js'ning siri — oddiy JavaScript. Keling, eng kichik variantini o'zimiz yozamiz. U bazaga ulanmaydi, faqat { text, values } qaytaradi — pg qabul qiladigan shakl:
function sql(qismlar, ...qiymatlar) {
const text = qismlar.reduce(
(natija, qism, i) => natija + "$" + i + qism,
);
return { text, values: qiymatlar };
}
const egasi = 1;
const soz = "' OR 1=1 --";
const s = sql`SELECT id FROM vazifalar
WHERE egasi_id = ${egasi} AND matn ILIKE ${"%" + soz + "%"}`;
console.log(s.text);
console.log(s.values);Konsolda:
SELECT id FROM vazifalar
WHERE egasi_id = $1 AND matn ILIKE $2
[ 1, "%' OR 1=1 --%" ]qismlar — ${} lar orasidagi matnlar (bu yerda 3 ta), qiymatlar — ${} ichidagilar (2 ta). reduce boshlang'ich qiymatsiz: birinchi qism bilan boshlanadi, keyin har qadamda $i va keyingi qismni qo'shadi. Hujum matni values da qoldi — SQL'da emas. Yozuv "yopishtirishga" o'xshaydi, lekin aslida parametr.
Diqqat: Teg oldidagi nom muhim.
sql`… ${x}`— xavfsiz (teg funksiyasi chaqiriladi).`… ${x}`(tegsiz) — oddiy satr,xyopishadi. Bitta so'z farqi — xavfsizlik va injection farqi. Kod review'da shu so'zga qarang.
2.2 postgres.js'ning haqiqiy so'rovi
O'rnatish (kanon versiyasi): npm i postgres@3.4.9.
import postgres from "postgres";
const sql = postgres(process.env.DATABASE_URL, { max: 5 });
const egasi = 1;
const soz = "' OR 1=1 --";
const r = await sql`
SELECT id, matn FROM vazifalar
WHERE egasi_id = ${egasi} AND matn ILIKE ${"%" + soz + "%"}`;
console.log(
"tagged template, injection urinishi:",
r.length, "qator; count:", r.count,
);Kanon chiqishi (natijalar/tajriba/t43-postgres-js.txt, postgres 3.4.9, PostgreSQL 18.6):
tagged template, injection urinishi: 0 qator; count: 0Farqlarga qarang: postgres(url, sozlamalar) — bitta funksiya hovuzni yaratadi va sql tegini qaytaradi. Natija — rows xususiyatli obyekt emas, to'g'ridan-to'g'ri massiv (r.length); qo'shimcha ma'lumot massivning xususiyatlarida (r.count). client.connect() va release() yo'q — hovuz ichkarida.
Tekshirib ko'ring:
sql`SELECT * FROM ${jadval}`—jadval = "vazifalar". Bu ishlaydimi?
Javob
Yo'q. ${jadval} parametrga ($1) aylanadi, jadval nomi esa parametr bo'la olmaydi — pg dagi kabi sintaksis xatosi. Nom uchun postgres.js'da alohida yozuv bor: ${sql(jadval)} — keyingi bo'limda.
3. Dinamik qismlar: sql(…)
postgres.js'da sql ni oddiy funksiya kabi ham chaqirish mumkin — u qiymatni turiga qarab xavfsiz SQL bo'lagiga aylantiradi:
| Yozuv | Nima bo'ladi | pg dagi o'xshashi |
|---|---|---|
${sql("matn")} |
identifikator "matn" |
%I, oq ro'yxat |
${sql([2, 3])} |
ro'yxat ($1, $2) |
= ANY($1) |
${sql({ egasi_id: 8, matn: "…" })} |
INSERT ustunlari va qiymatlari | qo'lda $1, $2 |
const ustun = "matn";
const r2 = await sql`
SELECT ${sql(ustun)} FROM vazifalar
WHERE id IN ${sql([2, 3])} ORDER BY id`;
console.log("sql(ustun):", r2.map((x) => x.matn));Kanon chiqishi:
sql(ustun): [
"Postgres'ni Docker'da ko'tarish #o'qish #docker",
'Mijozga taklifnoma yuborish #ish'
]sql(ustun) — ustun nomi qo'shtirnoq ichida escape qilinadi (%I kabi). Lekin bu oq ro'yxatning o'rnini bosmaydi: escape qilingan nom ham foydalanuvchi tanlagan istalgan ustun bo'lishi mumkin (masalan maxfiy ustun). Foydalanuvchi tanlovi bo'lsa — avval oq ro'yxat, keyin sql(nom).
4. Tranzaksiya va xatolar
4.1 sql.begin
await sql.begin(async (tx) => {
const [yangi] = await tx`
INSERT INTO vazifalar
${tx({ egasi_id: 8, matn: "postgres.js orqali" })}
RETURNING id, versiya`;
console.log("sql.begin ichida INSERT:", yangi);
throw new Error("ataylab — ROLLBACK");
}).catch((e) => console.log("sql.begin:", e.message));Kanon chiqishi:
sql.begin ichida INSERT: { id: '51', versiya: 1 }
sql.begin: ataylab — ROLLBACK
rollback'dan keyin: 0sql.begin(fn) — bitta ulanishni oladi, BEGIN qiladi, fn ni chaqiradi. fn muvaffaqiyatli tugasa — COMMIT, xato tashlasa — ROLLBACK va xato tashqariga chiqadi. Ichkarida faqat tx tegidan foydalaning — tashqi sql boshqa ulanishga tushadi va tranzaksiyadan tashqarida bajariladi. pg da bu yordamchini o'zimiz yozamiz (Tranzaksiya asoslari).
Yana bir narsa: id: '51' — string. postgres.js ham bigint ni string qiladi, xuddi pg dek. Kanon turlarni solishtirdi:
turlar: {
id: 'string',
matn: 'string',
bajarildi: 'boolean',
yaratilgan_vaqt: 'Date',
narx: 'string',
jami: 'string'
} | qiymat: 1 13 12.50bigint, numeric, count — string; timestamptz — Date. node-postgres asoslari darsidagi qoidalar bu yerda ham amal qiladi.
4.2 Xato obyekti
xato: 23514 vazifalar_matn_check PostgresErrorXato klassi — PostgresError, kod — o'sha SQLSTATE 23514. Bitta farq: cheklov nomi constraint_name maydonida (pg da — constraint). Drayverni almashtirsangiz, xato qayta ishlovchi kod ham o'zgaradi.
5. sql.unsafe: eshik ochiq qoladi
Ba'zan SQL matni butunlay dinamik (masalan migratsiya faylini o'qib bajarish). Buning uchun sql.unsafe(matn) bor — xom satr, hech qanday parametrsiz. Kanon buni "raqam" bilan sinadi:
const egasiId = "1 OR true"; // URL'dan kelgan "raqam"
const r = await sql.unsafe(
"SELECT count(*)::int AS n FROM vazifalar " +
"WHERE egasi_id = " + egasiId,
);Kanon chiqishi:
sql.unsafe: 48 (egasi 1 emas, hammasi!)Azizning 13 ta vazifasi o'rniga — hamma 48 ta. Oldingi darsdagi injection aynan qaytdi. Nomida "unsafe" (xavfli) so'zi bejiz emas: foydalanuvchidan kelgan har narsa uchun — faqat teg yoki sql.unsafe(matn, [qiymatlar]) ning ikkinchi argumenti (parametrlar).
6. Tezlik: kanon o'lchovi
6.1 Raqamlar
Kanon ikkala drayverda 2 000 ta oddiy SELECT … WHERE id = $1 bajardi, 5 marta, mediana (hovuz — 5 ulanish):
ketma-ket 2000: pg 2667 ms | postgres.js 2822 ms
parallel 2000 (5 ulanish): pg 685 ms | postgres.js 40 ms- pg, ketma-ket2 667 ms
- postgres.js, ketma-ket2 822 ms
- pg, parallel685 ms
- postgres.js, parallel40 ms
Manba: IlmHamroh kanon o'lchovi, 2026-10-24: Node 24.21.0, pg 8.23.1, postgres 3.4.9, PostgreSQL 18.6 (Docker, WSL2), Windows 11, i5-12500H
Grafikda ikki manzara. Ketma-ket (har so'rov oldingisini await bilan kutadi) — deyarli teng: har so'rov ~1.3 ms, bu vaqtning asosiy qismi — Node'dan Docker ichidagi Postgres'ga borib-kelish (tarmoq aylanishi). Drayver qanchalik tez bo'lmasin, aylanishni qisqartira olmaydi. Parallel — 17 baravar farq.
6.2 Nega: pipelining
pg da bitta ulanish bir paytda bitta so'rovni "havoda" ushlaydi: so'rov ketdi → javob keldi → keyingisi ketadi. 5 ulanish — bir vaqtda 5 ta so'rov. postgres.js esa bitta ulanishga ko'p so'rovni javobini kutmasdan ketma-ket yozadi: Postgres ularni navbat bilan bajarib, javoblarni o'sha tartibda qaytaradi. Bu pipelining (quvurlash).
sequenceDiagram
participant N as Node
participant P as Postgres
Note over N,P: pg: kutib yuboradi
N->>P: so'rov 1
P-->>N: javob 1
N->>P: so'rov 2
P-->>N: javob 2
Note over N,P: postgres.js: pipelining
N->>P: so'rov 1
N->>P: so'rov 2
N->>P: so'rov 3
P-->>N: javob 1, 2, 3Diagrammaga qarang: pastki qismda bo'sh kutish yo'q — tarmoq aylanishi uchta so'rovga bitta. O'xshatish: do'konga borib, bitta mahsulot olib qaytish va yana borish (pg) — ro'yxat bilan bir marta borish (pipelining).
6.3 Raqamni to'g'ri o'qish
17 baravar — "postgres.js har doim 17 baravar tez" degani emas:
- Kanon so'rovi juda yengil (indeks bo'yicha bitta qator) — vaqt deyarli faqat tarmoqqa ketadi. Og'ir so'rovda (JOIN, agregat) asosiy vaqt Postgres ichida va farq kamayadi.
- Ketma-ket ishlaydigan kodda (ko'p API handler'lari shunday: bitta so'rov, javob, keyingisi) farq yo'q.
- Pipelining tranzaksiya ichida va xato bo'lganda o'z qoidalariga ega — kutubxona buni ichkarida boshqaradi.
Kanon xulosasi: drayver tanlovi ko'pincha tezlik emas, API qulayligi va ekotizim (25–30-qismlardagi vositalar pg ni kutadi) masalasi.
Tekshirib ko'ring: API handler'ida uchta mustaqil so'rov (
vazifalar,teglar,izohlar_soni) ketma-ketawaitbilan bajarilyapti. Drayverni postgres.js'ga almashtirsangiz tezlashadimi?
Javob
Deyarli yo'q — ketma-ket await har javobni kutadi, pipelining uchun "havoda" bir nechta so'rov bo'lishi kerak. Avval kodni o'zgartiring: Promise.all([…]) bilan uchtasini birga yuboring. Shunda pg ham uchta ulanishda parallel bajaradi, postgres.js esa bitta ulanishda quvurlaydi.
7. Boshqa drayverlar xaritasi
7.1 Jadval
Bir xil g'oya (ulanish, parametr, natija) boshqa bazalarda boshqa paketlar bilan. Quyidagilar kanonda sinalmagan — 2026-10-24 dagi rasmiy hujjat bo'yicha:
| Drayver | Baza | Parametr | Eslatma |
|---|---|---|---|
mysql2 |
MySQL / MariaDB | ? |
execute() — prepared statement; MySQL va MariaDB |
better-sqlite3 |
SQLite (fayl) | ?, @nom |
sinxron API; SQLite |
node:sqlite |
SQLite | ?, :nom |
Node'ga o'rnatilgan, paket shart emas |
mongodb |
MongoDB | SQL yo'q — obyekt filtr | 27-qismda |
Bun sql |
Postgres, MySQL, SQLite | tagged template | faqat Bun runtime'da |
Ikkita umumiy saboq. Birinchisi: parametr belgisi bazaga qarab o'zgaradi ($1 faqat Postgres'da), lekin "qiymat — alohida" qoidasi hamma joyda bir xil. Ikkinchisi: Bun sql ham postgres.js'dagi tagged template g'oyasini oldi va unda ham sql.unsafe bor — hujjati "foydalanuvchi kiritganini escape qilmaydi" deb ogohlantiradi.
7.2 node:sqlite — o'zimiz sinab ko'ramiz
Ro'yxatdagi bittasini shu yerda tekshirish mumkin: node:sqlite Node'ning o'zida bor (Node 24 hujjatida barqarorlik darajasi — "1.2 Release candidate", bayroqsiz). Baza — xotirada (:memory:), server ham, Docker ham kerak emas. Bu blok faqat Node'da ishlaydi — o'z terminalingizda node fayl.mjs:
import { DatabaseSync } from "node:sqlite";
const db = new DatabaseSync(":memory:");
db.exec(`CREATE TABLE vazifalar (
id INTEGER PRIMARY KEY,
matn TEXT NOT NULL
) STRICT`);
const qosh = db.prepare(
"INSERT INTO vazifalar (matn) VALUES (?) RETURNING id",
);
console.log(qosh.get("Bozordan meva olish #bozor").id);
console.log(qosh.get("' OR 1=1 --").id);
const qidir = db.prepare(
"SELECT id, matn FROM vazifalar WHERE matn LIKE ?",
);
console.log(qidir.all("%bozor%").map((q) => q.matn));
console.log(typeof qidir.all("%")[0].id);
db.close();Konsolda:
1
2
[ "Bozordan meva olish #bozor" ]
numberUchta farqqa qarang: ? — parametr belgisi; hamma metod sinxron (await yo'q — SQLite diskdagi fayl, tarmoq yo'q); id — number (SQLite butun soni 64 bit, lekin node:sqlite sukut bo'yicha number beradi). Hujum matni ' OR 1=1 -- oddiy vazifa bo'lib saqlandi — parametr bu yerda ham himoya qildi.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| Injection, garchi "postgres.js xavfsiz" | tegsiz satr yoki sql.unsafe |
faqat sql`…` |
sql.begin ichidagi so'rov tranzaksiyaga kirmadi |
ichkarida tashqi sql ishlatildi |
faqat tx |
r.rows is undefined |
postgres.js natijasi — massivning o'zi | r[0], r.length |
e.constraint — undefined |
postgres.js'da constraint_name |
drayverga mos maydon |
| Ustun nomi escape qilindi, lekin maxfiy ustun ochildi | sql(nom) oq ro'yxat emas |
avval oq ro'yxat |
9. Mashqlar
Mashqlar kurs/mashqlar/26/43-postgres-js/ da.
1-mashq (oson): moslashtiring
- postgres.js'da ustun nomini xavfsiz qo'yish —
${sql()}(o'zgaruvchi nominombo'lsin) - postgres.js tranzaksiyasi —
sql. - Xom, parametrsiz SQL eshigi —
sql. - MySQL'da parametr belgisi —
- 2 000 parallel so'rovda kanon: postgres.js ms
Yechim
- nom —
sql(nom)identifikatorni escape qiladi (oq ro'yxatdan keyin). - begin — muvaffaqiyatda COMMIT, xatoda ROLLBACK.
- unsafe — foydalanuvchi qiymati bilan hech qachon.
- ? —
mysql2, SQLite ham; Postgres —$1. - 40 — pipelining tufayli;
pg— 685 ms.
2-mashq (o'rta): tegni kengaytiring
«O'zimizning sql tegi» bo'limidagi funksiyani o'zgartiring: agar qiymat massiv bo'lsa, u bitta parametr bo'lib qolsin, lekin SQL'da ANY(…) ga o'ralsin. Ya'ni sql`SELECT id FROM vazifalar WHERE id = ${[2, 5]}` → text: … WHERE id = ANY($1), values: [[2, 5]]. Oddiy qiymat — avvalgidek.
Yechim
function sql(qismlar, ...qiymatlar) {
const text = qismlar.reduce((natija, qism, i) => {
const qiymat = qiymatlar[i - 1];
const joy = Array.isArray(qiymat) ? `ANY($${i})` : `$${i}`;
return natija + joy + qism;
});
return { text, values: qiymatlar };
}
const s = sql`SELECT id FROM vazifalar
WHERE id = ${[2, 5]} AND egasi_id = ${1}`;
console.log(s.text);
console.log(s.values);Konsolda:
SELECT id FROM vazifalar
WHERE id = ANY($1) AND egasi_id = $2
[ [ 2, 5 ], 1 ]reduce da i — keyingi qismning raqami, unga mos qiymat — qiymatlar[i - 1]. Massiv ham bitta parametr bo'lib qoldi — matnga hech narsa yopishmadi. postgres.js'ning sql([…]) yozuvi shunga o'xshash ishni, lekin IN ($1, $2) shaklida qiladi.
3-mashq (qiyin): node:sqlite da kichik repository
node:sqlite bilan xotiradagi bazada vazifalar (id, matn, bajarildi — INTEGER, 0/1) jadvalini yarating. Uch funksiya yozing: qosh(matn) → yangi id; belgila(id) → o'zgargan qatorlar soni (run() natijasidagi changes); royxat() → { id, matn, bajarildi: boolean } massivi. Ikki vazifa qo'shing, birinchisini belgilang, mavjud bo'lmagan 99 ni belgilashga urining va ro'yxatni chiqaring.
Yechim
import { DatabaseSync } from "node:sqlite";
const db = new DatabaseSync(":memory:");
db.exec(`CREATE TABLE vazifalar (
id INTEGER PRIMARY KEY,
matn TEXT NOT NULL,
bajarildi INTEGER NOT NULL DEFAULT 0
) STRICT`);
const qoshSorov = db.prepare(
"INSERT INTO vazifalar (matn) VALUES (?) RETURNING id",
);
const belgilaSorov = db.prepare(
"UPDATE vazifalar SET bajarildi = 1 WHERE id = ?",
);
const royxatSorov = db.prepare(
"SELECT id, matn, bajarildi FROM vazifalar ORDER BY id",
);
const qosh = (matn) => qoshSorov.get(matn).id;
const belgila = (id) => belgilaSorov.run(id).changes;
const royxat = () =>
royxatSorov.all().map((q) => ({
id: q.id,
matn: q.matn,
bajarildi: q.bajarildi === 1,
}));
const birinchi = qosh("Onamga dori olib borish #oila");
qosh("Elektr to'lovini Click orqali qilish #to'lov");
console.log("belgilandi:", belgila(birinchi));
console.log("99:", belgila(99));
console.log(royxat());
db.close();Konsolda:
belgilandi: 1
99: 0
[
{ id: 1, matn: "Onamga dori olib borish #oila", bajarildi: true },
{
id: 2,
matn: "Elektr to'lovini Click orqali qilish #to'lov",
bajarildi: false
}
]changes: 0 — pg dagi rowCount: 0 ning o'xshashi: API'da 404. SQLite'da boolean tur yo'q — 0/1 ni o'zimiz boolean ga o'girdik (Postgres'da pg buni o'zi qiladi). Repository naqshi — "SQL faqat shu funksiyalar ichida" — 25-qism kanonidagi xotira repository'sining Postgres varianti ham xuddi shunday tuziladi.
10. Node qadami
Node qadami: kanon tajribasi, loyihaga kirmaydi. vazifalar-api pg da qoladi — postgres.js qo'shilmaydi. Sabablari:
PgOmborinode-postgres asoslari darsidapgbilan yozildi va 25-qism shartnoma testlaridan o'tdi. Drayverni almashtirish xato kodlarini ham o'zgartiradi (constraint→constraint_name) — foyda esa yo'q.- API handler'i so'rovlarni ketma-ket bajaradi: ro'yxat, keyin versiya. Bu holatda kanon o'lchovi ikki drayverni deyarli teng ko'rsatdi. Pipelining faqat parallel so'rovlarda yutadi.
- Keyingi qismlardagi vositalar (27-qismdagi ORM va migratsiya)
pgni kutadi.
O'quvchi qadami — tajriba: pg-tajriba papkasida npm i postgres@3.4.9 qiling va tezlik o'lchovini (2 000 ta SELECT, ketma-ket va Promise.all bilan) o'z mashinangizda takrorlang. Raqamlaringiz kanondan farq qilishi tabiiy (Docker, disk, protsessor) — nisbatga qarang: ketma-ketda teng, parallelda bir necha o'n baravar. Commit yo'q.
11. Real ishda
- postgres.js — Drizzle ORM (drayverlardan biri sifatida) va ko'plab yangi loyihalarda;
pg— eng ko'p yuklanadigan Postgres drayveri, NestJS/TypeORM, Prisma adapterlari, Kysely uni ishlatadi. - Tagged template g'oyasi keng tarqaldi: Drizzle'ning
sql`…`, Prisma'ning$queryRaw`…`, Bunsql, Vercel/Neon serverless drayverlari. Hammasida "xom" eshik ham bor — nomidaunsafe/raw. - SQLite — test, CLI va kichik ilovalar uchun;
node:sqlitepaketsiz ishlaydi (SQLite darsida chuqur). - Intervyuda: "postgres.js'da
${}nega injection emas?", "Pipelining nima?", "Qaysi drayverni tanlaysiz va nega?"
Xulosa
- postgres.js — tagged template drayveri:
${}avtomatik parametr; teg so'zi yo'qolsa — oddiy satr, injection. sql(nom),sql([…]),sql({…})— nom, ro'yxat, INSERT obyekti; nom uchun baribir avval oq ro'yxat.sql.begin— avtomatik COMMIT/ROLLBACK, ichkarida faqattx;sql.unsafe— xom SQL, kanonda 13 o'rniga 48 qator.- Turlar
pgbilan bir xil:bigint,numeric,count— string. - Kanon: ketma-ket teng (2 667 / 2 822 ms), parallelda postgres.js 17 baravar tez (pipelining) — og'ir so'rovda farq kamayadi.
- Har drayverda qoida bir xil: qiymat — alohida (
$1,?, teg).
Keyingi dars: Connection pooling — hovuz hajmini qanday tanlash, release() unutilganda nima bo'ladi va 101-ulanish nega rad etiladi.
Manbalar
- postgres.js (porsager) — README: queries, dynamic
sql(),sql.begin,sql.unsafe: https://github.com/porsager/postgres - Node.js 24 hujjati — SQLite (
node:sqlite, Stability 1.2): https://nodejs.org/docs/latest-v24.x/api/sqlite.html - Bun hujjati — SQL (
sql.unsafeogohlantirishi), 2026-10-24 da o'qildi: https://bun.com/docs/runtime/sql - mysql2: https://sidorares.github.io/node-mysql2/docs · better-sqlite3: https://github.com/WiseLibs/better-sqlite3 · MongoDB Node driver: https://www.mongodb.com/docs/drivers/node/current/ (sinalmagan)
- PostgreSQL 18 hujjati — Pipeline mode (libpq): https://www.postgresql.org/docs/18/libpq-pipeline-mode.html
- Kanon:
tajriba/t43-postgres-js.mjs,natijalar/tajriba/t43-postgres-js.txt(postgres 3.4.9, pg 8.23.1, PostgreSQL 18.6, 2026-10-24).node:sqlitemisollari — biz ishga tushirdik (Node 24.21.0).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!