@@ -91,14 +91,24 @@ func MakeRecursive(ctx context.Context, db dbForMakeRecursive, pathToCreate stri
9191// where `~` - is a root of database
9292func RemoveRecursive (ctx context.Context , db dbFoRemoveRecursive , pathToRemove string ) error {
9393 fullSysTablePath := path .Join (db .Name (), sysDirectory )
94- var rmPath func (int , string ) error
95- rmPath = func (i int , p string ) error {
96- if exists , err := IsDirectoryExists (ctx , db .Scheme (), p ); err != nil {
97- return xerrors .WithStackTrace (
98- fmt .Errorf ("check directory %q exists failed: %w" , p , err ),
99- )
100- } else if ! exists {
101- return nil
94+ var removePathRecursively func (int , string ) error
95+ removePathRecursively = rmPath (ctx , db , fullSysTablePath , removePathRecursively )
96+ pathToRemove = removeWithPrefix (pathToRemove , db )
97+
98+ return removePathRecursively (0 , pathToRemove )
99+ }
100+
101+ // rmPath removes a path recursively from the database
102+ func rmPath (
103+ ctx context.Context ,
104+ db dbFoRemoveRecursive ,
105+ fullSysTablePath string ,
106+ removePathRecursively func (int , string ) error ,
107+ ) func (i int , p string ) error {
108+ return func (i int , p string ) error {
109+ err := checkDirectoryExists (ctx , db , p )
110+ if err != nil {
111+ return err
102112 }
103113
104114 entry , err := db .Scheme ().DescribePath (ctx , p )
@@ -108,15 +118,9 @@ func RemoveRecursive(ctx context.Context, db dbFoRemoveRecursive, pathToRemove s
108118 )
109119 }
110120
111- if entry .Type != scheme .EntryDirectory && entry .Type != scheme .EntryDatabase {
112- return nil
113- }
114-
115- dir , err := db .Scheme ().ListDirectory (ctx , p )
121+ dir , err := checkEntryAndListDirectory (ctx , db , & entry , p )
116122 if err != nil {
117- return xerrors .WithStackTrace (
118- fmt .Errorf ("listing directory %q failed: %w" , p , err ),
119- )
123+ return err
120124 }
121125
122126 for j := range dir .Children {
@@ -126,7 +130,7 @@ func RemoveRecursive(ctx context.Context, db dbFoRemoveRecursive, pathToRemove s
126130 }
127131 switch t := dir .Children [j ].Type ; t {
128132 case scheme .EntryDirectory :
129- if err = rmPath (i + 1 , pt ); err != nil {
133+ if err = removePathRecursively (i + 1 , pt ); err != nil {
130134 return xerrors .WithStackTrace (
131135 fmt .Errorf ("recursive removing directory %q failed: %w" , pt , err ),
132136 )
@@ -157,22 +161,76 @@ func RemoveRecursive(ctx context.Context, db dbFoRemoveRecursive, pathToRemove s
157161 }
158162 }
159163
160- if entry .Type != scheme .EntryDirectory {
161- return nil
164+ err = removeDirectoryIfNotEntry (ctx , db , & entry , p )
165+ if err != nil {
166+ return err
162167 }
163168
164- err = db .Scheme ().RemoveDirectory (ctx , p )
169+ return nil
170+ }
171+ }
172+
173+ // removeWithPrefix prepends the db.Name() to the pathToRemove string if it does not already have the prefix.
174+ func removeWithPrefix (pathToRemove string , db dbFoRemoveRecursive ) string {
175+ if ! strings .HasPrefix (pathToRemove , db .Name ()) {
176+ pathToRemove = path .Join (db .Name (), pathToRemove )
177+ }
178+
179+ return pathToRemove
180+ }
181+
182+ // checkDirectoryExists checks if a directory exists in the specified database.
183+ func checkDirectoryExists (ctx context.Context , db dbFoRemoveRecursive , p string ) error {
184+ exists , err := IsDirectoryExists (ctx , db .Scheme (), p )
185+ if err != nil {
186+ return xerrors .WithStackTrace (
187+ fmt .Errorf ("check directory %q exists failed: %w" , p , err ),
188+ )
189+ } else if ! exists {
190+ return nil
191+ }
192+
193+ return nil
194+ }
195+
196+ // removeDirectoryIfNotEntry removes a directory if it is not an entry.
197+ func removeDirectoryIfNotEntry (
198+ ctx context.Context ,
199+ db dbFoRemoveRecursive ,
200+ entry * scheme.Entry ,
201+ p string ,
202+ ) error {
203+ if entry .Type == scheme .EntryDirectory {
204+ err := db .Scheme ().RemoveDirectory (ctx , p )
165205 if err != nil {
166206 return xerrors .WithStackTrace (
167207 fmt .Errorf ("removing directory %q failed: %w" , p , err ),
168208 )
169209 }
210+ }
170211
171- return nil
212+ return nil
213+ }
214+
215+ // checkEntryAndListDirectory checks if the given entry is not a EntryDirectory or a EntryDatabase
216+ // and lists its children directories and files.
217+ func checkEntryAndListDirectory (
218+ ctx context.Context ,
219+ db dbFoRemoveRecursive ,
220+ entry * scheme.Entry ,
221+ p string ,
222+ ) (scheme.Directory , error ) {
223+ var dir scheme.Directory
224+ if entry .Type != scheme .EntryDirectory && entry .Type != scheme .EntryDatabase {
225+ return dir , nil
172226 }
173- if ! strings .HasPrefix (pathToRemove , db .Name ()) {
174- pathToRemove = path .Join (db .Name (), pathToRemove )
227+
228+ dir , err := db .Scheme ().ListDirectory (ctx , p )
229+ if err != nil {
230+ return dir , xerrors .WithStackTrace (
231+ fmt .Errorf ("listing directory %q failed: %w" , p , err ),
232+ )
175233 }
176234
177- return rmPath ( 0 , pathToRemove )
235+ return dir , nil
178236}
0 commit comments