|
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