|
1 | 1 | /*
|
2 |
| - * Copyright 2017-2019 ObjectBox Ltd. All rights reserved. |
| 2 | + * Copyright 2017-2020 ObjectBox Ltd. All rights reserved. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
16 | 16 |
|
17 | 17 | package io.objectbox;
|
18 | 18 |
|
| 19 | +import io.objectbox.annotation.apihint.Beta; |
19 | 20 | import org.greenrobot.essentials.collections.LongHashMap;
|
20 | 21 |
|
21 | 22 | import java.io.Closeable;
|
@@ -66,9 +67,9 @@ public class BoxStore implements Closeable {
|
66 | 67 | @Nullable private static Object relinker;
|
67 | 68 |
|
68 | 69 | /** Change so ReLinker will update native library when using workaround loading. */
|
69 |
| - public static final String JNI_VERSION = "2.6.0-RC"; |
| 70 | + public static final String JNI_VERSION = "2.7.0"; |
70 | 71 |
|
71 |
| - private static final String VERSION = "2.6.0-2020-04-30"; |
| 72 | + private static final String VERSION = "2.7.0-2020-07-30"; |
72 | 73 | private static BoxStore defaultStore;
|
73 | 74 |
|
74 | 75 | /** Currently used DB dirs with values from {@link #getCanonicalPath(File)}. */
|
@@ -138,7 +139,13 @@ public static String getVersionNative() {
|
138 | 139 | */
|
139 | 140 | public static native void testUnalignedMemoryAccess();
|
140 | 141 |
|
141 |
| - static native long nativeCreate(String directory, long maxDbSizeInKByte, int maxReaders, byte[] model); |
| 142 | + /** |
| 143 | + * Creates a native BoxStore instance with FlatBuffer {@link io.objectbox.model.FlatStoreOptions} {@code options} |
| 144 | + * and a {@link ModelBuilder} {@code model}. Returns the handle of the native store instance. |
| 145 | + */ |
| 146 | + static native long nativeCreateWithFlatOptions(byte[] options, byte[] model); |
| 147 | + |
| 148 | + static native boolean nativeIsReadOnly(long store); |
142 | 149 |
|
143 | 150 | static native void nativeDelete(long store);
|
144 | 151 |
|
@@ -170,6 +177,10 @@ static native void nativeRegisterCustomType(long store, int entityId, int proper
|
170 | 177 |
|
171 | 178 | static native boolean nativeIsObjectBrowserAvailable();
|
172 | 179 |
|
| 180 | + native long nativeSizeOnDisk(long store); |
| 181 | + |
| 182 | + native long nativeValidate(long store, long pageLimit, boolean checkLeafLevel); |
| 183 | + |
173 | 184 | static native int nativeGetSupportedSync();
|
174 | 185 |
|
175 | 186 | public static boolean isObjectBrowserAvailable() {
|
@@ -242,10 +253,9 @@ public static boolean isSyncServerAvailable() {
|
242 | 253 | canonicalPath = getCanonicalPath(directory);
|
243 | 254 | verifyNotAlreadyOpen(canonicalPath);
|
244 | 255 |
|
245 |
| - handle = nativeCreate(canonicalPath, builder.maxSizeInKByte, builder.maxReaders, builder.model); |
| 256 | + handle = nativeCreateWithFlatOptions(builder.buildFlatStoreOptions(canonicalPath), builder.model); |
246 | 257 | int debugFlags = builder.debugFlags;
|
247 | 258 | if (debugFlags != 0) {
|
248 |
| - nativeSetDebugFlags(handle, debugFlags); |
249 | 259 | debugTxRead = (debugFlags & DebugFlags.LOG_TRANSACTIONS_READ) != 0;
|
250 | 260 | debugTxWrite = (debugFlags & DebugFlags.LOG_TRANSACTIONS_WRITE) != 0;
|
251 | 261 | } else {
|
@@ -360,6 +370,16 @@ static boolean isFileOpenSync(String canonicalPath, boolean runFinalization) {
|
360 | 370 | }
|
361 | 371 | }
|
362 | 372 |
|
| 373 | + /** |
| 374 | + * The size in bytes occupied by the data file on disk. |
| 375 | + * |
| 376 | + * @return 0 if the size could not be determined (does not throw unless this store was already closed) |
| 377 | + */ |
| 378 | + public long sizeOnDisk() { |
| 379 | + checkOpen(); |
| 380 | + return nativeSizeOnDisk(handle); |
| 381 | + } |
| 382 | + |
363 | 383 | /**
|
364 | 384 | * Explicitly call {@link #close()} instead to avoid expensive finalization.
|
365 | 385 | */
|
@@ -464,6 +484,14 @@ public boolean isClosed() {
|
464 | 484 | return closed;
|
465 | 485 | }
|
466 | 486 |
|
| 487 | + /** |
| 488 | + * Whether the store was created using read-only mode. |
| 489 | + * If true the schema is not updated and write transactions are not possible. |
| 490 | + */ |
| 491 | + public boolean isReadOnly() { |
| 492 | + return nativeIsReadOnly(handle); |
| 493 | + } |
| 494 | + |
467 | 495 | /**
|
468 | 496 | * Closes the BoxStore and frees associated resources.
|
469 | 497 | * This method is useful for unit tests;
|
@@ -926,6 +954,24 @@ public String diagnose() {
|
926 | 954 | return nativeDiagnose(handle);
|
927 | 955 | }
|
928 | 956 |
|
| 957 | + /** |
| 958 | + * Validate database pages, a lower level storage unit (integrity check). |
| 959 | + * Do not call this inside a transaction (currently unsupported). |
| 960 | + * @param pageLimit the maximum of pages to validate (e.g. to limit time spent on validation). |
| 961 | + * Pass zero set no limit and thus validate all pages. |
| 962 | + * @param checkLeafLevel Flag to validate leaf pages. These do not point to other pages but contain data. |
| 963 | + * @return Number of pages validated, which may be twice the given pageLimit as internally there are "two DBs". |
| 964 | + * @throws DbException if validation failed to run (does not tell anything about DB file consistency). |
| 965 | + * @throws io.objectbox.exception.FileCorruptException if the DB file is actually inconsistent (corrupt). |
| 966 | + */ |
| 967 | + @Beta |
| 968 | + public long validate(long pageLimit, boolean checkLeafLevel) { |
| 969 | + if (pageLimit < 0) { |
| 970 | + throw new IllegalArgumentException("pageLimit must be zero or positive"); |
| 971 | + } |
| 972 | + return nativeValidate(handle, pageLimit, checkLeafLevel); |
| 973 | + } |
| 974 | + |
929 | 975 | public int cleanStaleReadTransactions() {
|
930 | 976 | return nativeCleanStaleReadTransactions(handle);
|
931 | 977 | }
|
|
0 commit comments