surrealdb_core/sql/
order.rs1use crate::sql::fmt::Fmt;
2use crate::sql::idiom::Idiom;
3use crate::sql::Value;
4use revision::revisioned;
5use serde::{Deserialize, Serialize};
6use std::ops::Deref;
7use std::{cmp, fmt};
8
9#[revisioned(revision = 1)]
10#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
11#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
12#[non_exhaustive]
13pub enum Ordering {
14 Random,
15 Order(OrderList),
16}
17
18impl fmt::Display for Ordering {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 match self {
21 Ordering::Random => write!(f, "ORDER BY RAND()"),
22 Ordering::Order(list) => writeln!(f, "ORDER BY {list}"),
23 }
24 }
25}
26
27#[revisioned(revision = 1)]
28#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
29#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
30#[non_exhaustive]
31pub struct OrderList(pub Vec<Order>);
32
33impl Deref for OrderList {
34 type Target = Vec<Order>;
35 fn deref(&self) -> &Self::Target {
36 &self.0
37 }
38}
39
40impl fmt::Display for OrderList {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 write!(f, "{}", Fmt::comma_separated(&self.0))
43 }
44}
45
46impl OrderList {
47 pub(crate) fn compare(&self, a: &Value, b: &Value) -> cmp::Ordering {
48 for order in &self.0 {
49 let o = match order.direction {
51 true => a.compare(b, &order.value.0, order.collate, order.numeric),
52 false => b.compare(a, &order.value.0, order.collate, order.numeric),
53 };
54 match o {
56 Some(cmp::Ordering::Greater) => return cmp::Ordering::Greater,
57 Some(cmp::Ordering::Equal) => continue,
58 Some(cmp::Ordering::Less) => return cmp::Ordering::Less,
59 None => continue,
60 }
61 }
62 cmp::Ordering::Equal
63 }
64}
65
66#[revisioned(revision = 1)]
67#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
68#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
69#[non_exhaustive]
70pub struct Order {
71 pub value: Idiom,
73 pub collate: bool,
74 pub numeric: bool,
75 pub direction: bool,
77}
78
79impl fmt::Display for Order {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 write!(f, "{}", self.value)?;
82 if self.collate {
83 write!(f, " COLLATE")?;
84 }
85 if self.numeric {
86 write!(f, " NUMERIC")?;
87 }
88 if !self.direction {
89 write!(f, " DESC")?;
90 }
91 Ok(())
92 }
93}
94
95#[revisioned(revision = 1)]
96#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
97#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
98#[non_exhaustive]
99pub struct OldOrders(pub Vec<OldOrder>);
100
101#[revisioned(revision = 1)]
102#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
103#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
104#[non_exhaustive]
105pub struct OldOrder {
106 pub order: Idiom,
107 pub random: bool,
108 pub collate: bool,
109 pub numeric: bool,
110 pub direction: bool,
112}