|
37 | 37 | import io.objectbox.annotation.apihint.Internal;
|
38 | 38 | import io.objectbox.exception.DbException;
|
39 | 39 | import io.objectbox.ideasonly.ModelUpdate;
|
| 40 | +import io.objectbox.model.ValidateOnOpenMode; |
40 | 41 |
|
41 | 42 | /**
|
42 | 43 | * Builds a {@link BoxStore} with optional configurations. The class is not initiated directly; use
|
@@ -91,6 +92,13 @@ public class BoxStoreBuilder {
|
91 | 92 |
|
92 | 93 | int queryAttempts;
|
93 | 94 |
|
| 95 | + boolean readOnly; |
| 96 | + boolean usePreviousCommit; |
| 97 | + boolean usePreviousCommitOnValidationFailure; |
| 98 | + |
| 99 | + int validateOnOpenMode; |
| 100 | + long validateOnOpenPageLimit; |
| 101 | + |
94 | 102 | TxCallback<?> failedReadTxAttemptCallback;
|
95 | 103 |
|
96 | 104 | final List<EntityInfo<?>> entityInfoList = new ArrayList<>();
|
@@ -299,6 +307,85 @@ public BoxStoreBuilder maxSizeInKByte(long maxSizeInKByte) {
|
299 | 307 | return this;
|
300 | 308 | }
|
301 | 309 |
|
| 310 | + /** |
| 311 | + * Open the store in read-only mode: no schema update, no write transactions. |
| 312 | + * <p> |
| 313 | + * It is recommended to use this with {@link #usePreviousCommit()} to ensure no data is lost. |
| 314 | + */ |
| 315 | + public BoxStoreBuilder readOnly() { |
| 316 | + this.readOnly = true; |
| 317 | + return this; |
| 318 | + } |
| 319 | + |
| 320 | + /** |
| 321 | + * Ignores the latest data snapshot (committed transaction state) and uses the previous snapshot instead. |
| 322 | + * When used with care (e.g. backup the DB files first), this option may also recover data removed by the latest |
| 323 | + * transaction. |
| 324 | + * <p> |
| 325 | + * It is recommended to use this with {@link #readOnly()} to ensure no data is lost. |
| 326 | + */ |
| 327 | + public BoxStoreBuilder usePreviousCommit() { |
| 328 | + if (usePreviousCommitOnValidationFailure) { |
| 329 | + throw new IllegalStateException("Can not use together with usePreviousCommitOnValidationFailure()"); |
| 330 | + } |
| 331 | + this.usePreviousCommit = true; |
| 332 | + return this; |
| 333 | + } |
| 334 | + |
| 335 | + /** |
| 336 | + * If consistency checks fail during opening the DB, ObjectBox |
| 337 | + * automatically switches to the previous commit. This way, this constitutes |
| 338 | + * an auto-recover mode from severe failures. |
| 339 | + * <p> |
| 340 | + * However, keep in mind that any consistency failure |
| 341 | + * is an indication that something is very wrong with OS/hardware and thus you may possibly alert your users. |
| 342 | + * |
| 343 | + * @see #usePreviousCommit() |
| 344 | + * @see #validateOnOpen(int) |
| 345 | + */ |
| 346 | + public BoxStoreBuilder usePreviousCommitOnValidationFailure() { |
| 347 | + if (usePreviousCommit) { |
| 348 | + throw new IllegalStateException("Can not use together with usePreviousCommit()"); |
| 349 | + } |
| 350 | + this.usePreviousCommitOnValidationFailure = true; |
| 351 | + return this; |
| 352 | + } |
| 353 | + |
| 354 | + /** |
| 355 | + * When a database is opened, ObjectBox can perform additional consistency checks on its database structure. |
| 356 | + * Reliable file systems already guarantee consistency, so this is primarily meant to deal with unreliable |
| 357 | + * OSes, file systems, or hardware. |
| 358 | + * <p> |
| 359 | + * Note: ObjectBox builds upon ACID storage, which already has strong consistency mechanisms in place. |
| 360 | + * |
| 361 | + * @param validateOnOpenMode One of {@link ValidateOnOpenMode}. |
| 362 | + */ |
| 363 | + public BoxStoreBuilder validateOnOpen(int validateOnOpenMode) { |
| 364 | + if (validateOnOpenMode < ValidateOnOpenMode.None || validateOnOpenMode > ValidateOnOpenMode.Full) { |
| 365 | + throw new IllegalArgumentException("Must be one of ValidateOnOpenMode"); |
| 366 | + } |
| 367 | + this.validateOnOpenMode = validateOnOpenMode; |
| 368 | + return this; |
| 369 | + } |
| 370 | + |
| 371 | + /** |
| 372 | + * To fine-tune {@link #validateOnOpen(int)}, you can specify a limit on how much data is looked at. |
| 373 | + * This is measured in "pages" with a page typically holding 4000. |
| 374 | + * Usually a low number (e.g. 1-20) is sufficient and does not impact startup performance significantly. |
| 375 | + * <p> |
| 376 | + * This can only be used with {@link ValidateOnOpenMode#Regular} and {@link ValidateOnOpenMode#WithLeaves}. |
| 377 | + */ |
| 378 | + public BoxStoreBuilder validateOnOpenPageLimit(long limit) { |
| 379 | + if (validateOnOpenMode != ValidateOnOpenMode.Regular && validateOnOpenMode != ValidateOnOpenMode.WithLeaves) { |
| 380 | + throw new IllegalStateException("Must call validateOnOpen(mode) with mode Regular or WithLeaves first"); |
| 381 | + } |
| 382 | + if (limit < 1) { |
| 383 | + throw new IllegalArgumentException("limit must be positive"); |
| 384 | + } |
| 385 | + this.validateOnOpenPageLimit = limit; |
| 386 | + return this; |
| 387 | + } |
| 388 | + |
302 | 389 | /**
|
303 | 390 | * @deprecated Use {@link #debugFlags} instead.
|
304 | 391 | */
|
|
0 commit comments