Class Database

java.lang.Object
com.syzygy.events.database.Database
All Implemented Interfaces:
com.google.firebase.firestore.EventListener<com.google.firebase.firestore.DocumentSnapshot>

public class Database extends Object implements com.google.firebase.firestore.EventListener<com.google.firebase.firestore.DocumentSnapshot>
The handler for the Firestore database

Contains a reference to the database and listens for changes.

Provides methods to retrieve data and update data within the database

  • Field Details

    • errorListeners

      private final List<Consumer<RuntimeException>> errorListeners
      Set of listeners which are called whenever an error occurs
    • cache

      private final HashMap<String,DatabaseInstance<?>> cache
      The currently retrieved instances

      Each instance is identified by their database id

      See Also:
    • constants

      @NonNull android.content.res.Resources constants
    • db

      private final com.google.firebase.firestore.FirebaseFirestore db
      The firestore database
    • storage

      private final com.google.firebase.storage.StorageReference storage
      The firebase storage for images
    • trackCreatedInstances

      private final boolean trackCreatedInstances
      If all created instances should be tracked
    • trackedInstances

      private final List<DatabaseInstance<?>> trackedInstances
  • Constructor Details

    • Database

      public Database(@NonNull android.content.res.Resources constants)
    • Database

      public Database(@NonNull android.content.res.Resources constants, com.google.firebase.firestore.FirebaseFirestore db, com.google.firebase.storage.StorageReference storage)
  • Method Details

    • setConstants

      public void setConstants(@NonNull android.content.res.Resources constants)
    • getTrackedInstances

      public List<DatabaseInstance<?>> getTrackedInstances()
      Gets all tracked instances reference
      Returns:
      A list if tracked instances is set to true
    • returnInstance

      <T extends DatabaseInstance<T>> void returnInstance(@Observes DatabaseInstance<T> instance) throws IllegalStateException
      Deletes the instance from cache
      Type Parameters:
      T - The type of the instance
      Parameters:
      instance - The instance that should be removed from cache
      Throws:
      IllegalStateException - If the instance still has references
    • updateDatabase

      <T extends DatabaseInstance<T>> void updateDatabase(@Observes DatabaseInstance<T> instance) throws IllegalStateException
      Updates the database to match the instance
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The database instance
      Throws:
      IllegalStateException - if the instance is in an illegal state DatabaseInstance.assertNotIllegalState()
      See Also:
    • deleteFromDatabase

      <T extends DatabaseInstance<T>> void deleteFromDatabase(@Observes DatabaseInstance<T> instance) throws IllegalStateException
      Removes the instance from the database
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The database instance
      Throws:
      IllegalStateException - if the instance is in an illegal state DatabaseInstance.assertNotIllegalState()
      See Also:
    • addToDatabase

      <T extends DatabaseInstance<T>> void addToDatabase(@Observes DatabaseInstance<T> instance) throws IllegalStateException
      Adds the instance to the database
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The database instance
      Throws:
      IllegalStateException - if the instance is in an illegal state DatabaseInstance.assertNotIllegalState()
      See Also:
    • modifyField

      void modifyField(@NonNull Database.Collections collection, @NonNull String documentId, int propertyNameId, Object newValue, Consumer<Boolean> onComplete)
      Updates the field in the instance given by the collection and documentID without loading the instance.

      Does not do any cascading.

      Parameters:
      collection - The collection of the instance to update
      documentId - The documentID of the instance to update
      propertyNameId - The id of the property to update
      newValue - The new value to be put in the property
      onComplete - called on completion with if the update occurred successfully.
    • bulkModifyField

      void bulkModifyField(com.google.firebase.firestore.Query q, int propertyNameId, Object newValue, Consumer<Boolean> onComplete)
      Updates the field in all instances returned by the query without loading the instances

      Does not do any cascading.

      Parameters:
      q - The query which returns all documents that should be updated
      propertyNameId - The id of the property to update
      newValue - The new value to be put in the property
      onComplete - called on completion with if the update occurred successfully.
    • updateFromDatabase

      <T extends DatabaseInstance<T>> void updateFromDatabase(@Observes DatabaseInstance<T> instance) throws IllegalStateException
      Retrieves the document properties of the instance and updates the instance to match
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The database instance
      Throws:
      IllegalStateException - if the instance is in an illegal state DatabaseInstance.assertNotIllegalState()
      See Also:
    • initializeFromDatabase

      <T extends DatabaseInstance<T>> void initializeFromDatabase(@Observes DatabaseInstance<T> instance, Database.InitializationListener<T> onComplete) throws IllegalStateException
      Retrieves the document properties of the instance and sets the instance to match
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The database instance
      onComplete - called when complete
      Throws:
      IllegalStateException - if the instance is already initialized
      See Also:
    • initializeFromDatabase

      <T extends DatabaseInstance<T>> void initializeFromDatabase(@Observes DatabaseInstance<T> instance, com.google.firebase.firestore.DocumentSnapshot snapshot, Database.InitializationListener<T> onComplete) throws IllegalStateException, IllegalArgumentException
      Initializes and instance using the data in the given snapshot
      Type Parameters:
      T - The instance type
      Parameters:
      instance - The instance
      snapshot - The document snapshot
      onComplete - called when complete
      Throws:
      IllegalStateException - If the instance is already initialized
      IllegalArgumentException - If the document does not match the instance
      See Also:
    • getInstance

      @MustStir public <T extends DatabaseInstance<T>> void getInstance(Database.Collections collection, String documentID, Database.InitializationListener<T> listener)
      Returns the DatabaseInstance of the document within the collection.

      If the DatabaseInstance already exists in the cache, the cache object reference count is increased, and the object is returned

      If the DatabaseInstance does not exists in the cache, a new instance is retrieved from the database. The instance is added to the database

      If provided, the initializeListener} will be triggered once the instance has been populated.

      If the id does not exists, the listener will be called with success = false and in an illegal state

      Type Parameters:
      T - The type of instance
      Parameters:
      collection - The collection that this instance resides in
      documentID - The id of the instance within the collection
      See Also:
    • getInstance

      @MustStir public <T extends DatabaseInstance<T>> void getInstance(Database.Collections collection, String documentID, Database.InitializationListener<T> listener, @Nullable com.google.firebase.firestore.DocumentSnapshot document) throws IllegalArgumentException
      Returns the DatabaseInstance of the document within the collection given the document snapshot.

      If the DatabaseInstance already exists in the cache, the cache object reference count is increased, and the object is returned

      If the DatabaseInstance does not exists in the cache, a new instance is created using the given document. The instance is added to the database

      If provided, the initializeListener} will be triggered once the instance has been populated.

      If the id does not exists, the listener will be called with success = false and in an illegal state

      Type Parameters:
      T - The type of instance
      Parameters:
      collection - The collection that this instance resides in
      documentID - The id of the instance within the collection
      Throws:
      IllegalArgumentException - if the instance must be created and the document does not match the instance
      See Also:
    • getInstanceFromCache

      @MustStir public <T extends DatabaseInstance<T>> T getInstanceFromCache(Database.Collections collection, String documentID)
      Gets an instance from the current cache
      Type Parameters:
      T - The type of the instance
      Parameters:
      collection - The collection of the instance
      documentID - The documentID of the instance
      Returns:
      The instance from cache. If the instance is not in cache, returns null
    • replaceImage

      @StirsDeep(what="The image given to the method") public <W> void replaceImage(@Nullable android.net.Uri newImage, @Nullable @Stirs(when="if new image is set successfully") Image oldImage, String locName, Database.Collections collection, String documentID, BiConsumer<Image,BiConsumer<W,Boolean>> updateVariable, BiConsumer<W,Boolean> onComplete)
      Creates the image then calls the method. One completion of both or failure of one, calls the onComplete. Dissolves the image before calling onComplete. All data is passed from oldImage to newImage. If oldImage is null, then the data passed as arguments is used
      Type Parameters:
      W - The type of data to be passed from the method to the onComplete
      Parameters:
      newImage - The image to create and set
      oldImage - The previous image that will be deleted on the successful set of the new image
      locName - The name of the instance that will contain the image if oldImage is null
      collection - The collection of the instance that will contain the image if oldImage is null
      documentID - The documentId of the instance that will contain the image if oldImage is null
      updateVariable - The method to call after creating the image. This method should update the variable to the new image The consumer must be called with if the setting succeeded. If false is returned, deletes the new image. If true is returned, deletes the old image Any data that should be passed to the onComplete method can be given by the first param. Success should be passed in the second param.
      onComplete - The method to call after all has succeeded. The data returned by the method will be passed in the first argument.
    • replaceImage

      @StirsDeep(what="The image given to the method") public <W> void replaceImage(@Nullable android.net.Uri newImage, @NonNull @Stirs(when="if new image is set successfully") Image oldImage, BiConsumer<Image,BiConsumer<W,Boolean>> updateVariable, BiConsumer<W,Boolean> onComplete)
      Creates the image then calls the method. One completion of both or failure of one, calls the onComplete. Dissolves the image before calling onComplete. All data is passed from oldImage to newImage.
      Type Parameters:
      W - The type of data to be passed from the method to the onComplete
      Parameters:
      newImage - The image to create and set
      oldImage - The previous image that will be deleted on the successful set of the new image
      updateVariable - The method to call after creating the image. This method should update the variable to the new image The consumer must be called with if the setting succeeded. If false is returned, deletes the new image. If true is returned, deletes the old image Any data that should be passed to the onComplete method can be given by the first param. Success should be passed in the second param.
      onComplete - The method to call after all has succeeded. The data returned by the method will be passed in the first argument.
    • createImageAndThen

      @Observes @StirsDeep(what="The image given to the method") public <W> void createImageAndThen(@NonNull android.net.Uri image, String locName, Database.Collections collection, String documentID, BiConsumer<Image,BiConsumer<W,Boolean>> method, BiConsumer<W,Boolean> onComplete)
      Creates the image then calls the method. One completion of both or failure of one, calls the onComplete. Dissolves the image before calling onComplete
      Type Parameters:
      W - The type of data to be passed from the method to the onComplete
      Parameters:
      image - The image to create
      locName - The name of the instance that will contain the image
      collection - The collection of the instance that will contain the image
      documentID - The documentId of the instance that will contain the image
      method - The method to call after creating the image. The consumer must be called with if the method succeeded. If false if returned, deletes the image. Any data that should be passed to the onComplete method can be given by the first param. Success should be passed in the second param
      onComplete - The method to call after all has succeeded. The data returned by the method will be passed in the first argument.
    • createNewInstance

      @MustStir public <T extends DatabaseInstance<T>> Set<Integer> createNewInstance(Database.Collections collection, String documentID, @Dilutes Map<Integer,Object> data, @Nullable android.net.Uri image, String locName, Database.InitializationListener<T> listener)
      Validates the information and creates a new instance of the collection and the associated image.

      If one or more properties are invalid, does not create the instance, and the listener is not called.

      Creates the image, if the image is created successfully, creates the instance.

      Type Parameters:
      T - The type of instance
      Parameters:
      collection - The collection to which the instance belongs
      documentID - The documentID of the instance
      data - The data to initialize the instance with (resId -> value)
      image - The uri of the image
      locName - The name of the location where the image is stored
      listener - The initialization listener. The listener will be called once the instance is populated. If the documentID already exists in the database, the listener is called with success = false and the instance in an illegal state. The listener is called before the database is updated with information
      Returns:
      The invalid property ids
      See Also:
    • createNewInstance

      @MustStir public <T extends DatabaseInstance<T>> Set<Integer> createNewInstance(Database.Collections collection, String documentID, @Dilutes Map<Integer,Object> data, Database.InitializationListener<T> listener)
      Validates the information and creates a new instance of the collection.

      If one or more properties are invalid, does not create the instance, and the listener is not called.

      Type Parameters:
      T - The type of instance
      Parameters:
      collection - The collection to which the instance belongs
      documentID - The documentID of the instance
      data - The data to initialize the instance with (resid -> value)
      listener - The initialization listener. The listener will be called once the instance is populated. If the documentID already exists in the database, the listener is called with success = false and the instance in an illegal state. The listener is called before the database is updated with information
      Returns:
      The set of invalid properties.
    • convertIDMapToNames

      public Map<String,Object> convertIDMapToNames(Map<Integer,Object> data)
      Converts an ID property map to a Name property map
      Parameters:
      data - The resID-value map where resID is the res id to the property name
      Returns:
      The name-value map where name is the name of the property
    • addFileToStorage

      public void addFileToStorage(String fileName, android.net.Uri file, Consumer<android.net.Uri> listener)
      Adds the file to the database;
      Parameters:
      fileName - The filename
      file - The file
      listener - Called on completion. null if upload failed, otherwise download url
    • getFileExtension

      @Deprecated private String getFileExtension(android.net.Uri fileUri, android.content.ContentResolver contentResolver)
      Deprecated.
    • deleteFile

      public void deleteFile(String fileName, Consumer<Boolean> listener)
      Deletes the image from the storage
      Parameters:
      fileName - The filename including extension (e.g. `folder/image.jpg`)
      listener - Called on completion. true if the deletion was successful
    • onEvent

      public void onEvent(@Nullable com.google.firebase.firestore.DocumentSnapshot value, @Nullable com.google.firebase.firestore.FirebaseFirestoreException error)
      Specified by:
      onEvent in interface com.google.firebase.firestore.EventListener<com.google.firebase.firestore.DocumentSnapshot>
    • throwE

      void throwE(RuntimeException ex)
      Handles an error caused by the database
      Parameters:
      ex - the exception
    • addErrorListener

      public void addErrorListener(Consumer<RuntimeException> listener)
      Adds an error listener. This listener is called whenever an error occurs
      Parameters:
      listener - The listener
    • removeErrorListener

      public void removeErrorListener(Consumer<RuntimeException> listener)
      Removes an error listener.
      Parameters:
      listener - The listener
    • cleanup

      public void cleanup()
      Called to cleanup the database