Added distinct_on to query builder

This commit is contained in:
2025-01-07 17:08:08 -05:00
parent 136600ee01
commit e7f337c735
3 changed files with 49 additions and 14 deletions

View File

@@ -1,21 +1,24 @@
use std::fmt::Write;
use crate::data::condition::Condition;
use crate::data::executable_query::ExecutableQuery;
use crate::data::Value;
pub struct QueryBuilder {
table: String,
columns: Vec<String>,
pub struct QueryBuilder<'a> {
table: &'a str,
columns: Vec<&'a str>,
distinct_on: Option<Vec<String>>,
condition: Option<Condition>,
order_by: Vec<String>,
limit: Option<usize>,
offset: Option<usize>,
}
impl QueryBuilder {
pub fn new(table: &str) -> Self {
impl<'a> QueryBuilder<'a> {
pub fn new(table: &'a str) -> Self {
QueryBuilder {
table: table.to_string(),
table,
columns: Vec::new(),
distinct_on: None,
condition: None,
order_by: Vec::new(),
limit: None,
@@ -23,8 +26,13 @@ impl QueryBuilder {
}
}
pub fn select(mut self, columns: &[&str]) -> Self {
self.columns = columns.iter().map(|s| s.to_string()).collect();
pub fn select(mut self, columns: &[&'a str]) -> Self {
self.columns.extend(columns);
self
}
pub fn distinct_on(mut self, columns: &[&str]) -> Self {
self.distinct_on = Some(columns.iter().map(|s| s.to_string()).collect());
self
}
@@ -33,8 +41,11 @@ impl QueryBuilder {
self
}
pub fn order_by(mut self, column: &str, direction: &str) -> Self {
self.order_by.push(format!("{} {}", column, direction));
pub fn order_by(mut self, column: &str, direction: Option<OrderDirection>) -> Self {
match direction {
Some(order) => self.order_by.push(format!("{} {}", column, order.to_string())),
None => self.order_by.push(column.to_string()),
}
self
}
@@ -44,7 +55,22 @@ impl QueryBuilder {
}
}
impl ExecutableQuery for QueryBuilder {
pub enum OrderDirection {
Asc,
Desc
}
impl std::fmt::Display for OrderDirection {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let direction_str = match self {
OrderDirection::Asc => "ASC",
OrderDirection::Desc => "DESC",
};
write!(f, "{}", direction_str)
}
}
impl<'a> ExecutableQuery for QueryBuilder<'a> {
fn build(&self) -> (String, Vec<Value>) {
let columns = if self.columns.is_empty() {
"*".to_string()
@@ -52,7 +78,16 @@ impl ExecutableQuery for QueryBuilder {
self.columns.join(",")
};
let mut query = format!("SELECT {} FROM {}", columns, self.table);
let mut query = String::new();
if let Some(distinct_columns) = &self.distinct_on {
let distinct_on_clause = distinct_columns.join(",");
query = format!("SELECT DISTINCT ON ({}) {}", distinct_on_clause, columns);
} else {
query = format!("SELECT {}", columns);
}
query.push_str(format!(" FROM {}", self.table).as_str());
let mut values: Vec<Value> = Vec::new();
if let Some(condition) = &self.condition {

View File

@@ -1,6 +1,6 @@
use std::fmt;
use axum::http::StatusCode;
use axum::{http, Json};
use axum::Json;
use axum::response::{IntoResponse, Response};
use serde::{Deserialize, Serialize};

View File

@@ -1,7 +1,7 @@
use std::collections::HashSet;
use std::env;
use std::sync::Arc;
use dotenv::{dotenv, from_filename};
use dotenv::from_filename;
use serenity::http::Http;
use serenity::prelude::*;
use songbird::{SerenityInit, Songbird};