teamcraft/services/
mod.rs1pub mod access;
8pub mod access_log;
9pub mod access_review;
10pub mod annotations;
11pub mod as_built;
12pub mod assemblies;
13pub mod assistant;
14pub mod assistant_threads;
15pub mod attributes;
16pub mod audit;
17pub mod bom;
18pub mod bom_compare;
19pub mod bom_references;
20pub mod branding;
21pub mod bulk;
22pub mod changes;
23pub mod checkouts;
24pub mod deactivation;
25pub mod desktop;
26pub mod duplicates;
27pub mod explorer;
28pub mod files;
29pub mod folders;
30pub mod impacts;
31pub mod imports;
32pub mod insights;
33pub mod interchange;
34pub mod items;
35pub mod manager_gaps;
36pub mod mass_geometry;
37pub mod mass_properties;
38pub mod membership_conditions;
39pub mod notifications;
40pub mod offboarding;
41pub mod ownership;
42pub mod package;
43pub mod personal;
44pub mod project_policy;
45pub mod projects;
46pub mod quotas;
47pub mod readiness;
48pub mod references;
49pub mod request_digests;
50pub mod requests;
51pub mod result_proposals;
52pub mod result_templates;
53pub mod retention;
54pub mod reviewers;
55pub mod revisions;
56pub mod save_as;
57pub mod season;
58pub mod similar;
59pub mod simulations;
60pub mod stats;
61pub mod structure;
62pub mod uploads;
63pub mod users;
64pub mod webhooks;
65pub mod workset;
66
67use sqlx::PgConnection;
68
69use crate::error::AppResult;
70
71pub(crate) async fn next_counter(conn: &mut PgConnection, name: &str) -> AppResult<i64> {
73 let value = sqlx::query_scalar::<_, i64>(
74 "INSERT INTO counters (name, value) VALUES ($1, 1)
75 ON CONFLICT (name) DO UPDATE SET value = counters.value + 1
76 RETURNING value",
77 )
78 .bind(name)
79 .fetch_one(&mut *conn)
80 .await?;
81 Ok(value)
82}
83
84#[derive(Clone, Copy, Debug)]
86pub struct Page {
87 pub limit: i64,
88 pub offset: i64,
89}
90
91impl Page {
92 pub const DEFAULT_LIMIT: i64 = 50;
93 pub const MAX_LIMIT: i64 = 500;
94
95 pub fn new(limit: Option<i64>, offset: Option<i64>) -> Self {
96 Page {
97 limit: limit
98 .unwrap_or(Self::DEFAULT_LIMIT)
99 .clamp(1, Self::MAX_LIMIT),
100 offset: offset.unwrap_or(0).max(0),
101 }
102 }
103
104 pub fn from_page_number(page: Option<i64>, per_page: i64) -> Self {
106 let page = page.unwrap_or(1).max(1);
107 Page {
108 limit: per_page,
109 offset: (page - 1) * per_page,
110 }
111 }
112}