content: package com.coveros.training.persistence;
  
  import com.coveros.training.authentication.domainobjects.User;
  import com.coveros.training.library.domainobjects.Book;
  import com.coveros.training.library.domainobjects.Borrower;
  import com.coveros.training.library.domainobjects.Loan;
  
  import java.sql.Date;
  import java.util.List;
  import java.util.Optional;
  
  /**
   * This is the only place in our application allowed to speak
   * directly to the database.  All business functionality that
   * requires database access must go through here.
   */
  public interface IPersistenceLayer {
  
  
      /*
       * ==========================================================
       * ==========================================================
       *
       *  Library Persistence Functions
       *
       * ==========================================================
       * ==========================================================
       */
  
  
      /**
       * Creates a new borrower in the database
       *
       * @param borrowerName the name of the borrower
       * @return a long id representing its id in the database.  Generated by the database.
       */
      long saveNewBorrower(String borrowerName);
  
  
      /**
       * Creates a new loan of a book in the database.
       *
       * @param book       a book we have to loan out
       * @param borrower   a person who is borrowing the book
       * @param borrowDate the date this book was borrowed
       * @return a long id representing its id in the database.  Generated by the database.
       */
      long createLoan(Book book, Borrower borrower, Date borrowDate);
  
  
      /**
       * Creates a new book in the database
       *
       * @param bookTitle the String title of a book
       * @return a long id representing its id in the database.  Generated by the database.
       */
      long saveNewBook(String bookTitle);
  
  
      /**
       * If we already have a borrower, this command allows us to change
       * their values (except for their id)
       *
       * @param id           the id of a borrower (a constant)
       * @param borrowerName the name of a borrower, which we can change.
       */
      void updateBorrower(long id, String borrowerName);
  
  
      /**
       * Delete a book from the database
       * @param id the identifier for a book
       */
      void deleteBook(long id);
  
  
      /**
       * Delete a borrower from the database
       * @param id the identifier for a borrower
       */
      void deleteBorrower(long id);
  
  
      /**
       * Given the id for a borrower, this command returns their name.
       *
       * @param id a borrower's id.
       * @return the borrower's name, or empty
       */
      Optional<String> getBorrowerName(long id);
  
  
      /**
       * Searches for a borrower by name.  Returns full details
       * if found.  return empty borrower data if not found.
       *
       * @param borrowerName the name of a borrower
       * @return a valid borrower, or empty
       */
      Optional<Borrower> searchBorrowerDataByName(String borrowerName);
  
  
      /**
       * Find a book by its title
       * @param bookTitle the title of a book
       * @return a valid book, or empty
       */
      Optional<Book> searchBooksByTitle(String bookTitle);
  
  
      /**
       * Find a book by its id
       * @param id the database id for a book
       * @return a valid book, or empty
       */
      Optional<Book> searchBooksById(long id);
  
  
      /**
       * Find a borrower by their id
       * @param id the database id of a borrower
       * @return a borrower, or empty
       */
      Optional<Borrower> searchBorrowersById(long id);
  
  
      /**
       * List all the books in the library
       * @return all the books, or empty
       */
      Optional<List<Book>> listAllBooks();
  
  
      /**
       * List all the books currently available for borrowing
       * @return all the available books, or empty
       */
      Optional<List<Book>> listAvailableBooks();
  
  
      /**
       * List all the borrowers registered in the library
       * @return a list of all the borrowers, or empty
       */
      Optional<List<Borrower>> listAllBorrowers();
  
  
      /**
       * Search for book loans by borrower
       *
       * A borrower may have more than one loan.  But a book
       * can only be loaned to one borrower.  That is why when we
       * search for loans by borrower, we may get multiple loans
       * back, but when we search by book, we only get one back.
       * A book cannot be loaned to two people at the same time!
       *
       * @param borrower a given borrower registered with the library
       * @return a list of loans, or empty
       */
      Optional<List<Loan>> searchForLoanByBorrower(Borrower borrower);
  
  
      /**
       * A book can only be loaned to one person.  Find that loan
       * @param book the book used to search for the loan
       * @return a loan, or empty
       */
      Optional<Loan> searchForLoanByBook(Book book);
  
  
      /*
       * ==========================================================
       * ==========================================================
       *
       *  Authentication Persistence Functions
       *
       * ==========================================================
       * ==========================================================
       */
  
  
      /**
       * Save a new user to the database
       *
       * @param username a String name of a user
       * @return a long id representing its id in the database.  Generated by the database.
       */
      long saveNewUser(String username);
  
  
      /**
       * Change the password for a user.
       *
       * We store the user's hash, not their password.  This method
       * first hashes the password, then stores that.
       * @param id the database id for a given user
       * @param password the new password, which we'll hash first before storing
       */
      void updateUserWithPassword(long id, String password);
  
  
      /**
       * Search the database for a given borrower by their name
       * @param username a borrower's name
       * @return a user, or empty
       */
      Optional<User> searchForUserByName(String username);
  
  
      /**
       * Check whether the credentials are valid
       * @param username a user's chosen username
       * @param password a user's chosen password
       * @return true if the credentials match something we have, empty otherwise
       */
      Optional<Boolean> areCredentialsValid(String username, String password);
  
  
      /*
       * ==========================================================
       * ==========================================================
       *
       *  Utility Persistence Functions
       *      General functions related to database persistence
       *
       * ==========================================================
       * ==========================================================
       */
  
  
      /**
       * Records the current state of the database as a SQL script,
       * used later for restoring by something like {@link #runRestore(String)}
       *
       * @param backupFileName the path to the sql script, based in the project home directory.
       */
      void runBackup(String backupFileName);
  
  
      /**
       * Runs a database restore script.
       *
       * @param backupFileName the path to the sql script, based in the project home directory.
       */
      void runRestore(String backupFileName);
  
  
      /**
       * Cleans the database and runs the scripts to update it
       * to the most current version.
       */
      void cleanAndMigrateDatabase();
  
  
      /**
       * Cleans the database and runs the scripts to update it
       * to the most current version.
       */
      void cleanDatabase();
  
  
      /**
       * Cleans the database and runs the scripts to update it
       * to the most current version.
       */
      void migrateDatabase();
  
  
      /**
       * Used to indicate that a persistence layer object is
       * using an empty datasource.  See {@link EmptyDataSource}
       * @return true if the object is "empty"
       */
      boolean isEmpty();
  }
  