00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024 #ifndef DATABASES_COLLECTION_H
00025 #define DATABASES_COLLECTION_H
00026
00027
00028
00029 #include <list>
00030
00031 #include <containers/hashlist.h>
00032 #include <containers/vectorsp.h>
00033 #include <databases/record.h>
00034
00035
00036
00037 #ifndef ID_HASH_SIZE
00038 # define ID_HASH_SIZE 4096
00039 #endif
00040
00041 #ifndef NAME_HASH_SIZE
00042 # define NAME_HASH_SIZE 1024
00043 #endif
00044
00045
00046
00048
00049 namespace databases
00050 {
00051
00052
00053
00054 class Database;
00055 class Field;
00056 class NameRecord;
00057
00058
00059
00061
00078 class Collection
00079 {
00080 protected:
00082 static uint32_t const id_hashsize = ID_HASH_SIZE;
00084 typedef containers::HashList<Record *, Record::identifier_type,
00085 id_hashsize> id_hashlist;
00086
00088 typedef std::list<Collection *> owned_list;
00089 public:
00090
00091
00093
00100 class Hook
00101 {
00102 public:
00104 enum
00105 {
00107 chsPreAdd = 0x0001,
00109 chsPostAdd = 0x0002,
00111 chsPreUpdate = 0x0004,
00113 chsPostUpdate = 0x0008,
00115 chsPreRemove = 0x0010,
00117 chsPostRemove = 0x0020,
00119 chsNameChange = 0x0040
00120 };
00121
00123
00129 Hook(uint8_t selector) : m_selector(selector) { }
00131 Hook(Hook const &h) : m_selector(h.m_selector) { }
00133 Hook &operator=(Hook const &right);
00135 virtual ~Hook() { }
00136
00138
00148 virtual bool pre_add(Record *record) { return true; }
00149
00151
00158 virtual void post_add(Record *record) { }
00159
00161
00193 virtual bool pre_update(Record *record, Field const *field)
00194 { return true; }
00195
00197
00218 virtual void post_update(Record *record, Field const *field) { }
00219
00221
00236 virtual bool pre_remove(Record *record) { return true; }
00237
00239
00246 virtual void post_remove(Record *record) { }
00247
00249
00259 virtual void name_change(Record *record) { }
00260
00262
00268 uint8_t selector() const { return m_selector; }
00269 private:
00270 uint8_t m_selector;
00271 };
00272
00273
00274
00276 typedef id_hashlist::iterator iterator;
00278 typedef id_hashlist::const_iterator const_iterator;
00280 typedef id_hashlist::reverse_iterator reverse_iterator;
00282 typedef id_hashlist::const_reverse_iterator const_reverse_iterator;
00283
00285 enum
00286 {
00288 ceUnknown = 1,
00290 ceID = 2,
00292 ceList = 3,
00294 ceDatabase = 4,
00296 ceHook = 5,
00298 ceCustom = 128
00299 };
00300
00301
00302
00304 Collection();
00306
00308 virtual ~Collection();
00309
00311
00324 virtual bool begin_initial() { status_add(csInitial); return true; }
00325
00327
00340 virtual bool end_initial() { status_remove(csInitial); return true; }
00341
00343
00357 virtual bool begin_import(uint16_t type)
00358 { status_add(csImport | type); return true; }
00359
00361
00375 virtual bool end_import(uint16_t type)
00376 { status_remove(csImport | type); return true; }
00377
00379
00388 virtual bool update_new() { return true; }
00389
00391
00399 virtual Record *create(Record::identifier_type id = 0) const = 0;
00400
00402
00418 virtual bool add(Record *record, int *err = 0);
00419
00421
00434 bool change_s(Record *record, Field const *field, char const *value);
00435
00437
00450 bool change_i(Record *record, Field const *field, int32_t value);
00451
00453
00466 bool change_ui(Record *record, Field const *field, uint32_t value);
00467
00469
00482 bool change_ut(Record *record, Field const *field, time_t value);
00483
00485
00498 bool change_ri(Record *record, Field const *field,
00499 Record::identifier_type value);
00500
00502
00519 bool change_multi(Record *record, unsigned int valcount, ...);
00520
00522
00534 bool change_owned(Field const *field, Record::identifier_type id,
00535 Record::identifier_type new_id);
00536
00538
00551 virtual bool remove(Record *record, int *err = 0);
00552
00554
00570 virtual bool remove_owned(Collection const *coll,
00571 Record const *record, int *err = 0);
00572
00574
00582 virtual bool clear(int *err = 0);
00583
00585
00590 Record *find(Record::identifier_type id);
00592 Record const *find(Record::identifier_type id) const;
00593
00595
00603 void set_owned(Collection &coll) { m_owned.push_front(&coll); }
00604
00606
00610 void unset_owned(Collection &coll) { m_owned.remove(&coll); }
00611
00613
00621 void add_hook(Hook *hook);
00622
00624
00629 void remove_hook(Hook *hook);
00630
00632 iterator begin() { return m_members.begin(); }
00634 iterator end() { return m_members.end(); }
00636 const_iterator begin() const { return m_members.begin(); }
00638 const_iterator end() const { return m_members.end(); }
00639
00641 reverse_iterator rbegin() { return m_members.rbegin(); }
00643 reverse_iterator rend() { return m_members.rend(); }
00645 const_reverse_iterator rbegin() const { return m_members.rbegin(); }
00647 const_reverse_iterator rend() const { return m_members.rend(); }
00648
00650 bool empty() const { return m_members.empty(); }
00652 id_hashlist::size_type size() const { return m_members.size(); }
00653
00655
00660 virtual size_t memory_usage() const;
00661
00663 enum
00664 {
00666 csChanges = 0x0001,
00668 csInitial = 0x0002,
00670 csImport = 0x0004,
00672 csCreation = 0x0008,
00674 csUpdate = 0x0010,
00676 csDeletion = 0x0020,
00677
00679 csNoDelete = 0x8000
00680 };
00681
00683 Database *db() { return m_db; }
00685
00692 Database *db(Database *db) { return (m_db = db); }
00693
00695
00700 bool readable() const;
00701
00703
00708 bool writable() const;
00709
00711
00723 virtual Field const *owner_field(Collection const *coll) const
00724 { return 0; }
00725
00727 uint16_t status() const { return m_status; }
00729
00733 uint16_t status_add(uint16_t flags) { return (m_status |= flags); }
00735
00739 uint16_t status_remove(uint16_t flags) { return (m_status &= ~flags); }
00740
00742 Record::identifier_type last_id() const { return m_last_id; }
00743 protected:
00745 typedef std::list<Hook *> hooks_list;
00746
00748 id_hashlist m_members;
00750 Database *m_db;
00752 uint16_t m_status;
00754 Record::identifier_type m_last_id;
00755
00757 owned_list m_owned;
00758
00760 enum
00761 {
00763 chtPreAdd,
00765 chtPostAdd,
00767 chtPreUpdate,
00769 chtPostUpdate,
00771 chtPreRemove,
00773 chtPostRemove,
00775 chtNameChange,
00776
00778 chtCount = 7
00779 };
00780
00782 hooks_list m_hooks[chtCount];
00783
00785
00791 virtual bool add_list(Record *record);
00792
00794
00800 virtual bool add_db(Record *record);
00801
00803
00819 virtual bool remove_owned_db(Collection const *coll,
00820 Record const *record, int *err = 0);
00821
00823
00840 virtual bool remove_owned_list(Collection const *coll,
00841 Record const *record, int *err = 0);
00842
00844
00851 virtual void remove_list(Record *record);
00852
00854
00860 virtual bool remove_db(Record *record);
00861
00863
00875 virtual bool clear_owned(Collection const *coll, int *err = 0);
00876
00878
00882 virtual void clear_list();
00883
00885
00889 virtual bool clear_db();
00890
00892
00904 bool run_hooks(int type, Record *record, Field const *field = 0) const;
00905 private:
00906 Collection(Collection const &);
00907 Collection &operator=(Collection const &);
00908 };
00909
00910
00911
00913
00917 class NameCollection : public Collection
00918 {
00919 protected:
00921 static uint32_t const name_hashsize = NAME_HASH_SIZE;
00923 typedef containers::HashList<NameRecord *, char const *,
00924 name_hashsize> name_hashlist;
00925 public:
00926
00927
00929 typedef containers::Hash<NameRecord *, char const *> name_hash;
00930
00932 typedef name_hashlist::iterator niterator;
00934 typedef name_hashlist::const_iterator const_niterator;
00936 typedef name_hashlist::reverse_iterator reverse_niterator;
00938 typedef name_hashlist::const_reverse_iterator const_reverse_niterator;
00939
00940
00941
00943
00946 explicit NameCollection(name_hash &hash) : Collection(),
00947 m_nmembers(hash) { }
00948
00950
00961 virtual bool change_name(NameRecord *record, char const *newname);
00962
00964 niterator nbegin() { return m_nmembers.begin(); }
00966 niterator nend() { return m_nmembers.end(); }
00968 const_niterator nbegin() const { return m_nmembers.begin(); }
00970 const_niterator nend() const { return m_nmembers.end(); }
00971
00973 reverse_niterator nrbegin() { return m_nmembers.rbegin(); }
00975 reverse_niterator nrend() { return m_nmembers.rend(); }
00977 const_reverse_niterator nrbegin() const { return m_nmembers.rbegin(); }
00979 const_reverse_niterator nrend() const { return m_nmembers.rend(); }
00980
00982 virtual size_t memory_usage() const;
00983
00985
00990 NameRecord *nfind(char const *name);
00992 NameRecord const *nfind(char const *name) const;
00993 protected:
00995 name_hashlist m_nmembers;
00996
00998 virtual bool add_list(Record *record);
00999
01001 virtual void remove_list(Record *record);
01002
01004 virtual void clear_list();
01005 };
01006
01007
01008
01010
01014 class ArrayCollection : public Collection
01015 {
01016 public:
01017
01018
01020 typedef containers::VectorSP<Record *, uint16_t> array_type;
01021
01022
01023
01025 enum
01026 {
01028 ceName = 64
01029 };
01030
01031
01032
01034
01038 explicit ArrayCollection(bool named) : Collection(), m_array(),
01039 m_named(named) { }
01040
01042
01054 virtual bool add(Record *record, int *err = 0);
01055
01057 virtual size_t memory_usage() const;
01058
01060
01068 array_type &array() { return m_array; }
01069
01071 protected:
01073 array_type m_array;
01075 bool m_named;
01076
01078 virtual bool add_list(Record *record);
01079
01081 virtual void remove_list(Record *record);
01082
01084 virtual void clear_list();
01085 };
01086
01087
01088
01089 }
01090
01091
01092
01093 #endif