@@ -33,6 +33,16 @@ mononoke_queries! {
3333 "
3434 }
3535
36+ read GetBundleListsForRepo ( repo_id: RepositoryId ) -> (
37+ String , u64 , u64 , String , u64
38+ ) {
39+ "SELECT bundle_handle, in_bundle_list_order, bundle_list, bundle_fingerprint, generation_start_timestamp
40+ FROM git_bundles
41+ WHERE repo_id = {repo_id}
42+ ORDER BY bundle_list DESC, in_bundle_list_order ASC;
43+ "
44+ }
45+
3646 read GetLatestBundleListNumForRepo ( repo_id: RepositoryId ) -> (
3747 u64
3848 ) {
@@ -65,6 +75,11 @@ mononoke_queries! {
6575 none,
6676 "INSERT INTO git_bundles (repo_id, bundle_handle, bundle_list, in_bundle_list_order, bundle_fingerprint, generation_start_timestamp) VALUES {values}"
6777 }
78+
79+ write RemoveBundleList ( repo_id: RepositoryId , bundle_list: u64 ) {
80+ none,
81+ "DELETE FROM git_bundles WHERE repo_id = {repo_id} and bundle_list = {bundle_list}"
82+ }
6883}
6984
7085#[ derive( Clone ) ]
@@ -173,6 +188,81 @@ impl SqlGitBundleMetadataStorage {
173188
174189 Ok ( Some ( bundle_list) )
175190 }
191+
192+ pub async fn remove_bundle_list ( & self , bundle_list_num : u64 ) -> Result < ( ) > {
193+ RemoveBundleList :: query (
194+ & self . connections . write_connection ,
195+ & self . repo_id ,
196+ & bundle_list_num,
197+ )
198+ . await ?;
199+ Ok ( ( ) )
200+ }
201+
202+ pub async fn get_bundle_lists ( & self ) -> Result < Vec < BundleList > > {
203+ let rows =
204+ GetBundleListsForRepo :: query ( & self . connections . read_connection , & self . repo_id ) . await ?;
205+
206+ // +----------------------+-------------+
207+ // | in_bundle_list_order | bundle_list |
208+ // +----------------------+-------------+
209+ // | 1 | 3 |
210+ // | 1 | 2 |
211+ // | 2 | 2 |
212+ // | 3 | 2 |
213+ // | 1 | 1 |
214+ // +----------------------+-------------+
215+ let mut bundle_lists = vec ! [ ] ;
216+ let mut rows_iter = rows. into_iter ( ) . peekable ( ) ;
217+ while let Some ( (
218+ handle,
219+ in_bundle_list_order,
220+ first_seen_bundle_list,
221+ fingerprint,
222+ generation_start_timestamp,
223+ ) ) = rows_iter. next ( )
224+ {
225+ let current_bundle_list_num = first_seen_bundle_list;
226+ // First bundle for a new bundle-list.
227+ let mut bundles = vec ! [ Bundle {
228+ in_bundle_list_order,
229+ handle,
230+ fingerprint,
231+ generation_start_timestamp,
232+ } ] ;
233+
234+ // Rest of the bundles for the new bundle-list.
235+ while let Some ( (
236+ handle,
237+ in_bundle_list_order,
238+ bundle_list,
239+ fingerprint,
240+ generation_start_timestamp,
241+ ) ) = rows_iter. peek ( )
242+ {
243+ if current_bundle_list_num == * bundle_list {
244+ // This bundle belongs to the current bundle-list.
245+ bundles. push ( Bundle {
246+ in_bundle_list_order : * in_bundle_list_order,
247+ handle : handle. clone ( ) ,
248+ fingerprint : fingerprint. clone ( ) ,
249+ generation_start_timestamp : generation_start_timestamp. clone ( ) ,
250+ } ) ;
251+ rows_iter. next ( ) ;
252+ } else {
253+ // This bundle is the first elem of the next bundle-list. Do not consume it.
254+ // Break the loop to finish processing current bundle.
255+ break ;
256+ }
257+ }
258+ bundle_lists. push ( BundleList {
259+ bundle_list_num : current_bundle_list_num,
260+ bundles,
261+ } ) ;
262+ }
263+
264+ Ok ( bundle_lists)
265+ }
176266}
177267
178268#[ cfg( test) ]
@@ -277,4 +367,49 @@ mod test {
277367
278368 Ok ( ( ) )
279369 }
370+
371+ #[ mononoke:: fbinit_test]
372+ async fn test_get_bundle_lists ( _: FacebookInit ) -> Result < ( ) > {
373+ let repo_id = RepositoryId :: new ( 2137 ) ;
374+ let storage = SqlGitBundleMetadataStorageBuilder :: with_sqlite_in_memory ( ) ?. build ( repo_id) ;
375+
376+ storage. add_new_bundles ( & TEST_BUNDLE_LIST_2 [ ..] ) . await ?;
377+ storage. add_new_bundles ( & TEST_BUNDLE_LIST_3 [ ..] ) . await ?;
378+
379+ let bundle_lists = storage. get_bundle_lists ( ) . await ?;
380+ assert_eq ! ( bundle_lists. len( ) , 2 ) ;
381+ for bundle_list in bundle_lists. iter ( ) {
382+ for ( p, n) in bundle_list. bundles . iter ( ) . tuple_windows ( ) {
383+ assert ! ( p. in_bundle_list_order < n. in_bundle_list_order)
384+ }
385+ }
386+ for ( p, n) in bundle_lists. iter ( ) . tuple_windows ( ) {
387+ assert ! ( p. bundle_list_num > n. bundle_list_num)
388+ }
389+
390+ Ok ( ( ) )
391+ }
392+
393+ #[ mononoke:: fbinit_test]
394+ async fn test_remove_bundle_list ( _: FacebookInit ) -> Result < ( ) > {
395+ let repo_id = RepositoryId :: new ( 2137 ) ;
396+ let storage = SqlGitBundleMetadataStorageBuilder :: with_sqlite_in_memory ( ) ?. build ( repo_id) ;
397+
398+ let bundle_list_num_2 = storage. add_new_bundles ( & TEST_BUNDLE_LIST_2 [ ..] ) . await ?;
399+ let bundle_list_num_3 = storage. add_new_bundles ( & TEST_BUNDLE_LIST_3 [ ..] ) . await ?;
400+
401+ let bundle_lists = storage. get_bundle_lists ( ) . await ?;
402+ assert_eq ! ( bundle_lists. len( ) , 2 ) ;
403+ assert_eq ! ( bundle_lists[ 0 ] . bundle_list_num, bundle_list_num_3) ;
404+ assert_eq ! ( bundle_lists[ 1 ] . bundle_list_num, bundle_list_num_2) ;
405+ storage. remove_bundle_list ( bundle_list_num_2) . await ?;
406+ let bundle_lists = storage. get_bundle_lists ( ) . await ?;
407+ assert_eq ! ( bundle_lists. len( ) , 1 ) ;
408+ assert_eq ! ( bundle_lists[ 0 ] . bundle_list_num, bundle_list_num_3) ;
409+ storage. remove_bundle_list ( bundle_list_num_3) . await ?;
410+ let bundle_lists = storage. get_bundle_lists ( ) . await ?;
411+ assert_eq ! ( bundle_lists. len( ) , 0 ) ;
412+
413+ Ok ( ( ) )
414+ }
280415}
0 commit comments