Package io.objectbox

Class BoxStore

java.lang.Object
io.objectbox.BoxStore
All Implemented Interfaces:
Closeable, AutoCloseable

@ThreadSafe public class BoxStore extends Object implements Closeable
An ObjectBox database that provides Boxes to put and get objects of specific entity classes (see boxFor(Class)). To get an instance of this class use MyObjectBox.builder().
  • Field Details

    • IN_MEMORY_PREFIX

      public static final String IN_MEMORY_PREFIX
      Prefix supplied with database directory to signal a file-less and in-memory database should be used.
      See Also:
    • JNI_VERSION

      public static final String JNI_VERSION
      ReLinker uses this as a suffix for the extracted shared library file. If different, it will update it. Should be unique to avoid conflicts.
      See Also:
  • Method Details

    • getContext

      @Nullable @Internal public static Object getContext()
    • getRelinker

      @Nullable @Internal public static Object getRelinker()
    • getDefault

      public static BoxStore getDefault()
      Convenience singleton instance which gets set up using BoxStoreBuilder.buildDefault().

      Note: for better testability, you can usually avoid singletons by storing a BoxStore instance in some application scope object and pass it along.

    • clearDefaultStore

      public static boolean clearDefaultStore()
      Clears the convenience instance.

      Note: This is usually not required (for testability, please see the comment of getDefault()).

      Returns:
      true if a default store was available before
    • getVersion

      public static String getVersion()
      Gets the Version of ObjectBox Java.
    • getVersionNative

      public static String getVersionNative()
      Gets the Version of ObjectBox Core.
    • hasFeature

      public static boolean hasFeature(io.objectbox.internal.Feature feature)
    • isObjectBrowserAvailable

      public static boolean isObjectBrowserAvailable()
    • isSyncAvailable

      public static boolean isSyncAvailable()
    • isSyncServerAvailable

      public static boolean isSyncServerAvailable()
    • isDatabaseOpen

      public static boolean isDatabaseOpen(Object context, @Nullable String dbNameOrNull) throws IOException
      Using an Android Context and an optional database name, as configured with BoxStoreBuilder.name(String), checks if the associated database files are in use by a BoxStore instance.

      Use this to check that database files are not open before copying or deleting them.

      Throws:
      IOException
    • isDatabaseOpen

      public static boolean isDatabaseOpen(@Nullable File baseDirectoryOrNull, @Nullable String dbNameOrNull) throws IOException
      Using an optional base directory, as configured with BoxStoreBuilder.baseDirectory(File), and an optional database name, as configured with BoxStoreBuilder.name(String), checks if the associated database files are in use by a BoxStore instance.

      Use this to check that database files are not open before copying or deleting them.

      Throws:
      IOException
    • isDatabaseOpen

      public static boolean isDatabaseOpen(File directory) throws IOException
      Using a directory, as configured with BoxStoreBuilder.directory(File), checks if the associated database files are in use by a BoxStore instance.

      Use this to check that database files are not open before copying or deleting them.

      Throws:
      IOException
    • sysProcMeminfoKb

      @Experimental public static long sysProcMeminfoKb(String key)
      Linux only: extracts a kB value from /proc/meminfo (system wide memory information). A couple of interesting keys (from 'man proc'): - MemTotal: Total usable RAM (i.e., physical RAM minus a few reserved bits and the kernel binary code). - MemFree: The sum of LowFree+HighFree. - MemAvailable: An estimate of how much memory is available for starting new applications, without swapping.
      Parameters:
      key - The string identifying the wanted line from /proc/meminfo to extract a Kb value from. E.g. "MemTotal".
      Returns:
      Kb value or 0 on failure
    • sysProcStatusKb

      @Experimental public static long sysProcStatusKb(String key)
      Linux only: extracts a kB value from /proc/self/status (process specific information). A couple of interesting keys (from 'man proc'): - VmPeak: Peak virtual memory size. - VmSize: Virtual memory size. - VmHWM: Peak resident set size ("high water mark"). - VmRSS: Resident set size. Note that the value here is the sum of RssAnon, RssFile, and RssShmem. - RssAnon: Size of resident anonymous memory. (since Linux 4.5). - RssFile: Size of resident file mappings. (since Linux 4.5). - RssShmem: Size of resident shared memory (includes System V shared memory, mappings from tmpfs(5), and shared anonymous mappings). (since Linux 4.5). - VmData, VmStk, VmExe: Size of data, stack, and text segments. - VmLib: Shared library code size.
      Parameters:
      key - The string identifying the wanted line from /proc/self/status to extract a Kb value from. E.g. "VmSize".
      Returns:
      Kb value or 0 on failure
    • sizeOnDisk

      @Deprecated public long sizeOnDisk()
      Deprecated.
      Use getDbSize() or getDbSizeOnDisk() instead which properly handle in-memory databases.
      The size in bytes occupied by the data file on disk.
      Returns:
      0 if the size could not be determined (does not throw unless this store was already closed)
    • getDbSize

      public long getDbSize()
      Get the size of this store. For a disk-based store type, this corresponds to the size on disk, and for the in-memory store type, this is roughly the used memory bytes occupied by the data.
      Returns:
      The size in bytes of the database, or 0 if the file does not exist or some error occurred.
    • getDbSizeOnDisk

      public long getDbSizeOnDisk()
      The size in bytes occupied by the database on disk (if any).
      Returns:
      The size in bytes of the database on disk, or 0 if the underlying database is in-memory only or the size could not be determined.
    • finalize

      protected void finalize() throws Throwable
      Closes this if this is finalized.

      Explicitly call close() instead to avoid expensive finalization.

      Overrides:
      finalize in class Object
      Throws:
      Throwable
    • getEntityTypeIdOrThrow

      @Internal public int getEntityTypeIdOrThrow(Class<?> entityClass)
    • getAllEntityClasses

      public Collection<Class<?>> getAllEntityClasses()
    • beginTx

      @Internal public io.objectbox.Transaction beginTx()
      Internal, low level method: use runInTx(Runnable) instead.
    • beginReadTx

      @Internal public io.objectbox.Transaction beginReadTx()
      Internal, low level method: use runInReadTx(Runnable) instead. Begins a transaction for read access only. Note: there may be only one read transaction per thread.
    • isClosed

      public boolean isClosed()
      If this was closed.
    • isReadOnly

      public boolean isReadOnly()
      Whether the store was created using read-only mode. If true the schema is not updated and write transactions are not possible.
    • close

      public void close()
      Closes this BoxStore and releases associated resources.

      Before calling, all database operations must have finished (there are no more active transactions).

      If that is not the case, the method will briefly wait on any active transactions, but then will forcefully close them to avoid crashes and print warning messages ("Transactions are still active"). If this occurs, analyze your code to make sure all database operations, notably in other threads or data observers, are properly finished.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
    • deleteAllFiles

      public boolean deleteAllFiles()
      Danger zone! This will delete all data (files) of this BoxStore! You must call close() before and read the docs of that method carefully!

      A safer alternative: use the static deleteAllFiles(File) method before opening the BoxStore.

      Returns:
      true if the directory 1) was deleted successfully OR 2) did not exist in the first place. Note: If false is returned, any number of files may have been deleted before the failure happened.
    • deleteAllFiles

      public static boolean deleteAllFiles(File objectStoreDirectory)
      Danger zone! This will delete all files in the given directory!

      No BoxStore may be alive using the given directory. E.g. call this before building a store. When calling this after closing a store, read the docs of that method carefully first!

      If no name was specified when building the store, use like:

      
           BoxStore.deleteAllFiles(new File(BoxStoreBuilder.DEFAULT_NAME));
       

      For an in-memory database, this will just clean up the in-memory database.

      Parameters:
      objectStoreDirectory - directory to be deleted; this is the value you previously provided to BoxStoreBuilder.directory(File)
      Returns:
      true if the directory 1) was deleted successfully OR 2) did not exist in the first place. Note: If false is returned, any number of files may have been deleted before the failure happened.
      Throws:
      IllegalStateException - if the given directory is still used by an open BoxStore.
    • deleteAllFiles

      public static boolean deleteAllFiles(Object androidContext, @Nullable String customDbNameOrNull)
      Danger zone! This will delete all files in the given directory!

      No BoxStore may be alive using the given name.

      If you did not use a custom name with BoxStoreBuilder, you can pass "new File(BoxStoreBuilder.DEFAULT_NAME)".

      Parameters:
      androidContext - provide an Android Context like Application or Service
      customDbNameOrNull - use null for default name, or the name you previously provided to BoxStoreBuilder.name(String).
      Returns:
      true if the directory 1) was deleted successfully OR 2) did not exist in the first place. Note: If false is returned, any number of files may have been deleted before the failure happened.
      Throws:
      IllegalStateException - if the given name is still used by a open BoxStore.
    • deleteAllFiles

      public static boolean deleteAllFiles(@Nullable File baseDirectoryOrNull, @Nullable String customDbNameOrNull)
      Danger zone! This will delete all files in the given directory!

      No BoxStore may be alive using the given directory.

      If you did not use a custom name with BoxStoreBuilder, you can pass "new File(BoxStoreBuilder.DEFAULT_NAME)".

      Parameters:
      baseDirectoryOrNull - use null for no base dir, or the value you previously provided to BoxStoreBuilder.baseDirectory(File)
      customDbNameOrNull - use null for default name, or the name you previously provided to BoxStoreBuilder.name(String).
      Returns:
      true if the directory 1) was deleted successfully OR 2) did not exist in the first place. Note: If false is returned, any number of files may have been deleted before the failure happened.
      Throws:
      IllegalStateException - if the given directory (+name) is still used by a open BoxStore.
    • removeAllObjects

      public void removeAllObjects()
      Removes all objects from all types ("boxes"), e.g. deletes all database content (excluding meta data like the data model). This typically performs very quickly (e.g. faster than Box.removeAll()).

      Note that this does not reclaim disk space: the already reserved space for the DB file(s) is used in the future resulting in better performance because no/less disk allocation has to be done.

      If you want to reclaim disk space, delete the DB file(s) instead:

    • unregisterTransaction

      @Internal public void unregisterTransaction(io.objectbox.Transaction transaction)
    • boxFor

      public <T> Box<T> boxFor(Class<T> entityClass)
      Returns a Box for the given type. Objects are put into (and get from) their individual Box.

      Creates a Box only once and then always returns the cached instance.

    • runInTx

      public void runInTx(Runnable runnable)
      Runs the given runnable inside a transaction.

      Efficiency notes: it is advised to run multiple puts in a transaction because each commit requires an expensive disk synchronization.

    • runInReadTx

      public void runInReadTx(Runnable runnable)
      Runs the given runnable inside a read(-only) transaction. Multiple read transactions can occur at the same time. This allows multiple read operations (gets) using a single consistent state of data. Also, for a high number of read operations (thousands, e.g. in loops), it is advised to run them in a single read transaction for efficiency reasons.
    • callInReadTxWithRetry

      @Experimental public <T> T callInReadTxWithRetry(Callable<T> callable, int attempts, int initialBackOffInMs, boolean logAndHeal)
      Calls callInReadTx(Callable) and retries in case a DbException is thrown. If the given amount of attempts is reached, the last DbException will be thrown. Experimental: API might change.
    • callInReadTx

      public <T> T callInReadTx(Callable<T> callable)
      Calls the given callable inside a read(-only) transaction. Multiple read transactions can occur at the same time. This allows multiple read operations (gets) using a single consistent state of data. Also, for a high number of read operations (thousands, e.g. in loops), it is advised to run them in a single read transaction for efficiency reasons. Note that an exception thrown by the given Callable will be wrapped in a RuntimeException, if the exception is not a RuntimeException itself.
    • callInTx

      public <R> R callInTx(Callable<R> callable) throws Exception
      Like runInTx(Runnable), but allows returning a value and throwing an exception.
      Throws:
      Exception
    • callInTxNoException

      public <R> R callInTxNoException(Callable<R> callable)
      Like callInTx(Callable), but throws no Exception. Any Exception thrown in the Callable is wrapped in a RuntimeException.
    • runInTxAsync

      public void runInTxAsync(Runnable runnable, @Nullable TxCallback<Void> callback)
      Runs the given Runnable as a transaction in a separate thread. Once the transaction completes the given callback is called (callback may be null).

      See also runInTx(Runnable).

    • callInTxAsync

      public <R> void callInTxAsync(Callable<R> callable, @Nullable TxCallback<R> callback)
      Runs the given Runnable as a transaction in a separate thread. Once the transaction completes the given callback is called (callback may be null).

      * See also callInTx(Callable).

    • diagnose

      public String diagnose()
      Gives info that can be useful for debugging.
      Returns:
      String that is typically logged by the application.
    • validate

      @Beta public long validate(long pageLimit, boolean checkLeafLevel)
      Validate database pages, a lower level storage unit (integrity check). Do not call this inside a transaction (currently unsupported).
      Parameters:
      pageLimit - the maximum of pages to validate (e.g. to limit time spent on validation). Pass zero set no limit and thus validate all pages.
      checkLeafLevel - Flag to validate leaf pages. These do not point to other pages but contain data.
      Returns:
      Number of pages validated, which may be twice the given pageLimit as internally there are "two DBs".
      Throws:
      DbException - if validation failed to run (does not tell anything about DB file consistency).
      FileCorruptException - if the DB file is actually inconsistent (corrupt).
    • cleanStaleReadTransactions

      public int cleanStaleReadTransactions()
    • closeThreadResources

      public void closeThreadResources()
      Frees any cached resources tied to the calling thread (e.g. readers).

      Call this method from a thread that is about to be shut down or likely not to use ObjectBox anymore. Careful: ensure all transactions, like a query fetching results, have finished before.

      This method calls Box.closeThreadResources() for all initiated boxes (boxFor(Class)).

    • subscribe

      public SubscriptionBuilder<Class> subscribe()
      A DataObserver can be subscribed to data changes using the returned builder. The observer is supplied via SubscriptionBuilder.observer(DataObserver) and will be notified once a transaction is committed and will receive changes to any object class.

      Threading notes: All observers are notified from one separate thread (pooled). Observers are not notified in parallel. The notification order is the same as the subscription order, although this may not always be guaranteed in the future.

      Note that failed or aborted transaction do not trigger observers.

    • subscribe

      public <T> SubscriptionBuilder<Class<T>> subscribe(Class<T> forClass)
      Like subscribe(), but wires the supplied @DataObserver only to the given object class for notifications.
    • startObjectBrowser

      @Experimental @Nullable public String startObjectBrowser()
    • startObjectBrowser

      @Experimental @Nullable public String startObjectBrowser(int port)
    • startObjectBrowser

      @Experimental @Nullable public String startObjectBrowser(String urlToBindTo)
    • stopObjectBrowser

      @Experimental public boolean stopObjectBrowser()
    • getObjectBrowserPort

      @Experimental public int getObjectBrowserPort()
    • isObjectBrowserRunning

      public boolean isObjectBrowserRunning()
    • setDbExceptionListener

      public void setDbExceptionListener(@Nullable DbExceptionListener dbExceptionListener)
      Sets a listener that will be called when an exception is thrown. Replaces a previously set listener. Set to null to remove the listener.

      This for example allows central error handling or special logging for database-related exceptions.

    • internalScheduleThread

      @Internal public Future<?> internalScheduleThread(Runnable runnable)
    • internalThreadPool

      @Internal public ExecutorService internalThreadPool()
    • isDebugRelations

      @Internal public boolean isDebugRelations()
    • internalQueryAttempts

      @Internal public int internalQueryAttempts()
    • internalFailedReadTxAttemptCallback

      @Internal public TxCallback<?> internalFailedReadTxAttemptCallback()
    • getNativeStore

      public long getNativeStore()
      Gets the reference to the native store. Can be used with the C API to use the same store, e.g. via JNI, by passing it on to obx_store_wrap().

      Throws if the store is closed.

      The procedure is like this:
      1) you create a BoxStore on the Java side
      2) you call this method to get the native store pointer
      3) you pass the native store pointer to your native code (e.g. via JNI)
      4) your native code calls obx_store_wrap() with the native store pointer to get a OBX_store pointer
      5) Using the OBX_store pointer, you can use the C API.

      Note: Once you close() this BoxStore, do not use it from the C API.

    • isNativeStoreClosed

      @Internal public boolean isNativeStoreClosed()
      For internal use only. This API might change or be removed with a future release.

      Returns if the native Store was closed.

      This is true shortly after close() was called and isClosed() returns true.

    • getSyncClient

      @Nullable public SyncClient getSyncClient()
      Returns the SyncClient associated with this store. To create one see Sync.