ORM API
## Архитектура и основные компоненты
Система построена по модульному принципу, где каждый компонент отвечает за конкретную функциональность. Основные модули включают:
— **query/** — построение SQL-запросов
— **connection/** — управление соединениями с БД
— **security/** — система безопасности
— **cache/** — кэширование результатов
— **metrics/** и **monitoring/** — мониторинг производительности
— **scaling/** — масштабирование и балансировка
## Модуль построения запросов (query/)
### SelectBuilder — построение SELECT-запросов
«`rust
pub struct SelectBuilder
table: String,
fields: Vec
joins: Vec
where_conditions: Option
order_by: Vec<(String, Order)>,
limit: Option
offset: Option
distinct: bool,
group_by: Vec
having: Option
_phantom: PhantomData
}
«`
**Основные методы:**
«`rust
impl
pub fn new(table: &str) -> Self {
Self {
table: table.to_string(),
fields: Vec::new(),
joins: Vec::new(),
where_conditions: None,
order_by: Vec::new(),
limit: None,
offset: None,
distinct: false,
group_by: Vec::new(),
having: None,
_phantom: PhantomData,
}
}
pub fn fields(mut self, fields: &[&str]) -> Self {
self.fields = fields.iter().map(|s| s.to_string()).collect();
self
}
pub fn r#where(mut self, condition: Condition) -> Self {
self.where_conditions = Some(condition);
self
}
pub fn order_by(mut self, field: &str, order: Order) -> Self {
self.order_by.push((field.to_string(), order));
self
}
pub fn build(&self) -> String {
let distinct = if self.distinct { «DISTINCT » } else { «» };
let fields = if self.fields.is_empty() {
«*».to_string()
} else {
self.fields.join(«, «)
};
// … генерация SQL …
}
}
«`
**Пример использования:**
«`rust
let query = SelectBuilder::new(«users»)
.fields(&[«id», «name», «email»])
.r#where(Condition::eq(«active», true))
.order_by(«created_at», Order::Desc)
.limit(10)
.build();
«`
### InsertBuilder — построение INSERT-запросов
«`rust
pub struct InsertBuilder {
table: String,
columns: Vec
values: Vec
returning: Vec
on_conflict: Option
}
#[derive(Debug, Clone)]
pub enum ConflictResolution {
DoNothing,
DoUpdate(Vec<(String, QueryParameter)>),
}
«`
**Основные методы:**
«`rust
impl InsertBuilder {
pub fn new(table: &str) -> Self {
Self {
table: table.to_string(),
columns: Vec::new(),
values: Vec::new(),
returning: Vec::new(),
on_conflict: None,
}
}
pub fn columns(mut self, columns: &[&str]) -> Self {
self.columns = columns.iter().map(|s| s.to_string()).collect();
self
}
pub fn values(mut self, values: &[QueryParameter]) -> Self {
if self.columns.len() != values.len() {
panic!(«Columns and values must have the same length»);
}
self.values.push(values.to_vec());
self
}
pub fn on_conflict_do_nothing(mut self) -> Self {
self.on_conflict = Some(ConflictResolution::DoNothing);
self
}
}
«`
### Condition — система условий WHERE
«`rust
#[derive(Debug, Clone)]
pub enum Condition {
Simple {
field: String,
operator: Operator,
value: String,
},
And(Vec
Or(Vec
Group(Box
Raw(String),
Parameterized {
field: String,
operator: Operator,
parameter_index: usize,
},
}
#[derive(Debug, Clone)]
pub enum Operator {
Eq, Ne, Gt, Ge, Lt, Le,
Like, ILike, In, Between,
IsNull, IsNotNull,
NotIn, NotLike,
}
«`
**Пример составных условий:**
«`rust
let condition = Condition::and(vec![
Condition::eq(«status», «active»),
Condition::or(vec![
Condition::gt(«age», 18),
Condition::is_not_null(«parent_id»)
])
]);
«`
## Модуль параметров запросов (parameter/)
### QueryParameter — типобезопасные параметры
«`rust
#[derive(Debug, Clone)]
pub enum QueryParameter {
String(String),
Integer(i64),
Boolean(bool),
Null,
Float(f64),
Decimal(String),
Date(String),
DateTime(String),
Json(String),
Bytes(Vec
}
impl QueryParameter {
pub fn to_sql(&self) -> String {
match self {
QueryParameter::String(s) => format!(«‘{}'», s.replace(«‘», «»»)),
QueryParameter::Integer(i) => i.to_string(),
QueryParameter::Boolean(b) => if *b { «TRUE» } else { «FALSE» }.to_string(),
QueryParameter::Null => «NULL».to_string(),
// … обработка других типов …
}
}
pub fn validate(&self) -> Result<(), String> {
match self {
QueryParameter::String(s) => {
if s.len() > 100_000 {
return Err(«String parameter too long».to_string());
}
Ok(())
}
QueryParameter::Integer(i) => {
if *i == i64::MIN || *i == i64::MAX {
return Err(«Integer parameter at extreme bounds may cause issues».to_string());
}
Ok(())
}
// … валидация других типов …
}
}
}
«`
## Модуль управления соединениями (connection.rs)
### HighPerformanceConnectionManager
«`rust
pub struct HighPerformanceConnectionManager {
primary_pool: PgPool,
read_pool: PgPool,
write_pool: PgPool,
replica_pools: Vec
connection_semaphore: Arc
max_connections: u32,
current_connections: Arc
}
impl HighPerformanceConnectionManager {
pub async fn new(config: DatabaseConfig) -> Result
let primary_pool = PgPoolOptions::new()
.max_connections(config.max_connections)
.min_connections(config.min_connections)
.acquire_timeout(Duration::from_secs(2))
.connect(&config.primary_url)
.await?;
let read_pool = PgPoolOptions::new()
.max_connections(config.max_connections * 2)
.connect(&config.primary_url)
.await?;
let write_pool = PgPoolOptions::new()
.max_connections(config.max_connections / 2)
.connect(&config.primary_url)
.await?;
// … создание пулов реплик …
Ok(Self {
primary_pool,
read_pool,
write_pool,
replica_pools,
connection_semaphore: Arc::new(Semaphore::new(max_connections as usize)),
max_connections,
current_connections: Arc::new(AtomicUsize::new(0)),
})
}
pub fn get_pool_for_query(&self, is_read_query: bool) -> &PgPool {
if is_read_query {
self.get_read_pool()
} else {
self.get_write_pool()
}
}
pub async fn acquire_connection(&self) -> Result
let permit = self.connection_semaphore.acquire().await
.map_err(|_| sqlx::Error::PoolClosed)?;
self.current_connections.fetch_add(1, Ordering::SeqCst);
Ok(permit)
}
}
«`
## Модуль безопасности (security/)
### AdvancedSecurityLayer
«`rust
pub struct AdvancedSecurityLayer {
rate_limiter: Arc
sql_injection_detector: Arc
query_analyzer: Arc
ip_blocker: Arc
query_patterns: Arc
}
impl AdvancedSecurityLayer {
pub async fn validate_query(&self, query: &str, client_ip: &str) -> Result<(), SecurityError> {
// Проверка блокировки IP
if let Ok(ip) = client_ip.parse::
if self.ip_blocker.is_blocked(&ip).await {
return Err(SecurityError::IpBlocked);
}
}
// Проверка лимита запросов
self.rate_limiter.check_limit(client_ip).await?;
// Проверка SQL инъекций
self.sql_injection_detector.detect(query)?;
// Анализ запроса
let analysis = self.query_analyzer.analyze(query)?;
self.analyze_query_pattern(client_ip, &analysis).await?;
Ok(())
}
}
«`
### SqlInjectionDetector
«`rust
pub struct SqlInjectionDetector {
malicious_patterns: Vec
whitelist_patterns: Vec
suspicious_keywords: Vec<&'static str>,
}
impl SqlInjectionDetector {
pub fn detect(&self, query: &str) -> Result<(), SecurityError> {
// Сначала проверяем белый список
for pattern in &self.whitelist_patterns {
if pattern.is_match(query) {
return Ok(());
}
}
// Затем проверяем опасные паттерны
for pattern in &self.malicious_patterns {
if pattern.is_match(query) {
return Err(SecurityError::SqlInjectionAttempt);
}
}
let upper_query = query.to_uppercase();
for keyword in &self.suspicious_keywords {
if upper_query.contains(keyword) {
return Err(SecurityError::SqlInjectionAttempt);
}
}
Ok(())
}
}
«`
### RateLimiter
«`rust
pub struct RateLimiter {
requests: Arc
max_requests_per_minute: usize,
cleanup_interval: Duration,
last_cleanup: Arc
cleanup_count: std::sync::atomic::AtomicU64,
}
impl RateLimiter {
pub async fn check_limit(&self, client_ip: &str) -> Result<(), SecurityError> {
let now = Instant::now();
self.cleanup_expired(now).await;
let mut entry = self.requests.entry(client_ip.to_string()).or_insert_with(Vec::new);
// Удаляем записи старше 60 секунд
entry.retain(|&time| now.duration_since(time) < Duration::from_secs(60));
if entry.len() >= self.max_requests_per_minute {
return Err(SecurityError::RateLimitExceeded);
}
entry.push(now);
Ok(())
}
}
«`
## Модуль кэширования (cache.rs)
### MultiLevelCache
«`rust
pub struct MultiLevelCache {
l1_cache: Arc
l2_cache: Arc
external_cache_enabled: bool,
ttl: Duration,
}
impl MultiLevelCache {
pub async fn get(&self, key: &str) -> Option
let now = Instant::now();
// Уровень 1: LRU кэш
let mut l1_cache = self.l1_cache.lock().await;
if let Some((value, timestamp)) = l1_cache.get(key) {
if now.duration_since(*timestamp) < self.ttl {
return Some(value.clone());
} else {
l1_cache.pop(key);
}
}
drop(l1_cache);
// Уровень 2: DashMap кэш
if let Some(entry) = self.l2_cache.get(key) {
let (value, timestamp) = entry.clone();
if now.duration_since(timestamp) < self.ttl {
// Обновляем L1 кэш
let mut l1_cache = self.l1_cache.lock().await;
l1_cache.put(key.to_string(), (value.clone(), timestamp));
return Some(value);
} else {
self.l2_cache.remove(key);
}
}
None
}
pub async fn set(&self, key: String, value: String) {
let now = Instant::now();
let mut l1_cache = self.l1_cache.lock().await;
l1_cache.put(key.clone(), (value.clone(), now));
drop(l1_cache);
self.l2_cache.insert(key, (value, now));
}
}
```
### QueryResultCache
```rust
pub struct QueryResultCache {
cache: MultiLevelCache,
query_timeout: Duration,
}
impl QueryResultCache {
fn generate_cache_key(&self, query: &str, params: &[&str]) -> String {
let mut key = query.to_string();
for param in params {
key.push_str(param);
}
format!(«{:x}», md5::compute(key))
}
pub async fn get_query_result(&self, query: &str, params: &[&str]) -> Option
let cache_key = self.generate_cache_key(query, params);
self.cache.get(&cache_key).await
}
}
«`
## Модуль мониторинга (metrics.rs)
### MetricsCollector
«`rust
pub struct MetricsCollector {
metrics: Arc
query_history: Arc
start_time: Instant,
}
struct MetricsData {
total_queries: AtomicU64,
successful_queries: AtomicU64,
failed_queries: AtomicU64,
cache_hits: AtomicU64,
cache_misses: AtomicU64,
batch_queries_processed: AtomicU64,
active_connections: AtomicUsize,
prepared_statements_count: AtomicUsize,
response_times: Mutex
}
impl MetricsCollector {
pub fn record_query_start(&self) -> QueryTimer {
self.metrics.total_queries.fetch_add(1, Ordering::Relaxed);
self.metrics.active_connections.fetch_add(1, Ordering::Relaxed);
QueryTimer {
start_time: Instant::now(),
query_type: String::new(),
client_ip: String::new(),
}
}
pub fn record_query_success(&self, query_metrics: QueryMetrics) {
self.metrics.successful_queries.fetch_add(1, Ordering::Relaxed);
self.metrics.active_connections.fetch_sub(1, Ordering::Relaxed);
let response_times = self.metrics.response_times.try_lock();
if let Ok(mut times) = response_times {
times.push(query_metrics.execution_time);
if times.len() > 1000 {
times.drain(0..100);
}
}
// Сохраняем историю запросов
let query_key = format!(«{}:{}», query_metrics.query_type, &query_metrics.client_ip[..8]);
self.query_history.entry(query_key)
.or_insert_with(Vec::new)
.push(query_metrics);
}
pub fn get_metrics(&self) -> ServerMetrics {
let total_queries = self.metrics.total_queries.load(Ordering::Relaxed);
let uptime = self.start_time.elapsed().as_secs_f64();
let response_times = self.metrics.response_times.try_lock()
.map(|times| times.clone())
.unwrap_or_default();
let average_response_time = if !response_times.is_empty() {
response_times.iter().map(|d| d.as_secs_f64()).sum::
} else {
0.0
};
ServerMetrics {
total_queries,
successful_queries: self.metrics.successful_queries.load(Ordering::Relaxed),
failed_queries: self.metrics.failed_queries.load(Ordering::Relaxed),
average_response_time,
queries_per_second: total_queries as f64 / uptime.max(1.0),
cache_hits: self.metrics.cache_hits.load(Ordering::Relaxed),
cache_misses: self.metrics.cache_misses.load(Ordering::Relaxed),
active_connections: self.metrics.active_connections.load(Ordering::Relaxed),
prepared_statements_count: self.metrics.prepared_statements_count.load(Ordering::Relaxed),
batch_queries_processed: self.metrics.batch_queries_processed.load(Ordering::Relaxed),
}
}
}
«`
### PerformanceMonitor
«`rust
pub struct PerformanceMonitor {
metrics_sender: broadcast::Sender
last_update: Instant,
query_count: u64,
total_response_time: Duration,
error_count: u64,
server_metrics: Arc
}
impl PerformanceMonitor {
pub fn record_query(&mut self, response_time: Duration) {
self.query_count += 1;
self.total_response_time += response_time;
if self.last_update.elapsed() >= Duration::from_secs(1) || self.query_count >= 1000 {
let sender = self.metrics_sender.clone();
let server_metrics = self.server_metrics.clone();
let query_count = self.query_count;
let total_response_time = self.total_response_time;
let error_count = self.error_count;
let last_update = self.last_update;
tokio::spawn(async move {
Self::emit_metrics_async(
sender,
server_metrics,
query_count,
total_response_time,
error_count,
last_update
).await;
});
self.last_update = Instant::now();
self.query_count = 0;
self.total_response_time = Duration::default();
self.error_count = 0;
}
}
}
«`
## Модуль балансировки нагрузки (scaling/balancer.rs)
### ReadReplicaBalancer
«`rust
pub struct ReadReplicaBalancer {
replicas: Arc
current_index: AtomicUsize,
strategy: LoadBalancingStrategy,
node_metrics: Arc
}
#[derive(Debug, Clone)]
pub enum LoadBalancingStrategy {
RoundRobin,
WeightedRoundRobin,
LeastConnections,
LatencyBased,
}
impl ReadReplicaBalancer {
pub async fn select_replica(&self) -> Option
let replicas = self.replicas.read().await;
if replicas.is_empty() {
return None;
}
match self.strategy {
LoadBalancingStrategy::RoundRobin => {
let index = self.current_index.fetch_add(1, Ordering::Relaxed);
replicas.get(index % replicas.len()).cloned()
}
LoadBalancingStrategy::LeastConnections => {
self.select_least_loaded(&replicas).await
}
LoadBalancingStrategy::LatencyBased => {
self.select_lowest_latency(&replicas).await
}
LoadBalancingStrategy::WeightedRoundRobin => {
self.select_weighted(&replicas).await
}
}
}
async fn select_least_loaded(&self, replicas: &[DatabaseNode]) -> Option
let metrics = self.node_metrics.read().await;
let mut best_node = None;
let mut min_connections = usize::MAX;
for (i, node) in replicas.iter().enumerate() {
if let Some(metric) = metrics.get(i) {
if metric.is_healthy && metric.connection_count < min_connections {
min_connections = metric.connection_count;
best_node = Some(node.clone());
}
}
}
best_node
}
}
```
## Модуль автоматического масштабирования (scaling/auto_scaler.rs)
### AutoScaler
```rust
pub struct AutoScaler {
config: AutoScalingConfig,
current_replicas: Arc
metrics_history: Arc
}
impl AutoScaler {
pub async fn check_and_scale(&self, current_metrics: SystemMetrics) -> ScalingDecision {
if !self.config.enable_auto_scaling {
return ScalingDecision::NoAction;
}
let current_replicas = *self.current_replicas.read().await;
// Проверяем условия для масштабирования вверх
if self.should_scale_up(¤t_metrics, current_replicas).await {
let new_replicas = (current_replicas + 1).min(self.config.max_replicas);
*self.current_replicas.write().await = new_replicas;
return ScalingDecision::ScaleUp(new_replicas);
}
// Проверяем условия для масштабирования вниз
if self.should_scale_down(¤t_metrics, current_replicas).await {
let new_replicas = current_replicas.saturating_sub(1).max(1);
*self.current_replicas.write().await = new_replicas;
return ScalingDecision::ScaleDown(new_replicas);
}
ScalingDecision::NoAction
}
async fn should_scale_up(&self, metrics: &SystemMetrics, current_replicas: usize) -> bool {
if current_replicas >= self.config.max_replicas {
return false;
}
metrics.cpu_usage > self.config.scale_up_cpu_threshold ||
metrics.active_connections > self.config.scale_up_connections_threshold ||
metrics.queries_per_second > 1000.0
}
}
«`
## Основной серверный модуль (server.rs)
### SqlServer
«`rust
pub struct SqlServer {
connection_manager: HighPerformanceConnectionManager,
security_layer: AdvancedSecurityLayer,
prepared_statements: Arc
batch_processor: Arc
metrics: Arc
query_cache: Arc
is_running: bool,
}
impl SqlServer {
pub async fn execute_query(
&self,
query: &str,
client_ip: &str,
) -> Result
if !self.is_running {
return Err(ServerError::NotRunning);
}
let timer = self.metrics.record_query_start()
.set_query_type(self.detect_query_type(query))
.set_client_ip(client_ip);
// Проверка безопасности
self.security_layer.validate_query(query, client_ip).await?;
let is_read_query = query.trim_start().to_uppercase().starts_with(«SELECT»);
let has_returning = query.to_uppercase().contains(«RETURNING»);
// Проверяем кэш для SELECT запросов
if is_read_query && !has_returning {
if let Some(cached) = self.query_cache.get_query_result(query, &[]).await {
self.metrics.record_cache_hit();
let query_metrics = timer.finish(0, true, false);
self.metrics.record_query_success(query_metrics);
return Ok(QueryResult {
rows_affected: 0,
execution_time: Duration::default(),
used_replica: false,
used_cache: true,
cached_result: Some(cached),
});
}
}
self.metrics.record_cache_miss();
let pool = self.connection_manager.get_pool_for_query(is_read_query);
let statement_sql = self.get_prepared_statement(query).await?;
let start_time = Instant::now();
if is_read_query || has_returning {
let result = sqlx::query(&statement_sql).fetch_all(pool).await?;
let duration = start_time.elapsed();
let json_result = Self::rows_to_json(result);
if is_read_query && !has_returning {
self.query_cache.set_query_result(query, &[], json_result.clone()).await;
}
let used_replica = is_read_query &&
std::ptr::eq(pool as *const _, self.connection_manager.get_read_pool() as *const _);
let query_metrics = timer.finish(0, false, used_replica);
self.metrics.record_query_success(query_metrics);
Ok(QueryResult {
rows_affected: 0,
execution_time: duration,
used_replica,
used_cache: false,
cached_result: Some(json_result),
})
} else {
let result = sqlx::query(&statement_sql).execute(pool).await?;
let duration = start_time.elapsed();
let used_replica = is_read_query &&
std::ptr::eq(pool as *const _, self.connection_manager.get_read_pool() as *const _);
let query_metrics = timer.finish(result.rows_affected(), false, used_replica);
self.metrics.record_query_success(query_metrics);
Ok(QueryResult {
rows_affected: result.rows_affected(),
execution_time: duration,
used_replica,
used_cache: false,
cached_result: None,
})
}
}
fn rows_to_json(rows: Vec
let mut json_array = Vec::new();
for row in rows {
let mut json_obj = serde_json::Map::new();
for column in row.columns() {
let column_name = column.name();
if let Ok(val) = row.try_get::
json_array.push(Value::Object(json_obj));
}
serde_json::to_string(&json_array).unwrap_or_else(|_| «[]».to_string())
}
}
«`
## Конфигурационная система (config.rs)
### Иерархическая конфигурация
«`rust
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct DatabaseConfig {
pub primary_url: String,
pub replica_urls: Vec
pub max_connections: u32,
pub min_connections: u32,
pub connection_timeout: u64,
pub acquire_timeout: u64,
pub idle_timeout: u64,
pub max_lifetime: u64,
pub statement_cache_size: usize,
pub connect_retries: u32,
}
impl DatabaseConfig {
pub fn validate(&self) -> Result<(), ConfigError> {
if self.max_connections < self.min_connections {
return Err(ConfigError::InvalidConnectionPoolSize);
}
if self.primary_url.is_empty() {
return Err(ConfigError::MissingPrimaryUrl);
}
if !self.primary_url.starts_with("postgres://") &&
!self.primary_url.starts_with("postgresql://") {
return Err(ConfigError::InvalidUrlFormat);
}
if self.connection_timeout == 0 {
return Err(ConfigError::InvalidTimeout("connection_timeout cannot be zero".to_string()));
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct SqlServerConfig {
pub database: DatabaseConfig,
pub security: SecurityConfig,
pub cache: CacheConfig,
pub log_level: String,
}
```
## Утилиты и вспомогательные функции (utils.rs)
```rust
pub const DEFAULT_MAX_CONNECTIONS: u32 = 50;
pub const DEFAULT_QUERY_TIMEOUT: Duration = Duration::from_secs(5);
pub const DEFAULT_CACHE_TTL: Duration = Duration::from_secs(300);
/// Проверка валидности SQL запроса
pub fn is_valid_sql(query: &str) -> bool {
let trimmed = query.trim();
!trimmed.is_empty() &&
trimmed.len() <= 10 * 1024 * 1024 &&
has_valid_sql_structure(trimmed)
}
fn has_valid_sql_structure(query: &str) -> bool {
let upper = query.to_uppercase();
upper.starts_with(«SELECT») ||
upper.starts_with(«INSERT») ||
upper.starts_with(«UPDATE») ||
upper.starts_with(«DELETE») ||
upper.starts_with(«WITH») ||
upper.starts_with(«CREATE») ||
upper.starts_with(«ALTER») ||
upper.starts_with(«DROP»)
}
/// Форматирование времени выполнения
pub fn format_duration(duration: Duration) -> String {
if duration.as_secs() > 0 {
format!(«{:.2}s», duration.as_secs_f64())
} else if duration.as_millis() > 0 {
format!(«{}ms», duration.as_millis())
} else {
format!(«{}μs», duration.as_micros())
}
}
«`
## Инициализация системы (init.rs)
«`rust
pub async fn initialize_sql_server() -> Result<(), Box
let db_config = DatabaseConfig::default();
let security_config = SecurityConfig::default();
println!(«[SQL Server] Initializing with config: {:?}», db_config);
let mut server = SqlServer::new(db_config, security_config).await?;
let server_metrics = server.get_metrics().await;
println!(«[SQL Server] Metrics system initialized: {:?}», server_metrics);
server.start().await?;
QUERY_EXECUTOR.register_server(server).await;
start_background_tasks().await;
println!(«[SQL Server] Initialized successfully and ready for queries»);
Ok(())
}
async fn start_background_tasks() {
tokio::spawn(async move {
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(60));
loop {
interval.tick().await;
perform_maintenance_tasks().await;
}
});
}
«`
## Пример использования системы
«`rust
// Инициализация сервера
initialize_sql_server().await?;
// Выполнение запроса через глобальный executor
let result = QUERY_EXECUTOR.execute_query(
«SELECT * FROM users WHERE active = true»,
«192.168.1.1»
).await;
match result {
Ok(query_result) => {
println!(«Query executed successfully»);
println!(«Rows affected: {}», query_result.rows_affected);
println!(«Execution time: {:?}», query_result.execution_time);
if let Some(cached) = query_result.cached_result {
println!(«Cached result: {}», cached);
}
}
Err(e) => {
eprintln!(«Query failed: {:?}», e);
}
}
// Использование построителя запросов
let select_query = SelectBuilder::new(«orders»)
.fields(&[«id», «customer_id», «amount», «status»])
.r#where(Condition::and(vec![
Condition::eq(«status», «completed»),
Condition::gt(«amount», 100),
Condition::between(«created_at», «2024-01-01», «2024-12-31»)
]))
.order_by(«created_at», Order::Desc)
.limit(50)
.build();
println!(«Generated SQL: {}», select_query);
«`
## Заключение
Данная ORM система предоставляет полный набор инструментов для работы с PostgreSQL в Rust-приложениях. Система включает:
1. **Типобезопасное построение запросов** через билдеры
2. **Интеллектуальное управление соединениями** с пулами для разных типов операций
3. **Многоуровневую систему безопасности** с защитой от инъекций и rate limiting
4. **Эффективное кэширование** с двухуровневой архитектурой
5. **Детальный мониторинг** производительности в реальном времени
6. **Автоматическое масштабирование** и балансировку нагрузки
7. **Гибкую конфигурацию** с поддержкой различных окружений
Система оптимизирована для production-сред и может использоваться в высоконагруженных приложениях, требующих высокой производительности, безопасности и надежности.