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

ambee/giterated

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

Giterated Stack `ObjectValue` and `Setting` refactor.

This refactor adds value and setting update events, as well as value getters. Additionally, the stack is now the owner of the ability to write settings into storage. This is accomplished with the `MetadataProvider` trait. This sets up the ground work for push federation, cache, and basically everything else. commit 7befc583cb3e0c6719506c550ed66ac76293413c Author: Amber <[email protected]> Date: Fri Sep 29 15:46:48 2023 -0500 Finish value and settings refactor in the stack. commit 3ac09994a0caafd1a0b95d9a781c7f202f20e75b Author: Amber <[email protected]> Date: Fri Sep 29 09:46:32 2023 -0500 Add set_setting handling back in commit 84fd31e3eae85d98fa68a28b333dbb32cde3bdb8 Author: Amber <[email protected]> Date: Wed Sep 27 06:36:31 2023 -0500 Remove some allocations from meta types commit 16c310ce3680c4a14ed35083b6a230aaecd43152 Author: Amber <[email protected]> Date: Wed Sep 27 05:35:03 2023 -0500 Add cargo metadata commit eb2520a20001bac7b21c6c3d34f62db32f0ada80 Author: Amber <[email protected]> Date: Wed Sep 27 05:26:27 2023 -0500 Refactor setting and value management to use the unified stack. Allows for tight management, inspection, and eventing of setting and value management. commit 901fe103da0fce4b40f33b0a8b64404049ae03cf Author: Amber <[email protected]> Date: Wed Sep 27 02:38:33 2023 -0500 Set up ground work for value / settings refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c377e4d

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨18471⁩ bytes
Raw
1 use std::sync::Arc;
2
3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 use giterated_models::{
5 authenticated::UserAuthenticationToken,
6 error::{
7 GetValueError, InstanceError, IntoInternalError, OperationError, RepositoryError, UserError,
8 },
9 instance::{
10 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
11 },
12 object_backend::ObjectBackend,
13 repository::{
14 Commit, DefaultBranch, Description, LatestCommit, Repository, RepositoryBranch,
15 RepositoryBranchesRequest, RepositoryCommitBeforeRequest, RepositoryCommitFromIdRequest,
16 RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile,
17 RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest,
18 RepositoryInfoRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics,
19 RepositoryStatisticsRequest, RepositorySummary, RepositoryView, Visibility,
20 },
21 settings::{GetSetting, GetSettingError},
22 user::{Bio, DisplayName, User, UserRepositoriesRequest},
23 value::{AnyValue, GetValueTyped},
24 };
25 use giterated_stack::{AuthenticatedUser, AuthorizedInstance, GiteratedStack, StackOperationState};
26 use serde_json::Value;
27
28 use super::DatabaseBackend;
29
30 pub fn user_get_repositories(
31 object: &User,
32 _operation: UserRepositoriesRequest,
33 state: DatabaseBackend,
34 _operation_state: StackOperationState,
35 requester: Option<AuthenticatedUser>,
36 ) -> LocalBoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
37 let object = object.clone();
38
39 async move {
40 let mut user_backend = state.user_backend.lock().await;
41 let repositories_response = user_backend
42 .repositories_for_user(&requester, &object)
43 .await
44 .as_internal_error()?;
45 drop(user_backend);
46 let mut repositories_backend = state.repository_backend.lock().await;
47
48 let mut repositories = vec![];
49
50 for repository in repositories_response {
51 if repositories_backend
52 .exists(&requester, &repository.repository)
53 .await
54 .as_internal_error()?
55 {
56 repositories.push(repository);
57 }
58 }
59
60 Ok(repositories)
61 }
62 .boxed_local()
63 }
64
65 pub fn user_get_value(
66 object: &User,
67 operation: GetValueTyped<AnyValue<User>>,
68 state: DatabaseBackend,
69 ) -> LocalBoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
70 let object = object.clone();
71
72 async move {
73 let mut user_backend = state.user_backend.lock().await;
74 let value = user_backend
75 .get_value(&object, &operation.value_name)
76 .await
77 .as_internal_error()?;
78
79 Ok(value)
80 }
81 .boxed_local()
82 }
83
84 pub fn user_get_setting(
85 object: &User,
86 operation: GetSetting,
87 state: DatabaseBackend,
88 ) -> LocalBoxFuture<'static, Result<Value, OperationError<GetSettingError>>> {
89 let object = object.clone();
90
91 async move {
92 let mut user_backend = state.user_backend.lock().await;
93 let value = user_backend
94 .get_setting(&object, &operation.setting_name)
95 .await
96 .as_internal_error()?;
97
98 Ok(value.0)
99 }
100 .boxed_local()
101 }
102
103 pub fn repository_info(
104 object: &Repository,
105 operation: RepositoryInfoRequest,
106 state: DatabaseBackend,
107 operation_state: StackOperationState,
108 backend: Arc<GiteratedStack>,
109 requester: Option<AuthenticatedUser>,
110 ) -> LocalBoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
111 let object = object.clone();
112
113 async move {
114 let mut object = backend
115 .get_object::<Repository>(&object.to_string(), &operation_state)
116 .await
117 .unwrap();
118 let mut repository_backend = state.repository_backend.lock().await;
119 let tree = repository_backend
120 .repository_file_inspect(
121 &requester,
122 object.object(),
123 &RepositoryFileInspectRequest {
124 extra_metadata: operation.extra_metadata,
125 path: operation.path,
126 rev: operation.rev.clone(),
127 },
128 )
129 .await
130 .as_internal_error()?;
131
132 let statistics = repository_backend
133 .repository_get_statistics(
134 &requester,
135 object.object(),
136 &RepositoryStatisticsRequest {
137 rev: operation.rev.clone(),
138 },
139 )
140 .await
141 .as_internal_error()?;
142 drop(repository_backend);
143
144 let info = RepositoryView {
145 name: object.object().name.clone(),
146 owner: object.object().owner.clone(),
147 description: object.get::<Description>(&operation_state).await.ok(),
148 visibility: object
149 .get::<Visibility>(&operation_state)
150 .await
151 .as_internal_error()?,
152 default_branch: object
153 .get::<DefaultBranch>(&operation_state)
154 .await
155 .as_internal_error()?,
156 // 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.
157 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
158 stats: statistics,
159 tree_rev: operation.rev,
160 tree,
161 };
162
163 Ok(info)
164 }
165 .boxed_local()
166 }
167
168 pub fn repository_get_statistics(
169 object: &Repository,
170 operation: RepositoryStatisticsRequest,
171 state: DatabaseBackend,
172 operation_state: StackOperationState,
173 backend: Arc<GiteratedStack>,
174 requester: Option<AuthenticatedUser>,
175 ) -> LocalBoxFuture<'static, Result<RepositoryStatistics, OperationError<RepositoryError>>> {
176 let object = object.clone();
177
178 async move {
179 let object = backend
180 .get_object::<Repository>(&object.to_string(), &operation_state)
181 .await
182 .unwrap();
183
184 let mut repository_backend = state.repository_backend.lock().await;
185 let statistics = repository_backend
186 .repository_get_statistics(
187 &requester,
188 object.object(),
189 &RepositoryStatisticsRequest { rev: operation.rev },
190 )
191 .await
192 .as_internal_error()?;
193 drop(repository_backend);
194
195 Ok(statistics)
196 }
197 .boxed_local()
198 }
199
200 pub fn repository_get_branches(
201 object: &Repository,
202 operation: RepositoryBranchesRequest,
203 state: DatabaseBackend,
204 operation_state: StackOperationState,
205 backend: Arc<GiteratedStack>,
206 requester: Option<AuthenticatedUser>,
207 ) -> LocalBoxFuture<'static, Result<Vec<RepositoryBranch>, OperationError<RepositoryError>>> {
208 let object = object.clone();
209
210 async move {
211 let object = backend
212 .get_object::<Repository>(&object.to_string(), &operation_state)
213 .await
214 .unwrap();
215
216 let mut repository_backend = state.repository_backend.lock().await;
217 let branches = repository_backend
218 .repository_get_branches(&requester, object.object(), &operation)
219 .await
220 .as_internal_error()?;
221 drop(repository_backend);
222
223 Ok(branches)
224 }
225 .boxed_local()
226 }
227
228 pub fn repository_file_from_id(
229 object: &Repository,
230 operation: RepositoryFileFromIdRequest,
231 state: DatabaseBackend,
232 operation_state: StackOperationState,
233 backend: Arc<GiteratedStack>,
234
235 requester: Option<AuthenticatedUser>,
236 ) -> LocalBoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
237 let object = object.clone();
238
239 async move {
240 let object = backend
241 .get_object::<Repository>(&object.to_string(), &operation_state)
242 .await
243 .unwrap();
244
245 let mut repository_backend = state.repository_backend.lock().await;
246 let file = repository_backend
247 .repository_file_from_id(
248 &requester,
249 object.object(),
250 &RepositoryFileFromIdRequest(operation.0),
251 )
252 .await
253 .as_internal_error()?;
254 drop(repository_backend);
255
256 Ok(file)
257 }
258 .boxed_local()
259 }
260
261 pub fn repository_file_from_path(
262 object: &Repository,
263 operation: RepositoryFileFromPathRequest,
264 state: DatabaseBackend,
265 operation_state: StackOperationState,
266 backend: Arc<GiteratedStack>,
267 requester: Option<AuthenticatedUser>,
268 ) -> LocalBoxFuture<'static, Result<(RepositoryFile, String), OperationError<RepositoryError>>> {
269 let object = object.clone();
270
271 async move {
272 let object = backend
273 .get_object::<Repository>(&object.to_string(), &operation_state)
274 .await
275 .unwrap();
276
277 let mut repository_backend = state.repository_backend.lock().await;
278 let file = repository_backend
279 .repository_file_from_path(
280 &requester,
281 object.object(),
282 &RepositoryFileFromPathRequest {
283 rev: operation.rev,
284 path: operation.path,
285 },
286 )
287 .await
288 .as_internal_error()?;
289 drop(repository_backend);
290
291 Ok(file)
292 }
293 .boxed_local()
294 }
295
296 pub fn repository_last_commit_of_file(
297 object: &Repository,
298 operation: RepositoryLastCommitOfFileRequest,
299 state: DatabaseBackend,
300 operation_state: StackOperationState,
301 backend: Arc<GiteratedStack>,
302 requester: Option<AuthenticatedUser>,
303 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
304 let object = object.clone();
305
306 async move {
307 let object = backend
308 .get_object::<Repository>(&object.to_string(), &operation_state)
309 .await
310 .unwrap();
311
312 let mut repository_backend = state.repository_backend.lock().await;
313 let commit = repository_backend
314 .repository_last_commit_of_file(
315 &requester,
316 object.object(),
317 &RepositoryLastCommitOfFileRequest {
318 start_commit: operation.start_commit,
319 path: operation.path,
320 },
321 )
322 .await
323 .as_internal_error()?;
324 drop(repository_backend);
325
326 Ok(commit)
327 }
328 .boxed_local()
329 }
330
331 pub fn repository_commit_by_id(
332 object: &Repository,
333 operation: RepositoryCommitFromIdRequest,
334 state: DatabaseBackend,
335 operation_state: StackOperationState,
336 backend: Arc<GiteratedStack>,
337 requester: Option<AuthenticatedUser>,
338 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
339 let object = object.clone();
340
341 async move {
342 let object = backend
343 .get_object::<Repository>(&object.to_string(), &operation_state)
344 .await
345 .unwrap();
346
347 let mut repository_backend = state.repository_backend.lock().await;
348 let commit = repository_backend
349 .repository_commit_from_id(
350 &requester,
351 object.object(),
352 &RepositoryCommitFromIdRequest(operation.0),
353 )
354 .await
355 .as_internal_error()?;
356 drop(repository_backend);
357
358 Ok(commit)
359 }
360 .boxed_local()
361 }
362
363 pub fn repository_diff(
364 object: &Repository,
365 operation: RepositoryDiffRequest,
366 state: DatabaseBackend,
367 operation_state: StackOperationState,
368 backend: Arc<GiteratedStack>,
369 requester: Option<AuthenticatedUser>,
370 ) -> LocalBoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
371 let object = object.clone();
372
373 async move {
374 let object = backend
375 .get_object::<Repository>(&object.to_string(), &operation_state)
376 .await
377 .unwrap();
378
379 let mut repository_backend = state.repository_backend.lock().await;
380 let diff = repository_backend
381 .repository_diff(&requester, object.object(), &operation)
382 .await
383 .as_internal_error()?;
384 drop(repository_backend);
385
386 Ok(diff)
387 }
388 .boxed_local()
389 }
390
391 pub fn repository_diff_patch(
392 object: &Repository,
393 operation: RepositoryDiffPatchRequest,
394 state: DatabaseBackend,
395 operation_state: StackOperationState,
396 backend: Arc<GiteratedStack>,
397 requester: Option<AuthenticatedUser>,
398 ) -> LocalBoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
399 let object = object.clone();
400
401 async move {
402 let object = backend
403 .get_object::<Repository>(&object.to_string(), &operation_state)
404 .await
405 .unwrap();
406
407 let mut repository_backend = state.repository_backend.lock().await;
408 let patch = repository_backend
409 .repository_diff_patch(&requester, object.object(), &operation)
410 .await
411 .as_internal_error()?;
412 drop(repository_backend);
413
414 Ok(patch)
415 }
416 .boxed_local()
417 }
418
419 pub fn repository_commit_before(
420 object: &Repository,
421 operation: RepositoryCommitBeforeRequest,
422 state: DatabaseBackend,
423 operation_state: StackOperationState,
424 backend: Arc<GiteratedStack>,
425 requester: Option<AuthenticatedUser>,
426 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
427 let object = object.clone();
428
429 async move {
430 let object = backend
431 .get_object::<Repository>(&object.to_string(), &operation_state)
432 .await
433 .unwrap();
434
435 let mut repository_backend = state.repository_backend.lock().await;
436 let file = repository_backend
437 .repository_commit_before(&requester, object.object(), &operation)
438 .await
439 .as_internal_error()?;
440 drop(repository_backend);
441
442 Ok(file)
443 }
444 .boxed_local()
445 }
446
447 pub fn instance_authentication_request(
448 object: &Instance,
449 operation: AuthenticationTokenRequest,
450 state: DatabaseBackend,
451 // Authorizes the request for SAME-INSTANCE
452 _authorized_instance: AuthorizedInstance,
453 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
454 let object = object.clone();
455 async move {
456 let mut backend = state.user_backend.lock().await;
457
458 backend.login(&object, operation).await.as_internal_error()
459 }
460 .boxed_local()
461 }
462
463 pub fn instance_registration_request(
464 _object: &Instance,
465 operation: RegisterAccountRequest,
466 state: DatabaseBackend,
467 // Authorizes the request for SAME-INSTANCE
468 _authorized_instance: AuthorizedInstance,
469 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
470 async move {
471 let mut backend = state.user_backend.lock().await;
472
473 backend.register(operation).await.as_internal_error()
474 }
475 .boxed_local()
476 }
477
478 pub fn instance_create_repository_request(
479 _object: &Instance,
480 operation: RepositoryCreateRequest,
481 state: DatabaseBackend,
482 requester: AuthenticatedUser,
483 // Authorizes the request for SAME-INSTANCE
484 _authorized_instance: AuthorizedInstance,
485 ) -> LocalBoxFuture<'static, Result<Repository, OperationError<InstanceError>>> {
486 async move {
487 let mut backend = state.repository_backend.lock().await;
488
489 backend
490 .create_repository(&requester, &operation)
491 .await
492 .as_internal_error()
493 }
494 .boxed_local()
495 }
496
497 pub fn user_get_value_display_name(
498 object: &User,
499 _operation: GetValueTyped<DisplayName>,
500 _state: DatabaseBackend,
501 stack: Arc<GiteratedStack>, // _requester: AuthorizedUser,
502 ) -> LocalBoxFuture<'static, Result<DisplayName, OperationError<GetValueError>>> {
503 let object = object.clone();
504
505 async move {
506 stack
507 .new_get_setting::<_, DisplayName>(&object)
508 .await
509 .as_internal_error()
510 }
511 .boxed_local()
512 }
513
514 pub fn user_get_value_bio(
515 object: &User,
516 _operation: GetValueTyped<Bio>,
517 _state: DatabaseBackend,
518 stack: Arc<GiteratedStack>,
519 ) -> LocalBoxFuture<'static, Result<Bio, OperationError<GetValueError>>> {
520 let object = object.clone();
521
522 async move {
523 stack
524 .new_get_setting::<_, Bio>(&object)
525 .await
526 .as_internal_error()
527 }
528 .boxed_local()
529 }
530
531 pub fn repository_get_value_description(
532 object: &Repository,
533 _operation: GetValueTyped<Description>,
534 _state: DatabaseBackend,
535 stack: Arc<GiteratedStack>,
536 ) -> LocalBoxFuture<'static, Result<Description, OperationError<GetValueError>>> {
537 let object = object.clone();
538
539 async move {
540 stack
541 .new_get_setting::<_, Description>(&object)
542 .await
543 .as_internal_error()
544 }
545 .boxed_local()
546 }
547
548 pub fn repository_get_value_visibility(
549 object: &Repository,
550 _operation: GetValueTyped<Visibility>,
551 _state: DatabaseBackend,
552 stack: Arc<GiteratedStack>,
553 ) -> LocalBoxFuture<'static, Result<Visibility, OperationError<GetValueError>>> {
554 let object = object.clone();
555
556 async move {
557 stack
558 .new_get_setting::<_, Visibility>(&object)
559 .await
560 .as_internal_error()
561 }
562 .boxed_local()
563 }
564
565 pub fn repository_get_default_branch(
566 object: &Repository,
567 _operation: GetValueTyped<DefaultBranch>,
568 _state: DatabaseBackend,
569 stack: Arc<GiteratedStack>,
570 ) -> LocalBoxFuture<'static, Result<DefaultBranch, OperationError<GetValueError>>> {
571 let object = object.clone();
572
573 async move {
574 stack
575 .new_get_setting::<_, DefaultBranch>(&object)
576 .await
577 .as_internal_error()
578 }
579 .boxed_local()
580 }
581
582 pub fn repository_get_latest_commit(
583 object: &Repository,
584 _operation: GetValueTyped<LatestCommit>,
585 state: DatabaseBackend,
586 _stack: Arc<GiteratedStack>,
587 ) -> LocalBoxFuture<'static, Result<LatestCommit, OperationError<GetValueError>>> {
588 let _object = object.clone();
589
590 async move {
591 let _backend = state.repository_backend.lock().await;
592
593 // stack
594 // .new_get_setting::<_, LatestCommit>(&*object)
595 // .await
596 // .as_internal_error()
597
598 todo!()
599 }
600 .boxed_local()
601 }
602