@@ -177,11 +177,31 @@ impl Dataset {
177
177
}
178
178
Ok ( Transaction :: new ( self ) )
179
179
}
180
+
181
+ /// Optionally start a transaction before running `func` for performance
182
+ ///
183
+ /// This uses transaction if the dataset supports it, otherwise it
184
+ /// runs the `func` function as it is on the dataset.
185
+ pub fn maybe_batch ( & mut self , func : impl Fn ( & Dataset ) -> Result < ( ) > ) -> Result < ( ) > {
186
+ let force = 0 ; // since this is for speed
187
+ let rv = unsafe { gdal_sys:: GDALDatasetStartTransaction ( self . c_dataset ( ) , force) } ;
188
+ let res = func ( self ) ;
189
+ if rv == OGRErr :: OGRERR_NONE {
190
+ let rv = unsafe { gdal_sys:: GDALDatasetCommitTransaction ( self . c_dataset ( ) ) } ;
191
+ if rv != OGRErr :: OGRERR_NONE {
192
+ return Err ( GdalError :: OgrError {
193
+ err : rv,
194
+ method_name : "GDALDatasetCommitTransaction" ,
195
+ } ) ;
196
+ }
197
+ }
198
+ res
199
+ }
180
200
}
181
201
182
202
#[ cfg( test) ]
183
203
mod tests {
184
- use crate :: test_utils:: { fixture, open_gpkg_for_update} ;
204
+ use crate :: test_utils:: { fixture, open_dataset_for_update , open_gpkg_for_update} ;
185
205
use crate :: vector:: { Geometry , LayerAccess } ;
186
206
use crate :: Dataset ;
187
207
@@ -241,4 +261,30 @@ mod tests {
241
261
let mut ds = Dataset :: open ( fixture ( "roads.geojson" ) ) . unwrap ( ) ;
242
262
assert ! ( ds. start_transaction( ) . is_err( ) ) ;
243
263
}
264
+
265
+ #[ test]
266
+ fn test_maybe_transaction ( ) {
267
+ let ( _temp_path, mut ds) = open_gpkg_for_update ( & fixture ( "poly.gpkg" ) ) ;
268
+ let orig_feature_count = ds. layer ( 0 ) . unwrap ( ) . feature_count ( ) ;
269
+
270
+ let res = ds. maybe_transaction ( |d| {
271
+ let mut layer = d. layer ( 0 ) . unwrap ( ) ;
272
+ layer. create_feature ( polygon ( ) )
273
+ } ) ;
274
+ assert ! ( res. is_ok( ) ) ;
275
+ assert_eq ! ( ds. layer( 0 ) . unwrap( ) . feature_count( ) , orig_feature_count + 1 ) ;
276
+ }
277
+
278
+ #[ test]
279
+ fn test_maybe_transaction_unsupported ( ) {
280
+ let ( _temp_path, mut ds) = open_dataset_for_update ( & fixture ( "roads.geojson" ) ) ;
281
+ let orig_feature_count = ds. layer ( 0 ) . unwrap ( ) . feature_count ( ) ;
282
+
283
+ let res = ds. maybe_transaction ( |d| {
284
+ let mut layer = d. layer ( 0 ) . unwrap ( ) ;
285
+ layer. create_feature ( polygon ( ) )
286
+ } ) ;
287
+ assert ! ( res. is_ok( ) ) ;
288
+ assert_eq ! ( ds. layer( 0 ) . unwrap( ) . feature_count( ) , orig_feature_count + 1 ) ;
289
+ }
244
290
}
0 commit comments