Signed by hanna SSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
crates/store/src/bookmarks.rs +98 −0 crates/store/src/lib.rs +1 −0 crates/store/src/repos.rs +2 −2 data/repos/01/01kye754pv7cb136x910ppnvja.git/FETCH_HEAD +2 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/HEAD +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/config +9 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/description +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/README.sample +5 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/post-receive +2 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/pre-receive +2 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/info/exclude +2 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/HEAD +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/refs/heads/a +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/refs/heads/main +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.idx +0 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.pack +0 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.rev +0 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/refs/heads/a +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/refs/heads/main +1 −0 migrations/postgres/0018_bookmarks.sql +10 −0 migrations/sqlite/0018_bookmarks.sql +10 −0 crates/store/src/bookmarks.rs +98 −0 1 2 3 4 5 6 7 8 use model:: Repo ; 9 use sqlx:: { AssertSqlSafe , Row } ; 10 11 use crate :: repos:: REPO_COLUMNS ; 12 use crate :: { Store , StoreError , new_id, now_ms} ; 13 14 impl Store { 15 16 17 18 19 20 pub async fn add_bookmark ( & self , user_id : & str , repo_id : & str ) -> Result < ( ) , StoreError > { 21 sqlx:: query ( 22 "INSERT INTO bookmarks (id, user_id, repo_id, created_at) VALUES ($1, $2, $3, $4) \ 23 ON CONFLICT (user_id, repo_id) DO NOTHING" , 24 ) 25 . bind ( new_id ( ) ) 26 . bind ( user_id) 27 . bind ( repo_id) 28 . bind ( now_ms ( ) ) 29 . execute ( & self . pool) 30 . await ?; 31 Ok ( ( ) ) 32 } 33 34 35 36 37 38 39 pub async fn remove_bookmark ( & self , user_id : & str , repo_id : & str ) -> Result < ( ) , StoreError > { 40 sqlx:: query ( "DELETE FROM bookmarks WHERE user_id = $1 AND repo_id = $2" ) 41 . bind ( user_id) 42 . bind ( repo_id) 43 . execute ( & self . pool) 44 . await ?; 45 Ok ( ( ) ) 46 } 47 48 49 50 51 52 53 pub async fn is_bookmarked ( & self , user_id : & str , repo_id : & str ) -> Result < bool , StoreError > { 54 let row = sqlx:: query ( "SELECT 1 AS n FROM bookmarks WHERE user_id = $1 AND repo_id = $2" ) 55 . bind ( user_id) 56 . bind ( repo_id) 57 . fetch_optional ( & self . pool) 58 . await ?; 59 Ok ( row. is_some ( ) ) 60 } 61 62 63 64 65 66 67 pub async fn count_repo_bookmarks ( & self , repo_id : & str ) -> Result < i64 , StoreError > { 68 let n: i64 = sqlx:: query ( "SELECT COUNT(*) AS n FROM bookmarks WHERE repo_id = $1" ) 69 . bind ( repo_id) 70 . fetch_one ( & self . pool) 71 . await ? 72 . try_get ( "n" ) ?; 73 Ok ( n) 74 } 75 76 77 78 79 80 81 82 pub async fn bookmarked_repos ( & self , user_id : & str ) -> Result < Vec < Repo > , StoreError > { 83 84 let cols = format ! ( "r.{}" , REPO_COLUMNS . replace ( ", " , ", r." ) ) ; 85 let sql = format ! ( 86 "SELECT {cols} FROM repos r JOIN bookmarks b ON b.repo_id = r.id \ 87 WHERE b.user_id = $1 ORDER BY b.created_at DESC" 88 ) ; 89 let rows = sqlx:: query ( AssertSqlSafe ( sql) ) 90 . bind ( user_id) 91 . fetch_all ( & self . pool) 92 . await ?; 93 rows. iter ( ) 94 . map ( |r| self . map_repo ( r) ) 95 . collect :: < Result < _ , _ > > ( ) 96 . map_err ( Into :: into) 97 } 98 }
crates/store/src/lib.rs +1 −0 26 26 27 27 28 mod admin; 28 mod admin; 29 mod bookmarks; 29 mod groups; 30 mod groups; 30 mod invites; 31 mod invites; 31 mod issues; 32 mod issues;
crates/store/src/repos.rs +2 −2 11 use crate :: { Store , StoreError , map_conflict, new_id, now_ms} ; 11 use crate :: { Store , StoreError , map_conflict, new_id, now_ms} ; 12 12 13 13 14 const REPO_COLUMNS : & str = "id, owner_id, group_id, name, path, description, visibility, \ 14 pub ( crate ) const REPO_COLUMNS : & str = "id, owner_id, group_id, name, path, description, visibility, \ 15 default_branch, object_format, issues_enabled, pulls_enabled, releases_enabled, is_mirror, \ 15 default_branch, object_format, issues_enabled, pulls_enabled, releases_enabled, is_mirror, \ 16 fork_parent_id, next_iid, archived_at, size_bytes, pushed_at, created_at, updated_at" ; 16 fork_parent_id, next_iid, archived_at, size_bytes, pushed_at, created_at, updated_at" ; 17 17 483 } 483 } 484 484 485 485 486 fn map_repo ( & self , row : & AnyRow ) -> Result < Repo , sqlx:: Error > { 486 pub ( crate ) fn map_repo ( & self , row : & AnyRow ) -> Result < Repo , sqlx:: Error > { 487 Ok ( Repo { 487 Ok ( Repo { 488 id: row. try_get ( "id" ) ?, 488 id: row. try_get ( "id" ) ?, 489 owner_id: row. try_get ( "owner_id" ) ?, 489 owner_id: row. try_get ( "owner_id" ) ?,
data/repos/01/01kye754pv7cb136x910ppnvja.git/FETCH_HEAD +2 −0 1 66215cd4f32408a28a91cc10f0080bb4b3beb2a6 branch 'a' of data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4 2 94ffb4ef79a86c7e24d038233859149ba61439aa branch 'main' of data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4
data/repos/01/01kye754pv7cb136x910ppnvja.git/HEAD +1 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/config +9 −0 1 [core] 2 bare = true 3 repositoryformatversion = 0 4 filemode = true 5 logallrefupdates = true 6 [receive] 7 denyNonFastForwards = false 8 [gc] 9 auto = 0
data/repos/01/01kye754pv7cb136x910ppnvja.git/description +1 −0 1 Unnamed repository; edit this file 'description' to name the repository.
data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/README.sample +5 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/post-receive +2 −0 1 2 exec "/nix/store/2ncl66xwbsl6qf2766w3sxy3dv9vaply-fabrica-0.1.0/bin/.fabrica-wrapped" hook post-receive
data/repos/01/01kye754pv7cb136x910ppnvja.git/hooks/pre-receive +2 −0 data/repos/01/01kye754pv7cb136x910ppnvja.git/info/exclude +2 −0 1 # File patterns to ignore; see `git help ignore` for more information. 2 # Lines that start with '#' are comments.
data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/HEAD +1 −0 1 0000000000000000000000000000000000000000 94ffb4ef79a86c7e24d038233859149ba61439aa hanna <me@hanna.lol> 1785036182 -0400 fetch --prune --quiet data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*: storing head
data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/refs/heads/a +1 −0 1 0000000000000000000000000000000000000000 66215cd4f32408a28a91cc10f0080bb4b3beb2a6 hanna <me@hanna.lol> 1785036182 -0400 fetch --prune --quiet data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*: storing head
data/repos/01/01kye754pv7cb136x910ppnvja.git/logs/refs/heads/main +1 −0 1 0000000000000000000000000000000000000000 94ffb4ef79a86c7e24d038233859149ba61439aa hanna <me@hanna.lol> 1785036182 -0400 fetch --prune --quiet data/repos/01/01kyc0j4dzrnx6afv3wwfvxgn4.git +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*: storing head
data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.idx +0 −0 Binary file not shown.
data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.pack +0 −0 Binary file not shown.
data/repos/01/01kye754pv7cb136x910ppnvja.git/objects/pack/pack-a7fdcb5c169f40c31c03119f33105da551053535.rev +0 −0 Binary file not shown.
data/repos/01/01kye754pv7cb136x910ppnvja.git/refs/heads/a +1 −0 1 66215cd4f32408a28a91cc10f0080bb4b3beb2a6
data/repos/01/01kye754pv7cb136x910ppnvja.git/refs/heads/main +1 −0 1 94ffb4ef79a86c7e24d038233859149ba61439aa
migrations/postgres/0018_bookmarks.sql +10 −0 1 -- Bookmarks (stars): a user marking a repository. Public on the user's profile, 2 -- filtered by the viewer's read access when listed. 3 CREATE TABLE bookmarks ( 4 id TEXT PRIMARY KEY , 5 user_id TEXT NOT NULL REFERENCES users ( id) ON DELETE CASCADE , 6 repo_id TEXT NOT NULL REFERENCES repos ( id) ON DELETE CASCADE , 7 created_at BIGINT NOT NULL 8 ) ; 9 CREATE UNIQUE INDEX idx_bookmarks_user_repo ON bookmarks ( user_id, repo_id) ; 10 CREATE INDEX idx_bookmarks_repo ON bookmarks ( repo_id) ;
migrations/sqlite/0018_bookmarks.sql +10 −0 1 -- Bookmarks (stars): a user marking a repository. Public on the user's profile, 2 -- filtered by the viewer's read access when listed. 3 CREATE TABLE bookmarks ( 4 id TEXT PRIMARY KEY , 5 user_id TEXT NOT NULL REFERENCES users ( id) ON DELETE CASCADE , 6 repo_id TEXT NOT NULL REFERENCES repos ( id) ON DELETE CASCADE , 7 created_at BIGINT NOT NULL 8 ) ; 9 CREATE UNIQUE INDEX idx_bookmarks_user_repo ON bookmarks ( user_id, repo_id) ; 10 CREATE INDEX idx_bookmarks_repo ON bookmarks ( repo_id) ;