مقدمة في العمل مع قواعد البيانات بلغة Rust
لغة Rust تكتسب شعبية متسارعة في البرمجة النظامية، لكن إمكانياتها تتجاوز بكثير المهام منخفضة المستوى. بفضل نظام الأنواع الصارم، وأمان الذاكرة، والأداء العالي، تصبح Rust خياراً ممتازاً لبناء تطبيقات خادم موثوقة تعمل مع قواعد البيانات. في هذه المقالة، سنشرح بالتفصيل كيفية الاتصال وتنفيذ العمليات مع اثنين من أنظمة إدارة قواعد البيانات الشهيرة: قاعدة البيانات العلائقية PostgreSQL وقاعدة البيانات الوثائقية MongoDB.
سنستعرض المكتبات الرئيسية (creates) مثل diesel لـ PostgreSQL والمشغل الرسمي mongodb، بالإضافة إلى عرض أمثلة لعمليات CRUD بلغة Rust الخالصة. ستكون المقالة مفيدة لكل من المبتدئين والمطورين ذوي الخبرة الراغبين في توسيع مجموعة تقنياتهم.
1. العمل مع PostgreSQL: Create Diesel
Diesel هو ORM آمن وقابل للتوسع ومنشئ استعلامات للغة Rust. يضمن التحقق من الأنواع في مرحلة التجميع، مما يستبعد العديد من أخطاء وقت التشغيل المتعلقة باستعلامات SQL. للبدء، يجب إضافة التبعيات إلى ملف Cargo.toml.
التثبيت والإعداد
أضف هذه الكريتات (creates):
[dependencies]diesel = { version = "2.1", features = ["postgres"] }dotenvy = "0.15"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1.0", features = ["full"] }قم أيضاً بتثبيت أداة سطر الأوامر Diesel CLI:
cargo install diesel_cli --no-default-features --features postgresأنشئ ملف .env في جذر المشروع مع رابط قاعدة البيانات الخاصة بك:
DATABASE_URL=postgres://username:password@localhost/my_databaseنفذ الأمر لإعداد الترحيلات (migrations):
diesel setupdiesel migration generate create_usersتعريف المخطط (Schema) والنموذج (Model)
في ملف الترحيل up.sql، اكتب SQL لإنشاء الجدول:
CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, email VARCHAR NOT NULL UNIQUE, age INTEGER NOT NULL);ثم نفذ diesel migration run. بعد ذلك، قم بإنشاء مخطط Rust (ملف src/schema.rs) باستخدام:
diesel print-schema > src/schema.rsالآن سنحدد النموذج والهيكل لإدراج البيانات:
// src/models.rsuse diesel::prelude::*;use serde::{Deserialize, Serialize};use crate::schema::users;
#[derive(Queryable, Selectable, Serialize, Deserialize)]#[diesel(table_name = users)]pub struct User { pub id: i32, pub name: String, pub email: String, pub age: i32,}
#[derive(Insertable, Deserialize)]#[diesel(table_name = users)]pub struct NewUser { pub name: String, pub email: String, pub age: i32,}عمليات CRUD مع PostgreSQL
لنستعرض العمليات الأساسية. الاتصال بقاعدة البيانات وإنشاء مستخدم جديد:
use diesel::prelude::*;use dotenvy::dotenv;use std::env;
use crate::models::{NewUser, User};use crate::schema::users::dsl::*;
pub fn establish_connection() -> PgConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL") .expect("DATABASE_URL must be set"); PgConnection::establish(&database_url) .expect(&format!("Error connecting to {}", database_url))}
pub fn create_user(conn: &mut PgConnection, name: &str, email: &str, age: i32) -> User { let new_user = NewUser { name: name.to_string(), email: email.to_string(), age, };
diesel::insert_into(users) .values(&new_user) .returning(User::as_returning()) .get_result(conn)```