systemprompt_content/repository/content/
mod.rs1mod mutations;
8mod queries;
9
10use crate::error::ContentError;
11use crate::models::{Content, CreateContentParams, UpdateContentParams};
12use sqlx::PgPool;
13use std::sync::Arc;
14use systemprompt_database::DbPool;
15use systemprompt_identifiers::{CategoryId, ContentId, LocaleCode, SourceId};
16
17#[derive(Debug)]
18pub struct ContentRepository {
19 pool: Arc<PgPool>,
20 write_pool: Arc<PgPool>,
21}
22
23impl ContentRepository {
24 pub fn new(db: &DbPool) -> Result<Self, ContentError> {
25 let pool = db
26 .pool_arc()
27 .map_err(|e| ContentError::InvalidRequest(format!("Database pool error: {e}")))?;
28 let write_pool = db
29 .write_pool_arc()
30 .map_err(|e| ContentError::InvalidRequest(format!("Database write pool error: {e}")))?;
31 Ok(Self { pool, write_pool })
32 }
33
34 pub async fn create(&self, params: &CreateContentParams) -> Result<Content, sqlx::Error> {
35 mutations::create(&self.write_pool, params).await
36 }
37
38 pub async fn get_by_id(&self, id: &ContentId) -> Result<Option<Content>, sqlx::Error> {
39 queries::get_by_id(&self.pool, id).await
40 }
41
42 pub async fn get_by_slug(
43 &self,
44 slug: &str,
45 locale: &LocaleCode,
46 ) -> Result<Option<Content>, sqlx::Error> {
47 queries::get_by_slug(&self.pool, slug, locale).await
48 }
49
50 pub async fn get_by_source_and_slug(
51 &self,
52 source_id: &SourceId,
53 slug: &str,
54 locale: &LocaleCode,
55 ) -> Result<Option<Content>, sqlx::Error> {
56 queries::get_by_source_and_slug(&self.pool, source_id, slug, locale).await
57 }
58
59 pub async fn list(&self, limit: i64, offset: i64) -> Result<Vec<Content>, sqlx::Error> {
60 queries::list(&self.pool, limit, offset).await
61 }
62
63 pub async fn list_by_source(
64 &self,
65 source_id: &SourceId,
66 locale: &LocaleCode,
67 ) -> Result<Vec<Content>, sqlx::Error> {
68 queries::list_by_source(&self.pool, source_id, locale).await
69 }
70
71 pub async fn list_by_source_limited(
72 &self,
73 source_id: &SourceId,
74 locale: &LocaleCode,
75 limit: i64,
76 ) -> Result<Vec<Content>, sqlx::Error> {
77 queries::list_by_source_limited(&self.pool, source_id, locale, limit).await
78 }
79
80 pub async fn find_sources_by_slug(
81 &self,
82 slug: &str,
83 locale: &LocaleCode,
84 ) -> Result<Vec<SourceId>, sqlx::Error> {
85 queries::find_sources_by_slug(&self.pool, slug, locale).await
86 }
87
88 pub async fn list_slugs_with_locales_by_source(
89 &self,
90 source_id: &SourceId,
91 ) -> Result<Vec<(String, LocaleCode)>, sqlx::Error> {
92 queries::list_slugs_with_locales_by_source(&self.pool, source_id).await
93 }
94
95 pub async fn update(&self, params: &UpdateContentParams) -> Result<Content, sqlx::Error> {
96 mutations::update(&self.write_pool, params).await
97 }
98
99 pub async fn category_exists(&self, category_id: &CategoryId) -> Result<bool, sqlx::Error> {
100 queries::category_exists(&self.pool, category_id).await
101 }
102
103 pub async fn delete(&self, id: &ContentId) -> Result<(), sqlx::Error> {
104 mutations::delete(&self.write_pool, id).await
105 }
106
107 pub async fn delete_by_source(&self, source_id: &SourceId) -> Result<u64, sqlx::Error> {
108 mutations::delete_by_source(&self.write_pool, source_id).await
109 }
110
111 pub async fn list_all(&self, limit: i64, offset: i64) -> Result<Vec<Content>, sqlx::Error> {
112 queries::list_all(&self.pool, limit, offset).await
113 }
114
115 pub async fn get_popular_content_ids(
116 &self,
117 source_id: &SourceId,
118 days: i32,
119 limit: i64,
120 ) -> Result<Vec<ContentId>, sqlx::Error> {
121 queries::get_popular_content_ids(&self.pool, source_id, days, limit).await
122 }
123}