JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Experimental repository diff structure

erremilia - ⁨2⁩ years ago

parent: tbd commit: ⁨0ef533d

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨11207⁩ bytes
Raw
1 use std::error::Error;
2
3 use futures_util::{future::BoxFuture, FutureExt};
4 use giterated_models::{
5 authenticated::UserAuthenticationToken,
6 error::{GetValueError, InstanceError, OperationError, RepositoryError, UserError},
7 instance::{AuthenticationTokenRequest, Instance, RegisterAccountRequest},
8 object_backend::ObjectBackend,
9 repository::{
10 Commit, DefaultBranch, Description, LatestCommit, Repository,
11 RepositoryCommitBeforeRequest, RepositoryDiff, RepositoryDiffRequest, RepositoryFile,
12 RepositoryFileFromIdRequest, RepositoryFileInspectRequest, RepositoryInfoRequest,
13 RepositorySummary, RepositoryView, Visibility, RepositoryDiffPatchRequest,
14 },
15 settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError},
16 user::{User, UserRepositoriesRequest},
17 value::{AnyValue, GetValue},
18 };
19 use giterated_stack::{BackendWrapper, StackOperationState};
20
21 use super::DatabaseBackend;
22
23 pub fn user_get_repositories(
24 object: &User,
25 _operation: UserRepositoriesRequest,
26 state: DatabaseBackend,
27 ) -> BoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
28 let object = object.clone();
29
30 async move {
31 let mut user_backend = state.user_backend.lock().await;
32 let repositories = user_backend
33 .repositories_for_user(None, &object)
34 .await
35 .map_err(|e| OperationError::Internal(e.to_string()))?;
36
37 Ok(repositories)
38 }
39 .boxed()
40 }
41
42 pub fn user_get_value(
43 object: &User,
44 operation: GetValue<AnyValue<User>>,
45 state: DatabaseBackend,
46 ) -> BoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
47 let object = object.clone();
48
49 async move {
50 let mut user_backend = state.user_backend.lock().await;
51 let value = user_backend
52 .get_value(&object, &operation.value_name)
53 .await
54 .map_err(|e| OperationError::Internal(e.to_string()))?;
55
56 Ok(value)
57 }
58 .boxed()
59 }
60
61 pub fn user_get_setting(
62 object: &User,
63 operation: GetSetting<AnySetting>,
64 state: DatabaseBackend,
65 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
66 let object = object.clone();
67
68 async move {
69 let mut user_backend = state.user_backend.lock().await;
70 let value = user_backend
71 .get_setting(&object, &operation.setting_name)
72 .await
73 .map_err(|e| OperationError::Internal(e.to_string()))?;
74
75 Ok(value)
76 }
77 .boxed()
78 }
79
80 pub fn user_set_setting(
81 object: &User,
82 operation: SetSetting<AnySetting>,
83 state: DatabaseBackend,
84 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
85 let object = object.clone();
86
87 async move {
88 let mut user_backend = state.user_backend.lock().await;
89 let value = user_backend
90 .write_setting(&object, &operation.setting_name, &operation.value.0)
91 .await
92 .map_err(|e| OperationError::Internal(e.to_string()))?;
93
94 Ok(value)
95 }
96 .boxed()
97 }
98
99 pub fn repository_info(
100 object: &Repository,
101 operation: RepositoryInfoRequest,
102 state: DatabaseBackend,
103 operation_state: StackOperationState,
104 backend: BackendWrapper,
105 ) -> BoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
106 let object = object.clone();
107
108 async move {
109 let mut object = backend
110 .get_object::<Repository>(&object.to_string(), &operation_state)
111 .await
112 .unwrap();
113
114 let mut repository_backend = state.repository_backend.lock().await;
115 let tree = repository_backend
116 .repository_file_inspect(
117 None,
118 object.object(),
119 &RepositoryFileInspectRequest {
120 extra_metadata: operation.extra_metadata,
121 path: operation.path,
122 rev: operation.rev.clone(),
123 },
124 )
125 .await
126 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
127 drop(repository_backend);
128
129 let info = RepositoryView {
130 name: object.object().name.clone(),
131 owner: object.object().owner.clone(),
132 description: object.get::<Description>(&operation_state).await.ok(),
133 visibility: object
134 .get::<Visibility>(&operation_state)
135 .await
136 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
137 default_branch: object
138 .get::<DefaultBranch>(&operation_state)
139 .await
140 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
141 // TODO: Can't be a simple get function, this needs to be returned alongside the tree as this differs depending on the rev and path.
142 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
143 tree_rev: operation.rev,
144 tree,
145 };
146
147 Ok(info)
148 }
149 .boxed()
150 }
151
152 pub fn repository_file_from_id(
153 object: &Repository,
154 operation: RepositoryFileFromIdRequest,
155 state: DatabaseBackend,
156 operation_state: StackOperationState,
157 backend: BackendWrapper,
158 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
159 let object = object.clone();
160
161 async move {
162 let object = backend
163 .get_object::<Repository>(&object.to_string(), &operation_state)
164 .await
165 .unwrap();
166
167 let mut repository_backend = state.repository_backend.lock().await;
168 let file = repository_backend
169 .repository_file_from_id(
170 None,
171 object.object(),
172 &RepositoryFileFromIdRequest(operation.0),
173 )
174 .await
175 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
176 drop(repository_backend);
177
178 Ok(file)
179 }
180 .boxed()
181 }
182
183 pub fn repository_diff(
184 object: &Repository,
185 operation: RepositoryDiffRequest,
186 state: DatabaseBackend,
187 operation_state: StackOperationState,
188 backend: BackendWrapper,
189 ) -> BoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
190 let object = object.clone();
191
192 async move {
193 let object = backend
194 .get_object::<Repository>(&object.to_string(), &operation_state)
195 .await
196 .unwrap();
197
198 let mut repository_backend = state.repository_backend.lock().await;
199 let diff = repository_backend
200 .repository_diff(None, object.object(), &operation)
201 .await
202 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
203 drop(repository_backend);
204
205 Ok(diff)
206 }
207 .boxed()
208 }
209
210 pub fn repository_diff_patch(
211 object: &Repository,
212 operation: RepositoryDiffPatchRequest,
213 state: DatabaseBackend,
214 operation_state: StackOperationState,
215 backend: BackendWrapper,
216 ) -> BoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
217 let object = object.clone();
218
219 async move {
220 let object = backend
221 .get_object::<Repository>(&object.to_string(), &operation_state)
222 .await
223 .unwrap();
224
225 let mut repository_backend = state.repository_backend.lock().await;
226 let patch = repository_backend
227 .repository_diff_patch(None, object.object(), &operation)
228 .await
229 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
230 drop(repository_backend);
231
232 Ok(patch)
233 }
234 .boxed()
235 }
236
237 pub fn repository_commit_before(
238 object: &Repository,
239 operation: RepositoryCommitBeforeRequest,
240 state: DatabaseBackend,
241 operation_state: StackOperationState,
242 backend: BackendWrapper,
243 ) -> BoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
244 let object = object.clone();
245
246 async move {
247 let object = backend
248 .get_object::<Repository>(&object.to_string(), &operation_state)
249 .await
250 .unwrap();
251
252 let mut repository_backend = state.repository_backend.lock().await;
253 let file = repository_backend
254 .repository_commit_before(None, object.object(), &operation)
255 .await
256 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
257 drop(repository_backend);
258
259 Ok(file)
260 }
261 .boxed()
262 }
263
264 pub fn repository_get_value(
265 object: &Repository,
266 operation: GetValue<AnyValue<Repository>>,
267 state: DatabaseBackend,
268 ) -> BoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
269 let object = object.clone();
270
271 async move {
272 let mut repository_backend = state.repository_backend.lock().await;
273 let value = repository_backend
274 .get_value(&object, &operation.value_name)
275 .await
276 .map_err(|e| {
277 OperationError::Internal(format!("error getting value: {}", e.to_string()))
278 })?;
279
280 Ok(value)
281 }
282 .boxed()
283 }
284
285 pub fn repository_get_setting(
286 object: &Repository,
287 operation: GetSetting<AnySetting>,
288 state: DatabaseBackend,
289 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
290 let object = object.clone();
291
292 async move {
293 let mut repository_backend = state.repository_backend.lock().await;
294 let value = repository_backend
295 .get_setting(&object, &operation.setting_name)
296 .await
297 .map_err(|e| OperationError::Internal(e.to_string()))?;
298
299 Ok(value)
300 }
301 .boxed()
302 }
303
304 pub fn repository_set_setting(
305 object: &Repository,
306 operation: SetSetting<AnySetting>,
307 state: DatabaseBackend,
308 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
309 let object = object.clone();
310
311 async move {
312 let mut repository_backend = state.repository_backend.lock().await;
313 let value = repository_backend
314 .write_setting(&object, &operation.setting_name, &operation.value.0)
315 .await
316 .map_err(|e| OperationError::Internal(e.to_string()))?;
317
318 Ok(value)
319 }
320 .boxed()
321 }
322
323 pub fn instance_authentication_request(
324 object: &Instance,
325 operation: AuthenticationTokenRequest,
326 state: DatabaseBackend,
327 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
328 let object = object.clone();
329 async move {
330 let mut backend = state.user_backend.lock().await;
331
332 backend
333 .login(&object, operation)
334 .await
335 .map_err(|e| OperationError::Internal(e.to_string()))
336 }
337 .boxed()
338 }
339
340 pub fn instance_registration_request(
341 _object: &Instance,
342 operation: RegisterAccountRequest,
343 state: DatabaseBackend,
344 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
345 async move {
346 let mut backend = state.user_backend.lock().await;
347
348 backend
349 .register(operation)
350 .await
351 .map_err(|e| OperationError::Internal(e.to_string()))
352 }
353 .boxed()
354 }
355