Supabase • المستوى الثالث • الدرس 2
العودة لفهرس المستوىقاعدة البيانات العلاقلية والأمان (Postgres + RLS)
أهداف الدرس
- CRUD كامل:
select,insert,update,delete. - الفلاتر:
eq,gte,order,limit. - الفهم الأساسي لـ Row Level Security (RLS).
- الاستعلامات الآمنة والأداء العالي.
1. Supabase Database — نظرة عامة
Supabase يعطيك قاعدة بيانات PostgreSQL كاملة، لكن مع واجهة JavaScript بسيطة تشبه ORM خفيف. يمكنك استخدام:
- • الطريقة الكاملة:
supabase.from('table').select()(هي التي سنتعلمها). - • الطريقة المباشرة: SQL عبر
supabase.rpc()أو psql.
javascript
// طريقة Supabase للاستعلامات
// from() → select() → filters → single()
const { data, error } = await supabase
.from('users') // المجموعة / الجدول
.select('*') // الأعمدة
.eq('age', 25) // فلتر
.order('name'); // ترتيب2. القراءة — select
select() هي نقطة البداية لأي قراءة. يمكنك تحديد الأعمدة أو استخدام *:
javascript
// كل الأعمدة
await supabase.from('users').select('*');
// أعمدة محددة
await supabase.from('users').select('name, age');
// مع جدول مرتبط (Foreign Table)
await supabase
.from('orders')
.select('id, total, users(name, email)');
// مع عدّاد
await supabase
.from('users')
.select('*', { count: 'exact' });3. الفلاتر — eq, gte, order, limit
بعد select()، يمكنك إضافة سلسلة من الفلاتر (Method Chaining):
eq
مساواة دقيقة.
.eq('id', 5)gte
أكبر أو يساوي.
.gte('age', 18)order
ترتيب النتائج.
.order('age', { ascending: false })limit
تحديد العدد.
.limit(5)
javascript
// استعلام مركب
const { data, error } = await supabase
.from('users')
.select('name, age')
.gte('age', 18)
.order('age', { ascending: false })
.limit(5);
// فلاتر أخرى شائعة:
// .lte() — أصغر أو يساوي
// .gt() — أكبر من
// .lt() — أصغر من
// .neq() — لا يساوي
// .like() — مطابقة نمط
// .in() — ضمن قائمة
// .is() — للـ NULL4. الإدراج والتحديث والحذف
insert
إدراج صف أو عدة صفوف.
await supabase
.from('users')
.insert([{ name, email }]);update
تحديث صفوف (يحتاج .eq لتفادي تحديث الكل).
await supabase
.from('users')
.update({ age: 30 })
.eq('id', 5);delete
حذف صفوف (يحتاج .eq).
await supabase
.from('users')
.delete()
.eq('id', 5);single
جلب صف واحد فقط (يُعيد كائناً لا مصفوفة).
await supabase
.from('users')
.select('*')
.eq('id', 5)
.single();تحذير أمني
await supabase.from('users').delete(); // يحذف كل شيء!في Supabase، delete() بدون .eq = مسح كامل. دائماً استخدم .eq أو فلتراً.
5. Row Level Security (RLS)
RLS هي طبقة أمان على مستوى الصف في Postgres. تُتيح لك تحديد: من يمكنه قراءة أي صف، من يمكنه تعديله، من يمكنه حذفه.
مثال Policy
-- كل مستخدم يقرأ بياناته فقط CREATE POLICY "Users can read own data" ON users FOR SELECT USING (auth.uid() = user_id); -- كل مستخدم يعدّل بياناته فقط CREATE POLICY "Users can update own data" ON users FOR UPDATE USING (auth.uid() = user_id);
- •
auth.uid()— يُرجع UID المستخدم الحالي - •
USING— الشرط للقراءة/التحديث - •
WITH CHECK— الشرط للإدراج/التحديث الجديد
sql
-- مثال شامل: جدول messages
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
user_id UUID REFERENCES auth.users(id),
content TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- RLS: لا يمكن قراءة إلا رسائل المستخدم
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own messages"
ON messages FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users insert own messages"
ON messages FOR INSERT
WITH CHECK (auth.uid() = user_id); التطبيق العملي
تحدي الدرس: CRUD كامل لجدول users
- أضف
createUserمعinsert. - أضف
updateUserAgeمعupdate().eq(). - أضف
deleteUserمعdelete().eq(). - أضف
getAdultsمعgte + order + limit. - أضف
getUserByIdمعsingle(). - أضف اختباراً تلقائياً.
⏳ جارٍ التحميل...