1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #pragma once
34
35 ///
36 /// This file contains the core objects that everything is
37 /// built from.
38 ///
39 /// The core objects are:
40 ///
41 /// dbId - included
42 /// dbObjectTable
43 /// dbObjectPage
44 /// dbTablePage
45 ///
46
47 #include "dbAttrTable.h"
48 #include "dbId.h"
49 #include "dbObject.h"
50 #include "odb.h"
51 namespace utl {
52 class Logger;
53 }
54 namespace odb {
55
56 class _dbDatabase;
57 class _dbProperty;
58 class dbObjectTable;
59
60 #define DB_ALLOC_BIT 0x80000000
61 #define DB_OFFSET_MASK (~DB_ALLOC_BIT)
62
63 typedef dbObjectTable* (dbObject::*GetObjTbl_t)(dbObjectType);
64
65 ///////////////////////////////////////////////////////////////
66 /// _dbObject definition
67 ///////////////////////////////////////////////////////////////
68 class _dbObject : public dbObject
69 {
70 private:
71 uint _oid;
72
73 public:
74 _dbDatabase* getDatabase() const;
75 dbObjectTable* getTable() const;
76 dbObjectPage* getObjectPage() const;
77 dbObject* getOwner() const;
78 dbObjectType getType() const;
79 uint getOID() const;
80 utl::Logger* getLogger() const;
81
82 template <class T>
83 friend class dbTable;
84 template <class T>
85 friend class dbArrayTable;
86 };
87
88 ///////////////////////////////////////////////////////////////
89 /// dbObjectTable definition
90 ///////////////////////////////////////////////////////////////
91 class dbObjectTable
92 {
93 public:
94 // NON-PERSISTANT DATA
95 _dbDatabase* _db;
96 dbObject* _owner;
97 dbObjectType _type;
98 uint _obj_size;
99 dbObjectTable* (dbObject::*_getObjectTable)(dbObjectType type);
100
101 // PERSISTANT DATA
102 dbAttrTable<dbId<_dbProperty>> _prop_list;
103
~dbObjectTable()104 virtual ~dbObjectTable(){};
105 dbObjectTable();
106 dbObjectTable(_dbDatabase* db,
107 dbObject* owner,
108 dbObjectTable* (dbObject::*m)(dbObjectType),
109 dbObjectType type,
110 uint size);
111
getPropList(uint oid)112 dbId<_dbProperty> getPropList(uint oid) { return _prop_list.getAttr(oid); }
113
setPropList(uint oid,dbId<_dbProperty> propList)114 void setPropList(uint oid, dbId<_dbProperty> propList)
115 {
116 _prop_list.setAttr(oid, propList);
117 }
118
119 virtual dbObject* getObject(uint id, ...) = 0;
120
getObjectTable(dbObjectType type)121 dbObjectTable* getObjectTable(dbObjectType type)
122 {
123 return (_owner->*_getObjectTable)(type);
124 }
125 };
126
127 ///////////////////////////////////////////////////////////////
128 /// _dbFreeObject definition - free-list object
129 ///////////////////////////////////////////////////////////////
130
131 class _dbFreeObject : public _dbObject
132 {
133 public:
134 uint _next;
135 uint _prev;
136 };
137
138 ///////////////////////////////////////////////////////////////
139 /// dbObjectPage definition
140 ///////////////////////////////////////////////////////////////
141 class dbObjectPage
142 {
143 public:
144 // NON-PERSISTANT DATA
145 dbObjectTable* _table;
146 uint _page_addr;
147 uint _alloccnt;
148
valid_page()149 bool valid_page() const { return _alloccnt != 0; }
150 };
151
152 ///////////////////////////////////////////////////////////////
153 /// dbObjectTable implementation
154 ///////////////////////////////////////////////////////////////
dbObjectTable()155 inline dbObjectTable::dbObjectTable()
156 {
157 _db = NULL;
158 _owner = NULL;
159 }
160
dbObjectTable(_dbDatabase * db,dbObject * owner,dbObjectTable * (dbObject::* m)(dbObjectType),dbObjectType type,uint size)161 inline dbObjectTable::dbObjectTable(_dbDatabase* db,
162 dbObject* owner,
163 dbObjectTable* (dbObject::*m)(dbObjectType),
164 dbObjectType type,
165 uint size)
166 {
167 _db = db;
168 _owner = owner;
169 _getObjectTable = m;
170 _type = type;
171
172 // Objects must be greater than 16-bytes
173 assert(size >= sizeof(_dbFreeObject));
174 _obj_size = size;
175 }
176
177 ///////////////////////////////////////////////////////////////
178 /// _dbObject inlines
179 ///////////////////////////////////////////////////////////////
180
getImpl()181 inline _dbObject* dbObject::getImpl()
182 {
183 return (_dbObject*) this;
184 }
185
getImpl()186 inline const _dbObject* dbObject::getImpl() const
187 {
188 return (_dbObject*) this;
189 }
190
getOID()191 inline uint _dbObject::getOID() const
192 {
193 uint offset = (_oid & DB_OFFSET_MASK);
194 char* base = (char*) this - offset;
195 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
196 return page->_page_addr | offset / page->_table->_obj_size;
197 }
198
getTable()199 inline dbObjectTable* _dbObject::getTable() const
200 {
201 uint offset = (_oid & DB_OFFSET_MASK);
202 char* base = (char*) this - offset;
203 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
204 return page->_table;
205 }
206
getDatabase()207 inline _dbDatabase* _dbObject::getDatabase() const
208 {
209 uint offset = (_oid & DB_OFFSET_MASK);
210 char* base = (char*) this - offset;
211 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
212 return page->_table->_db;
213 }
214
getOwner()215 inline dbObject* _dbObject::getOwner() const
216 {
217 uint offset = (_oid & DB_OFFSET_MASK);
218 char* base = (char*) this - offset;
219 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
220 return page->_table->_owner;
221 }
222
getType()223 inline dbObjectType _dbObject::getType() const
224 {
225 uint offset = (_oid & DB_OFFSET_MASK);
226 char* base = (char*) this - offset;
227 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
228 return page->_table->_type;
229 }
230
getObjectPage()231 inline dbObjectPage* _dbObject::getObjectPage() const
232 {
233 uint offset = (_oid & DB_OFFSET_MASK);
234 char* base = (char*) this - offset;
235 dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
236 return page;
237 }
238
239 } // namespace odb
240