geekorm_core/builder/keys/
primary.rs

1//! # Primary Key
2//!
3//! Primary Keys are used to uniquely identify a row in a table.
4//! GeekORM supports three primary key types:
5//!
6//! - `PrimaryKeyInteger` (default)
7//! - `PrimaryKeyString`
8//! - `PrimaryKeyUuid` (requires the `uuid` feature to be enabled)
9//!
10//! # Standard Example
11//!
12//! Here is an example of how to use the PrimaryKey.
13//!
14//! ```rust
15//! use geekorm::prelude::*;
16//!
17//! #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
18//! pub struct Users {
19//!     #[geekorm(primary_key, auto_increment)]
20//!     pub id: PrimaryKeyInteger,
21//!     #[geekorm(unique)]
22//!     pub username: String,
23//! }
24//!
25//! let user = Users {
26//!     id: PrimaryKey::from(1),
27//!     username: String::from("JohnDoe")
28//! };
29//! # assert_eq!(Users::primary_key(), "id");
30//! # assert_eq!(user.id.clone(), PrimaryKey::from(1));
31//! # assert_eq!(user.username.clone(), String::from("JohnDoe"));
32//! ```
33//!
34//! # String Example
35//!
36//! Here is an example of how to use the PrimaryKey struct with a String as the primary key.
37//!
38//! ```rust
39//! use geekorm::prelude::*;
40//!
41//! #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
42//! pub struct Users {
43//!     #[geekorm(primary_key, auto_increment)]
44//!     pub id: PrimaryKeyString,
45//!     #[geekorm(unique)]
46//!     pub username: String,
47//! }
48//!
49//! let user = Users {
50//!     id: PrimaryKey::from("1"),
51//!     username: String::from("JohnDoe")
52//! };
53//! # assert_eq!(user.id.clone(), PrimaryKey::from("1"));
54//! # assert_eq!(user.username.clone(), String::from("JohnDoe"));
55//! ```
56//!
57//! # Uuid Example
58//!
59//! With the `uuid` feature enabled, you can use the `PrimaryKeyUuid` struct to use a
60//! Uuid as the primary key.
61//!
62//! ```rust
63//! use geekorm::prelude::*;
64//!
65//!
66//! #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
67//! pub struct Users {
68//!     #[geekorm(primary_key, auto_increment)]
69//!     pub id: PrimaryKeyUuid,
70//!     #[geekorm(unique)]
71//!     pub username: String,
72//! }
73//!
74//! let new_uuid = uuid::Uuid::new_v4();
75//! let user = Users {
76//!     id: PrimaryKeyUuid::from(new_uuid),
77//!     username: String::from("JohnDoe")
78//! };
79//! # assert_eq!(user.username.clone(), String::from("JohnDoe"));
80//! # assert_eq!(user.id.clone(), PrimaryKeyUuid::from(new_uuid));
81//! ```
82//!
83use core::fmt;
84use std::fmt::{Debug, Display};
85
86use serde::{Deserialize, Serialize, Serializer, de::Visitor};
87#[cfg(feature = "uuid")]
88use uuid::Uuid;
89
90use crate::ToSqlite;
91
92/// # Primary Key
93///
94/// The Primary Key is a column in a Table used to uniquely identify a row.
95///
96/// In GeekORM, it can be an `u64` (default), a `String`, or a `Uuid`.
97///
98/// # Standard Example
99///
100/// Here is an example of how to use the PrimaryKey.
101///
102/// ```rust
103/// use geekorm::prelude::*;
104///
105/// #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
106/// pub struct Users {
107///     #[geekorm(primary_key, auto_increment)]
108///     pub id: PrimaryKey<u64>,
109///     #[geekorm(unique)]
110///     pub username: String,
111/// }
112///
113/// let user = Users {
114///     id: PrimaryKey::from(1),
115///     username: String::from("JohnDoe")
116/// };
117/// # assert_eq!(Users::primary_key(), "id");
118/// # assert_eq!(user.id.clone(), PrimaryKey::from(1));
119/// # assert_eq!(user.username.clone(), String::from("JohnDoe"));
120/// ```
121#[derive(Clone, Copy, Eq, PartialEq)]
122pub struct PrimaryKey<T>
123where
124    T: serde::Serialize + 'static,
125{
126    pub(crate) value: T,
127}
128
129impl<T> PrimaryKey<T>
130where
131    T: serde::Serialize + 'static,
132{
133    /// Get the Primary Key value
134    pub fn value(&self) -> &T {
135        &self.value
136    }
137}
138
139impl<T> Debug for PrimaryKey<T>
140where
141    T: serde::Serialize + Debug + 'static,
142{
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        write!(f, "PrimaryKey({:?})", self.value)
145    }
146}
147
148impl<T> Display for PrimaryKey<T>
149where
150    T: serde::Serialize + Display + 'static,
151{
152    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
153        write!(f, "{}", self.value)
154    }
155}
156
157impl PrimaryKey<u64> {
158    /// Create a new primary key with an integer
159    pub fn new(value: u64) -> Self {
160        Self { value }
161    }
162}
163
164impl PrimaryKey<String> {
165    /// Create a new primary key with a String
166    pub fn new(value: String) -> Self {
167        Self { value }
168    }
169}
170
171/// Primary Key as an Integer (u64)
172///
173/// This is the default primary key type for GeekORM.
174///
175/// ```rust
176/// use geekorm::prelude::*;
177///
178/// #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
179/// pub struct Users {
180///     #[geekorm(primary_key, auto_increment)]
181///     pub id: PrimaryKeyInteger,
182///     #[geekorm(unique)]
183///     pub username: String,
184/// }
185///
186/// let user = Users {
187///     id: PrimaryKeyInteger::from(1),
188///     username: String::from("JohnDoe")
189/// };
190/// # assert_eq!(user.id.clone(), PrimaryKeyInteger::from(1));
191/// # assert_eq!(user.username.clone(), String::from("JohnDoe"));
192/// ```
193pub type PrimaryKeyInteger = PrimaryKey<u64>;
194
195impl Default for PrimaryKeyInteger {
196    fn default() -> Self {
197        PrimaryKey { value: 0 }
198    }
199}
200
201/// This is the old primary key type for GeekORM.
202///
203/// This is used for backwards compatibility.
204pub(crate) type PrimaryKeyIntegerOld = PrimaryKey<i32>;
205
206impl Default for PrimaryKeyIntegerOld {
207    fn default() -> Self {
208        PrimaryKey { value: 0 }
209    }
210}
211
212/// # Primary Key as a String
213///
214/// PrimaryKeyString (alias) is a Primary Key as a String type
215///
216/// # Example
217///
218/// ```rust
219/// use geekorm::prelude::*;
220///
221/// #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
222/// pub struct Users {
223///     pub id: PrimaryKeyString,
224///     pub username: String,
225/// }
226///
227/// let user = Users {
228///     id: PrimaryKeyString::from("1"),
229///     username: String::from("JohnDoe")
230/// };
231/// # assert_eq!(user.id.clone(), PrimaryKeyString::from("1"));
232/// # assert_eq!(user.username.clone(), String::from("JohnDoe"));
233/// ```
234pub type PrimaryKeyString = PrimaryKey<String>;
235
236impl Default for PrimaryKeyString {
237    fn default() -> Self {
238        PrimaryKey {
239            value: String::from(""),
240        }
241    }
242}
243
244/// PrimaryKeyUuid (alias) is a Primary Key as a Uuid type
245///
246/// Note: This requires the `uuid` feature to be enabled.
247///
248/// ```rust
249/// use geekorm::prelude::*;
250///
251/// #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)]
252/// pub struct Users {
253///     pub id: PrimaryKeyUuid,
254///     pub username: String,
255/// }
256///
257/// let new_uuid = uuid::Uuid::new_v4();
258/// let user = Users {
259///     id: PrimaryKeyUuid::from(new_uuid),
260///     username: String::from("JohnDoe")
261/// };
262/// # assert_eq!(user.username.clone(), String::from("JohnDoe"));
263/// # assert_eq!(user.id.clone(), PrimaryKeyUuid::from(new_uuid));
264/// ```
265#[cfg(feature = "uuid")]
266pub type PrimaryKeyUuid = PrimaryKey<Uuid>;
267
268#[cfg(feature = "uuid")]
269impl Default for PrimaryKeyUuid {
270    fn default() -> Self {
271        PrimaryKey {
272            value: Uuid::new_v4(),
273        }
274    }
275}
276
277#[cfg(feature = "uuid")]
278impl PrimaryKeyUuid {
279    /// Create a new primary key with a Uuid
280    pub fn new(value: Uuid) -> Self {
281        Self { value }
282    }
283}
284
285#[cfg(feature = "uuid")]
286impl From<Uuid> for PrimaryKeyUuid {
287    fn from(value: Uuid) -> Self {
288        PrimaryKeyUuid::new(value)
289    }
290}
291
292impl ToSqlite for PrimaryKey<String> {
293    fn on_create(&self, _query: &crate::QueryBuilder) -> Result<String, crate::Error> {
294        Ok(String::from("PRIMARY KEY"))
295    }
296}
297
298impl From<u64> for PrimaryKeyInteger {
299    fn from(value: u64) -> Self {
300        PrimaryKey { value }
301    }
302}
303impl From<i64> for PrimaryKeyInteger {
304    fn from(value: i64) -> Self {
305        PrimaryKey {
306            value: value as u64,
307        }
308    }
309}
310
311/// This is to make sure we are backwards compatible
312impl From<i32> for PrimaryKeyInteger {
313    fn from(value: i32) -> Self {
314        PrimaryKey {
315            value: value as u64,
316        }
317    }
318}
319impl From<u32> for PrimaryKeyInteger {
320    fn from(value: u32) -> Self {
321        PrimaryKey {
322            value: value as u64,
323        }
324    }
325}
326
327impl From<i32> for PrimaryKeyIntegerOld {
328    fn from(value: i32) -> Self {
329        PrimaryKey { value }
330    }
331}
332impl From<u32> for PrimaryKeyIntegerOld {
333    fn from(value: u32) -> Self {
334        PrimaryKey {
335            value: value as i32,
336        }
337    }
338}
339
340impl From<String> for PrimaryKeyInteger {
341    fn from(value: String) -> Self {
342        PrimaryKey {
343            value: value.parse().unwrap(),
344        }
345    }
346}
347
348impl From<&str> for PrimaryKeyInteger {
349    fn from(value: &str) -> Self {
350        PrimaryKey {
351            value: value.parse().unwrap(),
352        }
353    }
354}
355
356impl From<String> for PrimaryKey<String> {
357    fn from(value: String) -> Self {
358        PrimaryKey { value }
359    }
360}
361
362impl From<&String> for PrimaryKey<String> {
363    fn from(value: &String) -> Self {
364        PrimaryKey {
365            value: value.clone(),
366        }
367    }
368}
369
370impl From<&str> for PrimaryKey<String> {
371    fn from(value: &str) -> Self {
372        PrimaryKey {
373            value: String::from(value),
374        }
375    }
376}
377
378#[cfg(feature = "uuid")]
379impl From<String> for PrimaryKeyUuid {
380    fn from(value: String) -> Self {
381        PrimaryKeyUuid {
382            value: Uuid::parse_str(&value).unwrap(),
383        }
384    }
385}
386
387#[cfg(feature = "uuid")]
388impl From<&str> for PrimaryKeyUuid {
389    fn from(value: &str) -> Self {
390        PrimaryKeyUuid {
391            value: Uuid::parse_str(value).unwrap(),
392        }
393    }
394}
395
396impl From<PrimaryKey<String>> for String {
397    fn from(value: PrimaryKey<String>) -> Self {
398        value.value
399    }
400}
401
402impl From<PrimaryKeyInteger> for u64 {
403    fn from(value: PrimaryKeyInteger) -> Self {
404        value.value
405    }
406}
407/// This is to make sure we are backwards compatible
408impl From<PrimaryKeyInteger> for i32 {
409    fn from(value: PrimaryKeyInteger) -> Self {
410        value.value as i32
411    }
412}
413impl From<PrimaryKeyIntegerOld> for i32 {
414    fn from(value: PrimaryKeyIntegerOld) -> Self {
415        value.value
416    }
417}
418impl From<&PrimaryKeyIntegerOld> for i32 {
419    fn from(value: &PrimaryKeyIntegerOld) -> Self {
420        value.value
421    }
422}
423impl From<PrimaryKeyIntegerOld> for u64 {
424    fn from(value: PrimaryKeyIntegerOld) -> Self {
425        value.value as u64
426    }
427}
428impl From<&PrimaryKeyIntegerOld> for u64 {
429    fn from(value: &PrimaryKeyIntegerOld) -> Self {
430        value.value as u64
431    }
432}
433
434impl Serialize for PrimaryKeyInteger {
435    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
436    where
437        S: Serializer,
438    {
439        serializer.serialize_u64(self.value)
440    }
441}
442
443impl Serialize for PrimaryKey<i32> {
444    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
445    where
446        S: Serializer,
447    {
448        serializer.serialize_i32(self.value)
449    }
450}
451
452impl<'de> Deserialize<'de> for PrimaryKeyInteger {
453    fn deserialize<D>(deserializer: D) -> Result<PrimaryKeyInteger, D::Error>
454    where
455        D: serde::Deserializer<'de>,
456    {
457        struct PrimaryKeyVisitor;
458
459        impl<'de> Visitor<'de> for PrimaryKeyVisitor {
460            type Value = PrimaryKeyInteger;
461
462            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
463                formatter.write_str("an integer representing a primary key")
464            }
465
466            fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
467            where
468                E: serde::de::Error,
469            {
470                Ok(PrimaryKeyInteger::from(v))
471            }
472            fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
473            where
474                E: serde::de::Error,
475            {
476                Ok(PrimaryKeyInteger::from(v))
477            }
478
479            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
480            where
481                E: serde::de::Error,
482            {
483                Ok(PrimaryKeyInteger::from(v))
484            }
485
486            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
487            where
488                E: serde::de::Error,
489            {
490                Ok(PrimaryKeyInteger::from(v as u64))
491            }
492
493            fn visit_str<E>(self, value: &str) -> Result<PrimaryKeyInteger, E>
494            where
495                E: serde::de::Error,
496            {
497                match value.parse::<u64>() {
498                    Ok(value) => Ok(PrimaryKeyInteger::from(value)),
499                    Err(_) => Err(serde::de::Error::custom("Invalid integer value")),
500                }
501            }
502
503            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
504            where
505                E: serde::de::Error,
506            {
507                match v.parse::<u64>() {
508                    Ok(value) => Ok(PrimaryKeyInteger::from(value)),
509                    Err(_) => Err(serde::de::Error::custom("Invalid integer value")),
510                }
511            }
512        }
513
514        deserializer.deserialize_u64(PrimaryKeyVisitor)
515    }
516}
517
518/// For backwards compatibility
519impl<'de> Deserialize<'de> for PrimaryKeyIntegerOld {
520    fn deserialize<D>(deserializer: D) -> Result<PrimaryKeyIntegerOld, D::Error>
521    where
522        D: serde::Deserializer<'de>,
523    {
524        struct PrimaryKeyVisitor;
525
526        impl<'de> Visitor<'de> for PrimaryKeyVisitor {
527            type Value = PrimaryKeyIntegerOld;
528
529            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
530                formatter.write_str("an integer representing a primary key")
531            }
532
533            fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
534            where
535                E: serde::de::Error,
536            {
537                Ok(PrimaryKeyIntegerOld { value: v })
538            }
539            fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
540            where
541                E: serde::de::Error,
542            {
543                Ok(PrimaryKeyIntegerOld { value: v as i32 })
544            }
545
546            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
547            where
548                E: serde::de::Error,
549            {
550                Ok(PrimaryKeyIntegerOld { value: v as i32 })
551            }
552
553            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
554            where
555                E: serde::de::Error,
556            {
557                Ok(PrimaryKeyIntegerOld { value: v as i32 })
558            }
559
560            fn visit_str<E>(self, value: &str) -> Result<PrimaryKeyIntegerOld, E>
561            where
562                E: serde::de::Error,
563            {
564                match value.parse::<i32>() {
565                    Ok(value) => Ok(PrimaryKeyIntegerOld { value }),
566                    Err(_) => Err(serde::de::Error::custom("Invalid integer value")),
567                }
568            }
569
570            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
571            where
572                E: serde::de::Error,
573            {
574                match v.parse::<u64>() {
575                    Ok(value) => Ok(PrimaryKeyIntegerOld {
576                        value: value as i32,
577                    }),
578                    Err(_) => Err(serde::de::Error::custom("Invalid integer value")),
579                }
580            }
581        }
582
583        deserializer.deserialize_i32(PrimaryKeyVisitor)
584    }
585}
586
587impl Serialize for PrimaryKey<String> {
588    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
589    where
590        S: Serializer,
591    {
592        serializer.serialize_str(&self.value)
593    }
594}
595
596impl<'de> Deserialize<'de> for PrimaryKey<String> {
597    fn deserialize<D>(deserializer: D) -> Result<PrimaryKey<String>, D::Error>
598    where
599        D: serde::Deserializer<'de>,
600    {
601        struct PrimaryKeyVisitor;
602
603        impl<'de> Visitor<'de> for PrimaryKeyVisitor {
604            type Value = PrimaryKey<String>;
605
606            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
607                formatter.write_str("a string representing a primary key")
608            }
609
610            fn visit_str<E>(self, value: &str) -> Result<PrimaryKey<String>, E>
611            where
612                E: serde::de::Error,
613            {
614                Ok(PrimaryKey::from(value))
615            }
616            fn visit_string<E>(self, value: String) -> Result<PrimaryKey<String>, E>
617            where
618                E: serde::de::Error,
619            {
620                Ok(PrimaryKey::from(value))
621            }
622        }
623
624        deserializer.deserialize_str(PrimaryKeyVisitor)
625    }
626}
627
628#[cfg(feature = "uuid")]
629impl Serialize for PrimaryKey<Uuid> {
630    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
631    where
632        S: Serializer,
633    {
634        serializer.serialize_str(self.value.to_string().as_str())
635    }
636}
637
638#[cfg(feature = "uuid")]
639impl<'de> Deserialize<'de> for PrimaryKey<Uuid> {
640    fn deserialize<D>(deserializer: D) -> Result<PrimaryKeyUuid, D::Error>
641    where
642        D: serde::Deserializer<'de>,
643    {
644        struct PrimaryKeyVisitor;
645
646        impl<'de> Visitor<'de> for PrimaryKeyVisitor {
647            type Value = PrimaryKeyUuid;
648
649            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
650                formatter.write_str("a string representing a primary key")
651            }
652
653            fn visit_str<E>(self, value: &str) -> Result<PrimaryKeyUuid, E>
654            where
655                E: serde::de::Error,
656            {
657                Ok(PrimaryKey::from(value))
658            }
659            fn visit_string<E>(self, value: String) -> Result<PrimaryKeyUuid, E>
660            where
661                E: serde::de::Error,
662            {
663                Ok(PrimaryKey::from(value))
664            }
665        }
666
667        deserializer.deserialize_str(PrimaryKeyVisitor)
668    }
669}
670
671#[cfg(test)]
672mod tests {
673    use super::*;
674
675    #[test]
676    fn test_primary_key_string() {
677        let pk = PrimaryKey::<String>::new(String::from("1"));
678        let pk_json = serde_json::to_string(&pk).unwrap();
679        assert_eq!(pk_json, "\"1\"");
680
681        let pk_deserialized: PrimaryKey<String> = serde_json::from_str(&pk_json).unwrap();
682        assert_eq!(pk, pk_deserialized);
683    }
684
685    #[test]
686    fn test_primary_key_i32() {
687        let pk = PrimaryKeyInteger::new(1);
688        let pk_json = serde_json::to_string(&pk).unwrap();
689
690        assert_eq!(pk_json, "1");
691
692        let pk_deserialized: PrimaryKeyInteger = serde_json::from_str(&pk_json).unwrap();
693        assert_eq!(pk, pk_deserialized);
694    }
695
696    #[test]
697    #[cfg(feature = "uuid")]
698    fn test_primary_key_uuid() {
699        let id = Uuid::new_v4();
700
701        let pk = PrimaryKeyUuid::new(id);
702        let pk_json = serde_json::to_string(&pk).unwrap();
703
704        let pk_deserialized: PrimaryKeyUuid = serde_json::from_str(&pk_json).unwrap();
705        assert_eq!(pk, pk_deserialized);
706    }
707}