/*!
  @header BDBDatabase
  @abstract Contains a class representing a database
 
  @availability OS X, GNUstep
  @copyright (C) 2004, 2005, 2006 Oliver Langer
 
  Author: Oliver Langer

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

  <pre>
  -------------------------------------------------------------------------
  Modification history

  09.12.2005 ola     initial version
  22.08.2006 ola     license changed
  -------------------------------------------------------------------------
  </pre>
******************************************************************************/


#if !defined(__BDBDATABASE_H)
#define __BDBDATABASE_H

#include <db.h>
#include <Foundation/Foundation.h>
#include <BDB/BDBObject.h>
#include <BDB/BDBOperationStatus.h>
#include <BDB/BDBTransaction.h>
#include <BDB/BDBDatabaseConfig.h>
#include <BDB/BDBCursorConfig.h>
#include <BDB/BDBCursor.h>
#include <BDB/BDBDatabaseEntry.h>
#include <BDB/BDBDatabaseRecordNumber.h>

/*!
 * @class BDBDatabase
 * @abstract Wrapper for a DB instance
 * @discussion Use instances of this class to load/store values
 */
@interface BDBDatabase : BDBObject {
 @private
  /**
   * Underlying berkeley handle
   */
  DB *db;
  
  
  
  /**
   * Database configuration
   */
  BDBDatabaseConfig *dbConfig;
  
  
  /**
   * Name (not filename) of the database. May equal nil.
   */
  NSString *databaseName;
} 

+ (void) initialize;


/*!
 * @method initWithFilename
 * @abstract open a database with the given file name, database name
 *   and configuration.
 * @discussion Depending on the configuration the database may be
 *   created if not existent. Also, the configuration determines the kind of
 *   database to use.
 * @param fileName name of database file
 * @param databaseName name of database. Useful if multiple databases will
 *   be used within a single file. May equal nil. If nil is given 
 *   during creation then subsequent calls with values different from nil
 *   will be ignored.
 * @param aDbConfig configuration parameters
 * 
 */
+ (BDBDatabase *) initWithFilename: (NSString *) fileName 
  databaseName: (NSString *) databaseName 
  databaseConfig: (BDBDatabaseConfig *) aDbConfig;
- init;


/**
 * Used to close the database if opened at this stage
 */  
- (void) dealloc;


/*!
 * @method appendEntry
 * @abstract appends the given entry to the end of the database
 * @discussion This method is only defined for one of the modes
 *   {@link #BDB_RECNO}, {@link #BDB_QUEUE}
 * @param transaction transaction to use
 * @param entryToAppend value to add
 * @param recordNr will contain the record number after appending the value.
 *   The underlying database entry instance has to be instantiated by the 
 *   caller. If nil is passed then no record number will be returned this way.
 * @result status of the operation
 * @throws ECIllegalArgumentException if the given database entry contains no
 *   data.
 * @throws ECIllegalOperationException if the database type is wrong or if
 *   an attempt was made to modify a read-only database.
 * @throws DB_REP_HANDLE_DEAD invalid database handle due to a replication
 *   which unrolled a committed transaction. 
 * @throws DB_LOCK_DEADLOCK
 * @throws DB_LOCK_NOTGRANTED
 * @throws EINVAL The operation failed because of an invalid length of
 *   an record (in fixed record mode); OR attempt was made to append data to a 
 *   secondary index.
 * @throws BDBBtreeMaximumDepthReachedException
 */
- (BDBOperationStatus) appendEntryWithTransaction: 
  (BDBTransaction *) transaction 
  entryToAppend: (BDBDatabaseEntryData *) entryToAppend
  resultingRecordNr: (BDBDatabaseRecordNumber *)  recordNr;


/*!
 * Closes the database. After this call all settings related to the database
 * are being invalidated. The previously hand-off configuration may be reused.
 */
- close;


/*!
 * @method deleteEntryWithTransaction
 * @discussion In case of duplicate entries specified by the key 
 *   <b>all</b> entries will be removed.
 * @param transaction
 * @param key key specifying the entry to be deleted
 * @result status which may equal BDB_STATUS_NOTFOUND, BDB_STATUS_KEYEMPTY
 * or BDB_STATUS_SUCCESS
 * @throws BDBDeadLockExcepion
 * @throws BDBException
 */
- (BDBOperationStatus) deleteEntryWithTransaction:( BDBTransaction *) transaction
  key: (BDBDatabaseEntryData *) key;
  

/*!
 * @param transaction underlying transaction. May equal nil
 * @param key key to look for
 * @param data entry to fill with the found data entry
 * @return status of the operation
 * @see BDBOperationStatus
 * @throws BDBDeadLockException
 * @throws BDBLockNotGrantedException
 * @throws BDBIllegalIndexReference
 * @throws BDBNoValueForKeyException
 */
-  (BDBOperationStatus) getEntryWithTransaction: (BDBTransaction *) transaction 
  key: (BDBDatabaseEntryData *) key data: (BDBDatabaseEntryData *) data;


/*!
 * @method getEntryWithTransaction
 * @abstract retriev a value by its record number
 * @param transaction underlying transaction. May equal nil
 * @param key key to look for
 * @param data entry to fill with the found data entry
 * @return status of the operation
 * @throws BDBDeadLockException
 * @throws BDBLockNotGrantedException
 * @throws BDBIllegalIndexReference
 * @throws BDBNoValueForKeyException
 */

- (BDBOperationStatus) getEntryWithTransaction: (BDBTransaction *) transaction
  recordNumber: (BDBDatabaseRecordNumber *) recNo 
  data: (BDBDatabaseEntryData *) data;
  
  
/*!
 * @method openCursor
 * @abstract open and return a cursor used.
 * @param transaction underlying transaction. May be nil
 * @param config settings for the cursor to be created
 * ®result related cursor
 * @throws BDBException
 * @throws ECIllegalArgumentException
 */
- (BDBCursor *) openCursor: (BDBTransaction *) transaction 
  cursorConfig: (BDBCursorConfig *) config;
  
  
/*!
 * @method putEntryWithTransaction
 * @abstract Stores an entry in the database. 
 * @param key value for the key to be used. The handling of duplicates depends 
 * on the the configuration previously being set.
 * @param value
 * @result status of operation
 * @throws BDBDeadLockException
 * @throws BDBLockNotGrantedException
 * @throws BDBException
 */
- (BDBOperationStatus) putEntryWithTransaction: (BDBTransaction *) transaction
  key: (BDBDatabaseEntryData *) key value: (BDBDatabaseEntryData *) value;


/*!
 * Stores an entry in the database
 * @param key may not be null. The handling of duplicates depends 
 * on the the configuration previously being set.
 * @param value may not be null.
 * @throws BDBDeadLockException
 * @throws BDBLockNotGrantedException
 * @throws BDBException
 */
- (BDBOperationStatus) putDataWithTransaction: (BDBTransaction *) transaction
  key: (NSData *) key value: (NSData *) value;

@end

#endif

