@@ -505,4 +505,119 @@ 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(?, ?)' , [
535+ [ bucketName ] ,
536+ [ 'folder/file.txt' ]
537+ ] )
538+ ) . resolves . toBeDefined ( )
539+ } )
540+ } )
541+
542+ describe ( 'storage.delete_leaf_prefixes()' , ( ) => {
543+ it ( 'should delete leaf prefixes when no children exist' , async ( ) => {
544+ const db = tHelper . database . connection . pool . acquire ( )
545+
546+ // First, create some prefixes using add_prefixes function
547+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder1/file.txt' ] )
548+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder2/subfolder/file.txt' ] )
549+
550+ // Verify prefixes exist
551+ let prefixes = await db
552+ . select ( 'name' , 'level' )
553+ . from ( 'storage.prefixes' )
554+ . where ( 'bucket_id' , bucketName )
555+ . orderBy ( 'level' )
556+
557+ expect ( prefixes . length ) . toBeGreaterThan ( 0 )
558+
559+ await db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [
560+ [ bucketName ] ,
561+ [ 'folder1/file.txt' , 'folder2/subfolder/file.txt' ]
562+ ] )
563+
564+ // Check that some prefixes were deleted (function works)
565+ prefixes = await db
566+ . select ( 'name' , 'level' )
567+ . from ( 'storage.prefixes' )
568+ . where ( 'bucket_id' , bucketName )
569+ . orderBy ( 'level' )
570+
571+ // The function should have deleted some prefixes (exact count depends on implementation)
572+ expect ( prefixes . length ) . toBeLessThan ( 3 ) // Some prefixes were deleted
573+ } )
574+
575+ it ( 'should not delete prefixes with children' , async ( ) => {
576+ const db = tHelper . database . connection . pool . acquire ( )
577+
578+ // Create a prefix with a child object using add_prefixes
579+ await db . raw ( 'SELECT storage.add_prefixes(?, ?)' , [ bucketName , 'folder/file.txt' ] )
580+
581+ // Also create the actual object to ensure the prefix has children
582+ await db . raw ( 'INSERT INTO storage.objects (bucket_id, name, level) VALUES (?, ?, ?)' , [
583+ bucketName ,
584+ 'folder/file.txt' ,
585+ 2 ,
586+ ] )
587+
588+ await db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [
589+ [ bucketName ] ,
590+ [ 'folder/file.txt' ]
591+ ] )
592+
593+ // Check that prefix still exists (has children)
594+ const prefixes = await db
595+ . select ( 'name' , 'level' )
596+ . from ( 'storage.prefixes' )
597+ . where ( 'bucket_id' , bucketName )
598+ . orderBy ( 'level' )
599+
600+ expect ( prefixes ) . toHaveLength ( 1 )
601+ expect ( prefixes [ 0 ] . name ) . toBe ( 'folder' )
602+ } )
603+
604+ it ( 'should handle empty arrays' , async ( ) => {
605+ const db = tHelper . database . connection . pool . acquire ( )
606+
607+ await expect (
608+ db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [ [ ] , [ ] ] )
609+ ) . resolves . toBeDefined ( )
610+ } )
611+
612+ it ( 'should handle single bucket and name' , async ( ) => {
613+ const db = tHelper . database . connection . pool . acquire ( )
614+
615+ await expect (
616+ db . raw ( 'SELECT storage.delete_leaf_prefixes(?, ?)' , [
617+ [ bucketName ] ,
618+ [ 'folder/file.txt' ]
619+ ] )
620+ ) . resolves . toBeDefined ( )
621+ } )
622+ } )
508623} )
0 commit comments