Tinqer؛ LINQ برای تایپاسکریپت
خلاصهٔ کاملتر
تو مستندات پروژه اومده که Tinqer یه کوئریبیلدر تایپسیف برای تایپاسکریپته با APIای شبیه فریمورکهای مبتنی بر LINQ تو داتنت. کوئری رو بهعنوان یه arrow function درونخطی مینویسی، کتابخونه اون رو به یه درخت عبارت پارس میکنه و بعد به SQL کامپایلش میکنه — فعلاً برای PostgreSQL و SQLite. خود پکیج هسته @tinqerjs/tinqer هست و برای هر دیتابیس یه آداپتور جدا نصب میکنی.
اول اسکیمای دیتابیس رو بهشکل یه interface تایپاسکریپت تعریف و با createSchema ثبت میکنی، بعد کوئری رو مینویسی:
const results = await executeSelect(db, schema,
(q, params: { minAge: number }) =>
q.from("users")
.where((u) => u.age >= params.minAge)
.orderBy((u) => u.name)
.select((u) => ({ id: u.id, name: u.name })),
{ minAge: 18 },
);نکتهٔ اصلی همینه که همهچی از روی اسکیما تایپ میشه: اسم جدول، فیلدهای داخل where و شکل آبجکتی که select برمیگردونه. خروجی بالا بهشکل خودکار { id: number; name: string } استنتاج میشه، پس اگه اسم یه ستون رو غلط بنویسی یا فیلدی رو حذف کنی، همون موقع کامپایل خطا میگیری نه سر اجرا.
مقادیر متغیر هم از طریق آبجکت params جدا از خود کوئری میرن و بهشکل پارامتر نامدار توی SQL نهایی میشینن، نه اینکه داخل رشتهٔ کوئری چسبونده بشن. همین جدا بودن دادهٔ کاربر از متن کوئری، همون چیزیه که جلوی تزریق SQL رو میگیره.
کنار توابع execute* که کوئری رو واقعاً اجرا میکنن، یه تابع toSql هم هست که فقط SQL و پارامترها رو برمیگردونه بدون اجرا — بهدرد دیباگ، لاگگیری یا اجرای دستی میخوره. برای نوشتن هم defineSelect، defineInsert، defineUpdate و defineDelete رو داری؛ UPSERT هم با زنجیرهٔ onConflict و doUpdateSet روی هر دو دیتابیس کار میکنه.
نکتهٔ آخری که مستندات روش تأکید داره، ترکیبپذیریه: پلنهای کوئری تغییرناپذیرن و هر عملیات بهجای دستکاری پلن قبلی، یه پلن جدید برمیگردونه. یعنی میتونی یه کوئری پایه بسازی و ازش چند نسخهٔ تخصصی شاخه بزنی بدون اینکه نگران باشی نسخهٔ پایه خراب شده. عوض کردن دیتابیس هم فقط عوض کردن آداپتور و کانکشنه؛ منطق خود کوئری دستنخورده میمونه.
نکات کلیدی:
- کوئری بهشکل arrow function تایپاسکریپت نوشته میشه و به SQL پستگرس یا SQLite کامپایل میشه
- نوع خروجی از روی اسکیما استنتاج میشه، پس خطای اسم ستون سر کامپایل گرفته میشه
- پارامترها نامدار و جدا از متن کوئری بایند میشن
- toSql بدون اجرا فقط SQL و پارامترها رو میده؛ مناسب دیباگ و لاگ
- SELECT، INSERT، UPDATE، DELETE و UPSERT پشتیبانی میشن و پلنها تغییرناپذیر و ترکیبپذیرن




