Added distinct_on to query builder
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user