@@ -505,4 +505,110 @@ describe('Prefix SQL Functions Unit Tests', () => {
505505 expect ( prefix . bucket_id ) . toBe ( bucketName )
506506 } )
507507 } )
508+
509+ describe ( 'storage.lock_top_prefixes()' , ( ) => {
510+ it ( 'should acquire advisory locks for top-level prefixes' , async ( ) => {
511+ const db = tHelper . database . connection . pool . acquire ( )
512+
513+ // This function doesn't return a value, but we can test it doesn't throw
514+ await expect (
515+ db . raw ( 'SELECT storage.lock_top_prefixes(?, ?)' , [
516+ [ bucketName , bucketName ] ,
517+ [ 'folder1/file.txt' , 'folder2/subfolder/file.txt' ] ,
518+ ] )
519+ ) . resolves . toBeDefined ( )
520+ } )
521+
522+ it ( 'should handle empty arrays' , async ( ) => {
523+ const db = tHelper . database . connection . pool . acquire ( )
524+
525+ await expect (
526+ db . raw ( 'SELECT storage.lock_top_prefixes(?, ?)' , [ [ ] , [ ] ] )
527+ ) . resolves . toBeDefined ( )
528+ } )
529+
530+ it ( 'should handle single bucket and name' , async ( ) => {
531+ const db = tHelper . database . connection . pool . acquire ( )
532+
533+ await expect (
534+ db . raw ( 'SELECT storage.lock_top_prefixes(?, ?)' , [ [ bucketName ] , [ 'folder/file.txt' ] ] )
535+ ) . resolves . toBeDefined ( )
536+ } )
537+ } )
538+
539+ describe ( 'storage.delete_leaf_prefixes()' , ( ) => {
540+ it ( 'should delete leaf prefixes when no children exist' , async ( ) => {
541+ const db = tHelper . database . connection . pool . acquire ( )
542+
543+ // First, create some prefixes using add_prefixes function
544+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder1/file.txt' ] )
545+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder2/subfolder/file.txt' ] )
546+
547+ // Verify prefixes exist
548+ let prefixes = await db
549+ . select ( 'name' , 'level' )
550+ . from ( 'storage.prefixes' )
551+ . where ( 'bucket_id' , bucketName )
552+ . orderBy ( 'level' )
553+
554+ expect ( prefixes . length ) . toBeGreaterThan ( 0 )
555+
556+ await db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [
557+ [ bucketName ] ,
558+ [ 'folder1/file.txt' , 'folder2/subfolder/file.txt' ] ,
559+ ] )
560+
561+ // Check that some prefixes were deleted (function works)
562+ prefixes = await db
563+ . select ( 'name' , 'level' )
564+ . from ( 'storage.prefixes' )
565+ . where ( 'bucket_id' , bucketName )
566+ . orderBy ( 'level' )
567+
568+ // The function should have deleted some prefixes (exact count depends on implementation)
569+ expect ( prefixes . length ) . toBeLessThan ( 3 ) // Some prefixes were deleted
570+ } )
571+
572+ it ( 'should not delete prefixes with children' , async ( ) => {
573+ const db = tHelper . database . connection . pool . acquire ( )
574+
575+ // Create a prefix with a child object using add_prefixes
576+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder/file.txt' ] )
577+
578+ // Also create the actual object to ensure the prefix has children
579+ await db . raw ( 'INSERT INTO storage.objects (bucket_id, name, level) VALUES (?, ?, ?)' , [
580+ bucketName ,
581+ 'folder/file.txt' ,
582+ 2 ,
583+ ] )
584+
585+ await db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [ [ bucketName ] , [ 'folder/file.txt' ] ] )
586+
587+ // Check that prefix still exists (has children)
588+ const prefixes = await db
589+ . select ( 'name' , 'level' )
590+ . from ( 'storage.prefixes' )
591+ . where ( 'bucket_id' , bucketName )
592+ . orderBy ( 'level' )
593+
594+ expect ( prefixes ) . toHaveLength ( 1 )
595+ expect ( prefixes [ 0 ] . name ) . toBe ( 'folder' )
596+ } )
597+
598+ it ( 'should handle empty arrays' , async ( ) => {
599+ const db = tHelper . database . connection . pool . acquire ( )
600+
601+ await expect (
602+ db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [ [ ] , [ ] ] )
603+ ) . resolves . toBeDefined ( )
604+ } )
605+
606+ it ( 'should handle single bucket and name' , async ( ) => {
607+ const db = tHelper . database . connection . pool . acquire ( )
608+
609+ await expect (
610+ db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [ [ bucketName ] , [ 'folder/file.txt' ] ] )
611+ ) . resolves . toBeDefined ( )
612+ } )
613+ } )
508614} )
0 commit comments