@@ -900,142 +900,117 @@ Future<void> _worker(
900
900
rethrow ;
901
901
}
902
902
903
- final storesQuery = root
904
- .box <ObjectBoxStore >()
905
- .query (ObjectBoxStore_ .name.oneOf (storeNames))
906
- .build ();
903
+ try {
904
+ final storesQuery = root
905
+ .box <ObjectBoxStore >()
906
+ .query (ObjectBoxStore_ .name.oneOf (storeNames))
907
+ .build ();
908
+ final tilesQuery = (root.box <ObjectBoxTile >().query ()
909
+ ..linkMany (
910
+ ObjectBoxTile_ .stores,
911
+ ObjectBoxStore_ .name.oneOf (storeNames),
912
+ ))
913
+ .build ();
907
914
908
- final tilesQuery = (root.box <ObjectBoxTile >().query ()
909
- ..linkMany (
910
- ObjectBoxTile_ .stores,
911
- ObjectBoxStore_ .name.oneOf (storeNames),
912
- ))
913
- .build ();
915
+ // Copy all stores to external root
916
+ // Then, to make sure relations work 100%, we go through the stores
917
+ // just copied to the external root and add them to the map below
918
+ final storesToExport = storesQuery.find ();
919
+ if (! listEquals (
920
+ storesToExport.map ((s) => s.name).toList (growable: false ),
921
+ storeNames,
922
+ )) {
923
+ throw ArgumentError (
924
+ 'Specified stores did not match the resolved existing stores' ,
925
+ 'storeNames' ,
926
+ );
927
+ }
928
+ final storesObjectsForRelations =
929
+ Map <String , ObjectBoxStore >.fromEntries (
930
+ (exportingRoot.box <ObjectBoxStore >()
931
+ ..putMany (
932
+ storesQuery
933
+ .find ()
934
+ .map (
935
+ (store) => ObjectBoxStore (
936
+ name: store.name,
937
+ maxLength: store.maxLength,
938
+ length: store.length,
939
+ size: store.size,
940
+ hits: store.hits,
941
+ misses: store.misses,
942
+ metadataJson: store.metadataJson,
943
+ ),
944
+ )
945
+ .toList (growable: false ),
946
+ mode: PutMode .insert,
947
+ ))
948
+ .getAll ()
949
+ .map ((s) => MapEntry (s.name, s)),
950
+ );
914
951
915
- final storesObjectsForRelations = < String , ObjectBoxStore > {};
952
+ // Copy all tiles to external root
953
+ int numExportedTiles = 0 ;
954
+ tilesQuery.chunkedMultiTransaction (
955
+ chunkSize: 300 ,
956
+ root: root,
957
+ runInTransaction: (tile) {
958
+ exportingRoot.box <ObjectBoxTile >().put (
959
+ ObjectBoxTile (
960
+ url: tile.url,
961
+ bytes: tile.bytes,
962
+ lastModified: tile.lastModified,
963
+ )..stores.addAll (
964
+ tile.stores
965
+ .map ((s) => storesObjectsForRelations[s.name])
966
+ .nonNulls,
967
+ ),
968
+ mode: PutMode .insert,
969
+ );
970
+ numExportedTiles++ ;
971
+ },
972
+ );
916
973
917
- final exportingStores = root.runInTransaction (
918
- TxMode .read,
919
- storesQuery.stream,
920
- );
974
+ storesQuery.close ();
975
+ tilesQuery.close ();
976
+ exportingRoot.close ();
921
977
922
- exportingRoot
923
- .runInTransaction (
924
- TxMode .write,
925
- () => exportingStores.map (
926
- (exportingStore) {
927
- exportingRoot.box <ObjectBoxStore >().put (
928
- storesObjectsForRelations[exportingStore.name] =
929
- ObjectBoxStore (
930
- name: exportingStore.name,
931
- maxLength: exportingStore.maxLength,
932
- length: exportingStore.length,
933
- size: exportingStore.size,
934
- hits: exportingStore.hits,
935
- misses: exportingStore.misses,
936
- metadataJson: exportingStore.metadataJson,
937
- ),
938
- mode: PutMode .insert,
939
- );
940
- },
941
- ),
942
- )
943
- .length
944
- .then (
945
- (numExportedStores) {
946
- if (numExportedStores == 0 ) throw StateError ('Unpossible' );
947
-
948
- final exportingTiles = root.runInTransaction (
949
- TxMode .read,
950
- tilesQuery.stream,
951
- );
978
+ final dbFile = File (path.join (workingDir.absolute.path, 'data.mdb' ));
952
979
953
- exportingRoot
954
- .runInTransaction (
955
- TxMode .write,
956
- () => exportingTiles.map (
957
- (exportingTile) {
958
- exportingRoot.box <ObjectBoxTile >().put (
959
- ObjectBoxTile (
960
- url: exportingTile.url,
961
- bytes: exportingTile.bytes,
962
- lastModified: exportingTile.lastModified,
963
- )..stores.addAll (
964
- exportingTile.stores
965
- .map (
966
- (s) => storesObjectsForRelations[s.name],
967
- )
968
- .nonNulls,
969
- ),
970
- mode: PutMode .insert,
971
- );
972
- },
973
- ),
974
- )
975
- .length
976
- .then (
977
- (numExportedTiles) {
978
- if (numExportedTiles == 0 ) {
979
- throw ArgumentError (
980
- 'Specified stores must include at least one tile total' ,
981
- 'storeNames' ,
982
- );
983
- }
980
+ final ram = dbFile.openSync (mode: FileMode .writeOnlyAppend);
981
+ try {
982
+ ram
983
+ ..writeFromSync (List .filled (4 , 255 ))
984
+ ..writeStringSync ('ObjectBox' ) // Backend identifier
985
+ ..writeByteSync (255 )
986
+ ..writeByteSync (255 )
987
+ ..writeStringSync ('FMTC' ); // Signature
988
+ } finally {
989
+ ram.closeSync ();
990
+ }
984
991
985
- storesQuery.close ();
986
- tilesQuery.close ();
987
- exportingRoot.close ();
988
-
989
- final dbFile =
990
- File (path.join (workingDir.absolute.path, 'data.mdb' ));
991
-
992
- final ram = dbFile.openSync (mode: FileMode .writeOnlyAppend);
993
- try {
994
- ram
995
- ..writeFromSync (List .filled (4 , 255 ))
996
- ..writeStringSync ('ObjectBox' ) // Backend identifier
997
- ..writeByteSync (255 )
998
- ..writeByteSync (255 )
999
- ..writeStringSync ('FMTC' ); // Signature
1000
- } finally {
1001
- ram.closeSync ();
1002
- }
992
+ try {
993
+ dbFile.renameSync (outputPath);
994
+ } on FileSystemException {
995
+ dbFile.copySync (outputPath);
996
+ } finally {
997
+ workingDir.deleteSync (recursive: true );
998
+ }
1003
999
1004
- try {
1005
- dbFile.renameSync (outputPath);
1006
- } on FileSystemException {
1007
- dbFile.copySync (outputPath);
1008
- } finally {
1009
- workingDir.deleteSync (recursive: true );
1010
- }
1000
+ sendRes (
1001
+ id: cmd.id,
1002
+ data: {'numExportedTiles' : numExportedTiles},
1003
+ );
1011
1004
1012
- sendRes (
1013
- id: cmd.id,
1014
- data: {'numExportedTiles' : numExportedTiles},
1015
- );
1016
- },
1017
- ).catchError ((error, stackTrace) {
1018
- exportingRoot.close ();
1019
- try {
1020
- workingDir.deleteSync (recursive: true );
1021
- // If the working dir didn't exist, that's fine
1022
- // We don't want to spend time checking if exists, as it likely
1023
- // does
1024
- // ignore: empty_catches
1025
- } on FileSystemException {}
1026
- Error .throwWithStackTrace (error, stackTrace);
1027
- });
1028
- },
1029
- ).catchError ((error, stackTrace) {
1005
+ // We don't care what type, we always need to clean up and rethrow
1006
+ // ignore: avoid_catches_without_on_clauses
1007
+ } catch (e) {
1030
1008
exportingRoot.close ();
1031
- try {
1009
+ if (workingDir. existsSync ()) {
1032
1010
workingDir.deleteSync (recursive: true );
1033
- // If the working dir didn't exist, that's fine
1034
- // We don't want to spend time checking if exists, as it likely does
1035
- // ignore: empty_catches
1036
- } on FileSystemException {}
1037
- Error .throwWithStackTrace (error, stackTrace);
1038
- });
1011
+ }
1012
+ rethrow ;
1013
+ }
1039
1014
case _CmdType .importStores:
1040
1015
final importPath = cmd.args['path' ]! as String ;
1041
1016
final strategy = cmd.args['strategy' ] as ImportConflictStrategy ;
0 commit comments