ts-sql-query في TypeScript: دليل شامل مع أمثلة عملية
1. ما هي ts-sql-query ولماذا تحتاجها؟
ts-sql-query هي مكتبة قوية مبنية على TypeScript تتيح لك كتابة استعلامات SQL مع دعم كامل للأنواع (type-safe). توفر هذه المكتبة لغة خاصة بالمجال (DSL) لبناء استعلامات SQL، حيث يتم التحقق من كل استعلام بواسطة مترجم TypeScript للتأكد من توافقه مع مخطط قاعدة البيانات. هذا يعني أن الأخطاء في أسماء الجداول أو الحقول أو أنواع البيانات سيتم اكتشافها أثناء مرحلة الترجمة (compile time) وليس أثناء تشغيل التطبيق (runtime).
لماذا تحتاج إلى هذه المكتبة؟ في الطرق التقليدية (كتابة SQL كنصوص خام أو استخدام ORM)، غالبًا ما يواجه المطورون مشاكل مثل: أخطاء إملائية في أسماء الأعمدة، عدم تطابق الأنواع، وصعوبة إعادة الهيكلة (refactoring). تحل ts-sql-query هذه المشاكل من خلال توفير كتابة صارمة للأنواع لجميع العمليات: SELECT، INSERT، UPDATE، DELETE، JOIN، الاستعلامات الفرعية، الدوال التجميعية، وغيرها الكثير. تدعم المكتبة العديد من أنظمة إدارة قواعد البيانات (PostgreSQL، MySQL، SQLite، MariaDB، MSSQL) ويمكنها العمل مباشرة مع برامج التشغيل (drivers) أو من خلال مجمعات الاتصالات (connection pools).
على عكس ORM (مثل TypeORM أو Prisma)، لا تخفي ts-sql-query SQL خلف طبقات من التجريد، بل تجعلها جزءًا من كود TypeScript. ستظل تكتب SQL، ولكن مع الإكمال التلقائي (autocomplete)، والتحقق من الأنواع، وبدون خطر حقن SQL (SQL injection). هذا هو الخيار الأمثل للمشاريع التي تهم فيها الأداء والتحكم الكامل في الاستعلامات، مع الاستفادة من مزايا الكتابة الثابتة (static typing).
2. طريقة التثبيت
يتم التثبيت عبر npm. ستحتاج إلى تثبيت المكتبة الأساسية بالإضافة إلى برنامج التشغيل (driver) الخاص بقاعدة البيانات التي تستخدمها.
# تثبيت المكتبة الأساسية
npm install ts-sql-query
# تثبيت برنامج تشغيل PostgreSQL (مثال)
npm install pg
# تثبيت برنامج تشغيل MySQL
npm install mysql2
# تثبيت برنامج تشغيل SQLite
npm install better-sqlite3
# تثبيت برنامج تشغيل SQLite (غير متزامن)
npm install sql.js
# تثبيت أنواع Node.js (إذا كنت تستخدمها)
npm install --save-dev @types/node
بعد تثبيت برنامج التشغيل، ستحتاج إلى إنشاء اتصال بقاعدة البيانات. توفر ts-sql-query محولات (adapters) لكل برنامج تشغيل.
3. البداية السريعة — مثال عملي بسيط
لنلقِ نظرة على مثال باستخدام PostgreSQL. سننشئ جدولًا بسيطًا باسم users وننفذ استعلام SELECT.
import { createPool } from 'pg';
import { PostgreSqlConnection } from 'ts-sql-query/connections/PostgreSqlConnection';
// 1. إنشاء مجمع اتصالات
const pool = createPool({
host: 'localhost',
port: 5432,
database: 'testdb',
user: 'user',
password: 'password',
});
// 2. إنشاء كلاس الاتصال
class DBConnection extends PostgreSqlConnection {
// يمكنك هنا تعريف دوال للتعامل مع الجداول
}
// 3. إنشاء نسخة من الاتصال
const connection = new DBConnection(pool);
// 4. تعريف نوع (interface) لجدول users
interface User {
id: number;
name: string;
email: string;
age: number;
}
// 5. إنشاء كائن للتعامل مع الجدول
const users = connection.table('users').columns({
id: 'id',
name: 'name',
email: 'email',
age: 'age',
});
// 6. تنفيذ الاستعلام
async function getUsers() {
const query = connection
.selectFrom(users)
.select(users.id, users.name, users.email)
.where(users.age.greaterThan(18))
.orderBy(users.name, 'asc');
const result = await query.executeSelectMany();
return result;
}
getUsers().then(users => {
console.log('Users:', users);
}).catch(err => {
console.error('Error:', err);
});
في هذا المثال، قمنا بإنشاء اتصال، وعرّفنا جدولًا، ونفّذنا استعلام SELECT. يتم التحقق من جميع الأنواع بواسطة المترجم.