//-< DATABASE.H >----------------------------------------------------*--------* // GOODS Version 1.0 (c) 1997 GARRET * ? * // (Generic Object Oriented Database System) * /\| * // * / \ * // Created: 7-Jan-97 K.A. Knizhnik * / [] \ * // Last update: 16-Apr-97 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* // Application specific database interface //-------------------------------------------------------------------*--------* #ifndef __DATABASE_H__ #define __DATABASE_H__ #include "storage.h" #include "goodsdlx.h" BEGIN_GOODS_NAMESPACE class class_descriptor; class object_reference; class cache_manager; // // This class obtain application dependent interface with database storage. // It is responsible for: // 1) synchronization of request to database storage // 2) mapping between database and application class descriptors // 3) convertion of loaded and stored objects // 4) checking storage availablity // class GOODS_DLL_EXPORT obj_storage : public dbs_application { friend class database; friend class object; friend class object_handle; friend class basic_metaobject; protected: dnm_array descriptor_table; dnm_array cpid_table; dbs_storage* storage; mutex cs; // // Number of references to objects from this storage // The 'storage' object can be removed when there are no more references // to it from any object (n_references == 0) // long n_references; dnm_buffer loadBuf; dnm_buffer transBuf; boolean opened; opid_t* alloc_opid_buf; size_t* alloc_size_buf; cpid_t* alloc_cpid_buf; volatile size_t alloc_buf_pos; volatile size_t alloc_buf_size; public: database* const db; const stid_t id; void add_reference() { n_references += 1; } void remove_reference() { if (--n_references == 0) { delete this; } } // // Method called by server to invalidate object instance // virtual void invalidate(stid_t sid, opid_t opid); // // Method called by server to notify about server disconnection // virtual void disconnected(stid_t sid); // // Authorization procedure fails at server sid // virtual void login_refused(stid_t sid); // // Inform server that client no more has reference to specified object // void forget_object(opid_t opid) { if (opened) { storage->forget_object(opid); } } // // Inform server that client no more has instance of specified object // void throw_object(opid_t opid) { if (opened) { storage->throw_object(opid); } } // // Get server class identifier for specified application class // cpid_t get_cpid_by_descriptor(class_descriptor* desc); // // Allocate object at server // opid_t allocate(cpid_t cpid, size_t size, boolean aligned); // // Deallocate object at server // void deallocate(opid_t opid) { storage->deallocate(opid); } // // Download object from server. This method is called with // global lock set, release lock while waiting for object and // set it again after receiving object from server // void load(hnd_t hnd, int flags); // // Set new lock or upgrade an existed one (from shared to exclusive) // boolean lock(opid_t opid, lck_t lck, int attr); // // Remove or downgrade lock. // void unlock(opid_t opid, lck_t lck) { storage->unlock(opid, lck); } // // Transaction protocol. // No other storage methods (except forget_object and throw_object) // can be called until transaction completion. This syncronization should // be done by metaobject protocol. // void begin_transaction(); void include_object_in_transaction(hnd_t hnd, int flags); boolean commit_coordinator_transaction(int n_trans_servers, stid_t* trans_servers, trid_t& tid); void commit_transaction(stid_t coordinator, int n_trans_servers, stid_t* trans_servers, trid_t tid); boolean wait_global_transaction_completion(); boolean open(char const* connection_address); void close(); nat8 get_used_size(); obj_storage(database* dbs, stid_t sid); virtual~obj_storage(); }; enum transaction_isolation_level { PER_PROCESS_TRANSACTION, PER_THREAD_TRANSACTION }; // // Class 'database' is collection of storages. // It's main responsibility is transaction handling. // class GOODS_DLL_EXPORT database { protected: friend class object; friend class obj_storage; friend class field_descriptor; obj_storage** storages; int n_storages; boolean opened; mutex cs; cache_manager* manager; int fetch_flags; size_t alloc_buf_size; protected: virtual dbs_storage* create_dbs_storage(stid_t sid) const; // // Handle of one of storage servers disconnection // virtual void disconnected(stid_t sid); // // Handle authorization error // virtual void login_refused(stid_t sid); obj_storage* get_storage(stid_t sid) { internal_assert(sid < n_storages); return storages[sid]; } cache_manager* get_cache_manager(); public: virtual boolean open(const char* database_configuration_file); virtual void close(); // // Enable fetching of object clusters. When enabled server will send to the client // not only the requested object, but also objects which are directly or indirectly // referenced from the requested object. Maximal size of the cluster is configured // at server. // virtual void enable_clustering(boolean enabled); // // Set size of object allocation buffer. Server will return to the client set of OIDs // which can be used by client. At the end of transaction all new objects will be allocated // in the database using one bulk alloc operations. // virtual void set_alloc_buffer_size(size_t size); // // Attach current thread to the database connection // virtual void attach(); // // Set isolation level // virtual void set_isolation_level(transaction_isolation_level level); // // Detach current thread from the database connection // virtual void detach(); // // Get root object of specified storage // void get_root(object_reference& ref, stid_t sid = 0); int get_number_of_storages() const { return n_storages; } nat8 get_used_size(stid_t sid = 0) { return get_storage(sid)->get_used_size(); } stid_t get_storage_with_minimal_size(); database(); virtual ~database(); }; END_GOODS_NAMESPACE #endif