@@ -706,60 +706,64 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
706
706
try self . removeFromSearchIndices ( identifier: collection. identifier)
707
707
// Update search indices
708
708
try self . withDB { db in
709
- try db. exec ( query: " BEGIN TRANSACTION; " )
710
-
711
709
let packagesStatement = try db. prepare ( query: " INSERT INTO \( Self . packagesFTSName) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); " )
712
710
let targetsStatement = try db. prepare ( query: " INSERT INTO \( Self . targetsFTSName) VALUES (?, ?, ?); " )
711
+
712
+ try db. exec ( query: " BEGIN TRANSACTION; " )
713
+ do {
714
+ // Then insert new data
715
+ try collection. packages. forEach { package in
716
+ var targets = Set < String > ( )
717
+
718
+ try package . versions. forEach { version in
719
+ try version. manifests. values. forEach { manifest in
720
+ // Packages FTS
721
+ let packagesBindings : [ SQLite . SQLiteValue ] = [
722
+ . string( try self . encoder. encode ( collection. identifier) . base64EncodedString ( ) ) ,
723
+ . string( package . identity. description) ,
724
+ . string( version. version. description) ,
725
+ . string( manifest. packageName) ,
726
+ . string( package . location) ,
727
+ package . summary. map { . string( $0) } ?? . null,
728
+ package . keywords. map { . string( $0. joined ( separator: " , " ) ) } ?? . null,
729
+ . string( manifest. products. map { $0. name } . joined ( separator: " , " ) ) ,
730
+ . string( manifest. targets. map { $0. name } . joined ( separator: " , " ) ) ,
731
+ ]
732
+ try packagesStatement. bind ( packagesBindings)
733
+ try packagesStatement. step ( )
734
+
735
+ try packagesStatement. clearBindings ( )
736
+ try packagesStatement. reset ( )
737
+
738
+ manifest. targets. forEach { targets. insert ( $0. name) }
739
+ }
740
+ }
713
741
714
- // Then insert new data
715
- try collection. packages. forEach { package in
716
- var targets = Set < String > ( )
742
+ let collectionPackage = CollectionPackage ( collection: collection. identifier, package : package . identity)
743
+ try targets. forEach { target in
744
+ // Targets in-memory trie
745
+ self . targetTrie. insert ( word: target. lowercased ( ) , foundIn: collectionPackage)
717
746
718
- try package . versions. forEach { version in
719
- try version. manifests. values. forEach { manifest in
720
- // Packages FTS
721
- let packagesBindings : [ SQLite . SQLiteValue ] = [
747
+ // Targets FTS
748
+ let targetsBindings : [ SQLite . SQLiteValue ] = [
722
749
. string( try self . encoder. encode ( collection. identifier) . base64EncodedString ( ) ) ,
723
- . string( package . identity. description) ,
724
- . string( version. version. description) ,
725
- . string( manifest. packageName) ,
726
750
. string( package . location) ,
727
- package . summary. map { . string( $0) } ?? . null,
728
- package . keywords. map { . string( $0. joined ( separator: " , " ) ) } ?? . null,
729
- . string( manifest. products. map { $0. name } . joined ( separator: " , " ) ) ,
730
- . string( manifest. targets. map { $0. name } . joined ( separator: " , " ) ) ,
751
+ . string( target) ,
731
752
]
732
- try packagesStatement . bind ( packagesBindings )
733
- try packagesStatement . step ( )
753
+ try targetsStatement . bind ( targetsBindings )
754
+ try targetsStatement . step ( )
734
755
735
- try packagesStatement. clearBindings ( )
736
- try packagesStatement. reset ( )
737
-
738
- manifest. targets. forEach { targets. insert ( $0. name) }
756
+ try targetsStatement. clearBindings ( )
757
+ try targetsStatement. reset ( )
739
758
}
740
759
}
741
-
742
- let collectionPackage = CollectionPackage ( collection: collection. identifier, package : package . identity)
743
- try targets. forEach { target in
744
- // Targets in-memory trie
745
- self . targetTrie. insert ( word: target. lowercased ( ) , foundIn: collectionPackage)
746
-
747
- // Targets FTS
748
- let targetsBindings : [ SQLite . SQLiteValue ] = [
749
- . string( try self . encoder. encode ( collection. identifier) . base64EncodedString ( ) ) ,
750
- . string( package . location) ,
751
- . string( target) ,
752
- ]
753
- try targetsStatement. bind ( targetsBindings)
754
- try targetsStatement. step ( )
755
-
756
- try targetsStatement. clearBindings ( )
757
- try targetsStatement. reset ( )
758
- }
760
+
761
+ try db. exec ( query: " COMMIT; " )
762
+ } catch {
763
+ try db. exec ( query: " ROLLBACK; " )
764
+ throw error
759
765
}
760
766
761
- try db. exec ( query: " COMMIT; " )
762
-
763
767
try packagesStatement. finalize ( )
764
768
try targetsStatement. finalize ( )
765
769
}
@@ -785,12 +789,16 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
785
789
try statement. step ( )
786
790
}
787
791
788
- // Repack database file to reduce size (rdar://77077510)
789
- try self . withDB { db in
792
+ // Run VACUUM asynchronously since it's just an optimization measure and could take some time to complete.
793
+ // Add a delay since VACUUM often fails if run immediately after the deletions.
794
+ DispatchQueue . sharedConcurrent. asyncAfter ( deadline: . now( ) + 0.5 ) {
795
+ // Repack database file to reduce size (rdar://77077510)
790
796
do {
791
- try db. exec ( query: " VACUUM; " )
797
+ try self . withDB { db in
798
+ try db. exec ( query: " VACUUM; " )
799
+ }
792
800
} catch {
793
- self . observabilityScope. emit ( warning : " Failed to 'VACUUM' the database: \( error) " )
801
+ self . observabilityScope. emit ( info : " Failed to 'VACUUM' the database: \( error) " )
794
802
}
795
803
}
796
804
0 commit comments