Skip to main content

soar_db/models/
metadata.rs

1use diesel::{prelude::*, sqlite::Sqlite};
2use serde_json::Value;
3
4use crate::{json_vec, models::types::PackageProvide, schema::metadata::*};
5
6#[derive(Debug, Clone, Selectable)]
7pub struct Package {
8    pub id: i32,
9    pub pkg_id: String,
10    pub pkg_name: String,
11    pub pkg_family: Option<String>,
12    pub pkg_type: Option<String>,
13    pub pkg_webpage: Option<String>,
14    pub app_id: Option<String>,
15    pub description: Option<String>,
16    pub version: String,
17    pub licenses: Option<Vec<String>>,
18    pub download_url: String,
19    pub size: Option<i64>,
20    pub ghcr_pkg: Option<String>,
21    pub ghcr_size: Option<i64>,
22    pub ghcr_blob: Option<String>,
23    pub ghcr_url: Option<String>,
24    pub bsum: Option<String>,
25    pub icon: Option<String>,
26    pub desktop: Option<String>,
27    pub appstream: Option<String>,
28    pub homepages: Option<Vec<String>>,
29    pub notes: Option<Vec<String>>,
30    pub source_urls: Option<Vec<String>>,
31    pub tags: Option<Vec<String>>,
32    pub categories: Option<Vec<String>>,
33    pub build_id: Option<String>,
34    pub build_date: Option<String>,
35    pub build_action: Option<String>,
36    pub build_script: Option<String>,
37    pub build_log: Option<String>,
38    pub provides: Option<Vec<PackageProvide>>,
39    pub snapshots: Option<Vec<String>>,
40    pub replaces: Option<Vec<String>>,
41    pub soar_syms: bool,
42    pub desktop_integration: Option<bool>,
43    pub portable: Option<bool>,
44}
45
46impl Queryable<packages::SqlType, Sqlite> for Package {
47    type Row = (
48        i32,
49        String,
50        String,
51        Option<String>,
52        Option<String>,
53        Option<String>,
54        Option<String>,
55        Option<String>,
56        String,
57        Option<Value>,
58        String,
59        Option<i64>,
60        Option<String>,
61        Option<i64>,
62        Option<String>,
63        Option<String>,
64        Option<String>,
65        Option<String>,
66        Option<String>,
67        Option<String>,
68        Option<Value>,
69        Option<Value>,
70        Option<Value>,
71        Option<Value>,
72        Option<Value>,
73        Option<String>,
74        Option<String>,
75        Option<String>,
76        Option<String>,
77        Option<String>,
78        Option<Value>,
79        Option<Value>,
80        Option<Value>,
81        bool,
82        Option<bool>,
83        Option<bool>,
84    );
85
86    fn build(row: Self::Row) -> diesel::deserialize::Result<Self> {
87        Ok(Self {
88            id: row.0,
89            pkg_id: row.1,
90            pkg_name: row.2,
91            pkg_family: row.3,
92            pkg_type: row.4,
93            pkg_webpage: row.5,
94            app_id: row.6,
95            description: row.7,
96            version: row.8,
97            licenses: json_vec!(row.9),
98            download_url: row.10,
99            size: row.11,
100            ghcr_pkg: row.12,
101            ghcr_size: row.13,
102            ghcr_blob: row.14,
103            ghcr_url: row.15,
104            bsum: row.16,
105            icon: row.17,
106            desktop: row.18,
107            appstream: row.19,
108            homepages: json_vec!(row.20),
109            notes: json_vec!(row.21),
110            source_urls: json_vec!(row.22),
111            tags: json_vec!(row.23),
112            categories: json_vec!(row.24),
113            build_id: row.25,
114            build_date: row.26,
115            build_action: row.27,
116            build_script: row.28,
117            build_log: row.29,
118            provides: json_vec!(row.30),
119            snapshots: json_vec!(row.31),
120            replaces: json_vec!(row.32),
121            soar_syms: row.33,
122            desktop_integration: row.34,
123            portable: row.35,
124        })
125    }
126}
127
128/// Lightweight package struct for listing operations.
129/// Contains only the fields needed for display, reducing memory usage significantly.
130#[derive(Debug, Clone, Queryable, Selectable)]
131#[diesel(table_name = packages)]
132#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
133pub struct PackageListing {
134    pub pkg_id: String,
135    pub pkg_name: String,
136    pub pkg_type: Option<String>,
137    pub version: String,
138}
139
140/// Minimal package data for fuzzy search candidate matching.
141/// Only fetches fields needed for matching, avoiding expensive JSON deserialization.
142#[derive(Debug, Clone, Queryable, Selectable)]
143#[diesel(table_name = packages)]
144#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
145pub struct FuzzyCandidate {
146    pub id: i32,
147    pub pkg_name: String,
148    pub pkg_id: String,
149    pub description: Option<String>,
150}
151
152/// Package with repository name attached.
153/// This is used when querying across multiple repositories.
154#[derive(Debug, Clone)]
155pub struct PackageWithRepo {
156    pub repo_name: String,
157    pub package: Package,
158}
159
160impl PackageWithRepo {
161    pub fn new(repo_name: String, package: Package) -> Self {
162        Self {
163            repo_name,
164            package,
165        }
166    }
167}
168
169#[derive(Debug, Queryable, Selectable)]
170#[diesel(table_name = maintainers)]
171#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
172pub struct Maintainer {
173    pub id: i32,
174    pub contact: String,
175    pub name: String,
176}
177
178#[derive(Debug, Queryable, Selectable)]
179#[diesel(table_name = package_maintainers)]
180#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
181pub struct PackageMaintainer {
182    pub maintainer_id: i32,
183    pub package_id: i32,
184}
185
186#[derive(Default, Insertable)]
187#[diesel(table_name = packages)]
188pub struct NewPackage<'a> {
189    pub pkg_id: &'a str,
190    pub pkg_name: &'a str,
191    pub pkg_family: Option<&'a str>,
192    pub pkg_type: Option<&'a str>,
193    pub pkg_webpage: Option<&'a str>,
194    pub app_id: Option<&'a str>,
195    pub description: Option<&'a str>,
196    pub version: &'a str,
197    pub licenses: Option<Value>,
198    pub download_url: &'a str,
199    pub size: Option<i64>,
200    pub ghcr_pkg: Option<&'a str>,
201    pub ghcr_size: Option<i64>,
202    pub ghcr_blob: Option<&'a str>,
203    pub ghcr_url: Option<&'a str>,
204    pub bsum: Option<&'a str>,
205    pub icon: Option<&'a str>,
206    pub desktop: Option<&'a str>,
207    pub appstream: Option<&'a str>,
208    pub homepages: Option<Value>,
209    pub notes: Option<Value>,
210    pub source_urls: Option<Value>,
211    pub tags: Option<Value>,
212    pub categories: Option<Value>,
213    pub build_id: Option<&'a str>,
214    pub build_date: Option<&'a str>,
215    pub build_action: Option<&'a str>,
216    pub build_script: Option<&'a str>,
217    pub build_log: Option<&'a str>,
218    pub provides: Option<Value>,
219    pub snapshots: Option<Value>,
220    pub replaces: Option<Value>,
221    pub soar_syms: bool,
222    pub desktop_integration: Option<bool>,
223    pub portable: Option<bool>,
224}
225
226#[derive(Default, Insertable)]
227#[diesel(table_name = maintainers)]
228pub struct NewMaintainer<'a> {
229    pub contact: &'a str,
230    pub name: &'a str,
231}
232
233#[derive(Default, Insertable)]
234#[diesel(table_name = package_maintainers)]
235pub struct NewPackageMaintainer {
236    pub maintainer_id: i32,
237    pub package_id: i32,
238}
239
240#[derive(Debug, Queryable, Selectable)]
241#[diesel(table_name = repository)]
242#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
243pub struct Repository {
244    pub rowid: i32,
245    pub name: String,
246    pub etag: String,
247}
248
249#[derive(Default, Insertable)]
250#[diesel(table_name = repository)]
251pub struct NewRepository<'a> {
252    pub name: &'a str,
253    pub etag: &'a str,
254}