use std::sync::Arc; use giterated_models::{ authenticated::UserAuthenticationToken, error::{InstanceError, IntoInternalError, OperationError, RepositoryError, UserError}, instance::{ AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest, }, object_backend::ObjectBackend, repository::{ Commit, DefaultBranch, Description, LatestCommit, Repository, RepositoryBranch, RepositoryBranchesRequest, RepositoryCommitBeforeRequest, RepositoryCommitFromIdRequest, RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryInfoRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics, RepositoryStatisticsRequest, RepositorySummary, RepositoryView, Visibility, }, user::{User, UserRepositoriesRequest}, }; use giterated_stack::{AuthenticatedUser, GiteratedStack, StackOperationState}; use super::DatabaseBackend; pub async fn user_get_repositories( object: User, _operation: UserRepositoriesRequest, state: DatabaseBackend, _operation_state: StackOperationState, requester: Option, ) -> Result, OperationError> { let object = object.clone(); let mut user_backend = state.user_backend.lock().await; let repositories_response = user_backend .repositories_for_user(&requester, &object) .await .as_internal_error()?; drop(user_backend); let mut repositories_backend = state.repository_backend.lock().await; let mut repositories = vec![]; for repository in repositories_response { if repositories_backend .exists(&requester, &repository.repository) .await .as_internal_error()? { repositories.push(repository); } } Ok(repositories) } pub async fn repository_info( object: Repository, operation: RepositoryInfoRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let mut object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let tree = repository_backend .repository_file_inspect( &requester, object.object(), &RepositoryFileInspectRequest { extra_metadata: operation.extra_metadata, path: operation.path.clone(), rev: operation.rev.clone(), }, ) .await .as_internal_error()?; let statistics = repository_backend .repository_get_statistics( &requester, object.object(), &RepositoryStatisticsRequest { rev: operation.rev.clone(), }, ) .await .as_internal_error()?; drop(repository_backend); let info = RepositoryView { name: object.object().name.clone(), owner: object.object().owner.clone(), description: object.get::(&operation_state).await.ok(), visibility: object .get::(&operation_state) .await .as_internal_error()?, default_branch: object .get::(&operation_state) .await .as_internal_error()?, // 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. latest_commit: object.get::(&operation_state).await.ok(), stats: statistics, tree_rev: operation.rev.clone(), tree, }; Ok(info) } pub async fn repository_get_statistics( object: Repository, operation: RepositoryStatisticsRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let statistics = repository_backend .repository_get_statistics( &requester, object.object(), &RepositoryStatisticsRequest { rev: operation.rev.clone(), }, ) .await .as_internal_error()?; drop(repository_backend); Ok(statistics) } pub async fn repository_get_branches( object: Repository, operation: RepositoryBranchesRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result, OperationError> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let branches = repository_backend .repository_get_branches(&requester, object.object(), &operation) .await .as_internal_error()?; drop(repository_backend); Ok(branches) } pub async fn repository_file_from_id( object: Repository, operation: RepositoryFileFromIdRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let file = repository_backend .repository_file_from_id( &requester, object.object(), &RepositoryFileFromIdRequest(operation.0.clone()), ) .await .as_internal_error()?; drop(repository_backend); Ok(file) } pub async fn repository_file_from_path( object: Repository, operation: RepositoryFileFromPathRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result<(RepositoryFile, String), OperationError> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let file = repository_backend .repository_file_from_path( &requester, object.object(), &RepositoryFileFromPathRequest { rev: operation.rev.clone(), path: operation.path.clone(), }, ) .await .as_internal_error()?; drop(repository_backend); Ok(file) } pub async fn repository_last_commit_of_file( object: Repository, operation: RepositoryLastCommitOfFileRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let commit = repository_backend .repository_last_commit_of_file( &requester, object.object(), &RepositoryLastCommitOfFileRequest { start_commit: operation.start_commit.clone(), path: operation.path.clone(), }, ) .await .as_internal_error()?; drop(repository_backend); Ok(commit) } pub async fn repository_commit_by_id( object: Repository, operation: RepositoryCommitFromIdRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let commit = repository_backend .repository_commit_from_id( &requester, object.object(), &RepositoryCommitFromIdRequest(operation.0.clone()), ) .await .as_internal_error()?; drop(repository_backend); Ok(commit) } pub async fn repository_diff( object: Repository, operation: RepositoryDiffRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let diff = repository_backend .repository_diff(&requester, object.object(), &operation) .await .as_internal_error()?; drop(repository_backend); Ok(diff) } pub async fn repository_diff_patch( object: Repository, operation: RepositoryDiffPatchRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let patch = repository_backend .repository_diff_patch(&requester, object.object(), &operation) .await .as_internal_error()?; drop(repository_backend); Ok(patch) } pub async fn repository_commit_before( object: Repository, operation: RepositoryCommitBeforeRequest, state: DatabaseBackend, operation_state: StackOperationState, backend: Arc, requester: Option, ) -> Result> { let object = backend .get_object::(&object.to_string(), &operation_state) .await .unwrap(); let mut repository_backend = state.repository_backend.lock().await; let file = repository_backend .repository_commit_before(&requester, object.object(), &operation) .await .as_internal_error()?; drop(repository_backend); Ok(file) } pub async fn instance_authentication_request( object: Instance, operation: AuthenticationTokenRequest, state: DatabaseBackend, _operation_state: StackOperationState, // Authorizes the request for SAME-INSTANCE // _authorized_instance: AuthorizedInstance, ) -> Result> { let mut backend = state.user_backend.lock().await; backend .login(&object, operation.clone()) .await .as_internal_error() } pub async fn instance_registration_request( _object: Instance, operation: RegisterAccountRequest, state: DatabaseBackend, _operation_state: StackOperationState, // Authorizes the request for SAME-INSTANCE // _authorized_instance: AuthorizedInstance, ) -> Result> { let mut backend = state.user_backend.lock().await; backend .register(operation.clone()) .await .as_internal_error() } pub async fn instance_create_repository_request( _object: Instance, operation: RepositoryCreateRequest, state: DatabaseBackend, _operation_state: StackOperationState, requester: AuthenticatedUser, // Authorizes the request for SAME-INSTANCE // _authorized_instance: AuthorizedInstance, ) -> Result> { let mut backend = state.repository_backend.lock().await; backend .create_repository(&requester, &operation) .await .as_internal_error() }