Chunk is purely a wrapper class, any 'state variables', like 'characters in room...
[UnsignedByte.git] / src / DAL / SavableManager.h
blobd3414f0743787fe591de01e7ffcbcc1667517341
1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #pragma once
22 /**
23 * @file SavableManager.h
24 * This file container the SavableManager class.
26 * @see SavableManager.
27 */
29 #include "Types.h"
31 /** The type used to cache integer type field values. */
32 typedef std::map<KeyImpl*, value_type> KeyFieldMap;
34 /** The type used to cache text type field values. */
35 typedef std::pair<FieldImpl*, std::string> TextFieldPair;
37 /** The type used to cache SavableManagers by their keys in. */
38 typedef std::map<KeyFieldMap, SavableManagerPtr> ByKeyCache;
40 /** The type used to cache SavableManagers by their value in. */
41 typedef std::map<TextFieldPair, SavableManagerPtr> ByValueCache;
43 /**
44 * This class represents one row in the database.
46 * It may be used to perform CRUD operations on the database.
47 * (Create, Retreive, Update, Delete)
49 * Trivial locking is implemented through <code>lock</code> and <code>unlock</code>.
50 * That is, it is asserted that a lock was aquired when performing a write operation.
51 * However, it is not checked that it was the called that aquired the lock.
52 * It is therefore the responsibility of the caller not to use write operation unless it previously aquired a lock.
54 * @see lock
55 * @see unlock
56 */
57 class SavableManager : public boost::enable_shared_from_this<SavableManager>
59 public:
60 /**
61 * Select multiple entries from the database restricting on the specified values.
63 * This method wraps the creation of the SelectionMask and the call to the database.
64 * This is the preferred method of selection multiple rows from the database is through 'getmulti'.
66 * @param values The values to filter on.
67 * @return A SavableManagers bucket containing the retreived data.
68 * @see SelectionMask
70 static SavableManagersPtr getmulti(FieldValuesPtr values);
72 /**
73 * Select multiple entries from the database restricting on the specified values.
75 * This method wraps the creation of the SelectionMask and the call to the database.
76 * This is the preferred method of selection multiple rows from the database is through 'getmulti'.
78 * @param values The values to filter on.
79 * @param joins The joins to extend the selection with.
80 * @return A SavableManagers bucket containing the retreived data.
81 * @see SelectionMask
83 static SavableManagersPtr getmulti(FieldValuesPtr values, const Joins& joins);
85 /** Returns a new manager for the specified table, it is not yet stored in the database. */
86 static SavableManagerPtr getnew(TableImplPtr table);
88 /** Returns a manager for the specified table using the specified key. */
89 static SavableManagerPtr bykey(KeyValuePtr key);
91 /** Returns a manager using the specified keys, these are asserted to be all the keys for this table.*/
92 static SavableManagerPtr bykeys(KeysPtr keys);
94 /** Returns a manager using the specified value, this value should uniquely identify an entry. */
95 static SavableManagerPtr byvalue(ValuePtr value);
97 /** Wrapper that looks up a manager by the specified value and returns the keys. */
98 static KeysPtr lookupvalue(ValuePtr value);
100 /** Count how many entries there are that satisfy this mask. */
101 static size_t count(SelectionMaskPtr mask);
103 /** Count how many entries there are for the given keys set. */
104 static size_t count(KeysPtr keys);
107 /** Remove the row this manager represents from the databse. */
108 void erase();
110 /** Save the row this manager represents to the database. */
111 void save();
113 /** Discards any changes made to this manager. */
114 void discard();
116 /** Wether the manager has been saved to the database or not. */
117 bool exists() const;
119 /** Whether a write lock could be aquired for this manager. */
120 bool lock();
122 /** Releases the lock, it is asserted at run-time that a lock was previously aquired. */
123 void unlock();
126 /** Binds the keys of this manager to the specified statement. */
127 void bindKeys(sqlite3* db, sqlite3_stmt* stmt, const int startpos = 1) const;
129 /** Binds the fields of this manager to the specified statement. */
130 void bindFields(sqlite3* db, sqlite3_stmt* stmt, const int startpos = 1) const;
132 /** First binds the keys and then the fields of this manager to the specified statement. */
133 void bindUpdate(sqlite3* db, sqlite3_stmt* stmt) const;
135 /** Binds the lookup field of this manager to the specified statement. */
136 void bindLookup(sqlite3* db, sqlite3_stmt* stmt) const;
139 /**
140 * Parse an insertion from the database.
142 * Only valid on a table with a singular primary key.
143 * That is, sqlite3_last_insert_rowid must return the id of the inserted row.
145 void parseInsert(sqlite3* db);
147 /** Read in this managers fields from a selection from the database. */
148 void parseSelect(sqlite3_stmt* stmt, const int startpos = 0);
150 /** Read in the keys and the fields for this manager from a lookup from the database. */
151 void parseLookup(sqlite3_stmt* stmt);
154 /** Returns the table this manager belongs to. */
155 TableImplPtr getTable() const;
157 /** Returns the value of the specified field of the row this manager represents . */
158 ValuePtr getValue(FieldImplPtr field) const;
160 /** Returns the keys in this manager. */
161 KeysPtr getKeys() const;
163 /** Returns the size of the primary keys for this manager. */
164 size_t primaryKeySize() const;
167 /** Returns a string representation of this manager. */
168 std::string toString();
170 /** Returns an array of strings, one for each field in this row. */
171 Strings fieldList() const;
173 /** Returns a string representation of the valueus of this manager compared to the database. */
174 std::string getDiff() const;
176 /** Wether any changes been made to this manager that have not been saved to the databse yet. */
177 bool isDirty() const;
180 /** Sets this managers keys to the specified values, it is asserted at runtime that a lock has been aquired. */
181 void setKeys(KeysPtr keys);
183 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
184 void setValue(ValuePtr value);
186 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
187 void setValue(FieldImplPtr field, cstring value);
189 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
190 void setValue(FieldImplPtr field, value_type value);
192 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
193 void setValue(KeyImplPtr field, value_type value);
195 private:
196 /** This is a managed class, use the factory methods insteaed of this constructor to create a new instance. */
197 SavableManager(TableImplPtr table);
199 /** Destructor, a noop. */
200 ~SavableManager();
203 /** Unsets the dirty field and all the dirty fields of all keys and fields. */
204 void cleanup();
207 /** Cache the specified manager. */
208 static void doFullCache(SavableManagerPtr manager);
210 /** Uncache the specified manager. */
211 static void doUncache(SavableManagerPtr manager);
213 /** Recache the specified manager. */
214 static void doRecache(SavableManagerPtr manager);
216 /** Construct a map from the specified manager. */
217 static KeyFieldMap constructMap(SavableManagerPtr keys);
219 /** Construct a map from the specified keys bucket. */
220 static KeyFieldMap constructMap(KeysPtr keys);
222 /** Construct a pair from a value object. */
223 static TextFieldPair constructPair(FieldValuePtr value);
225 /** Returns a string presentation of a KeyField map. */
226 static std::string fromMap(const KeyFieldMap& map);
229 static ByKeyCache ms_byKeyCache; /**< Lookup to retreive managers by the keys. */
230 static ByValueCache ms_byValueCache; /**< Lookup to retreive managers by value. */
233 friend SmartPtrDelete(SavableManager);
234 friend class SelectionMask;
236 TableImplPtr m_table; /**< The table this manager belongs to. */
237 ValuePtr m_lookupvalue; /**< The value the lookup will use. */
239 FieldValueMap m_fields; /**< The value of this manager. */
240 FieldValueMap m_orig; /**< The values of this manager as they currently are in the database. */
242 bool m_newentry; /**< Whether this manager is saved to the database yet. */
243 bool m_locked; /**< Whether this manager is locked for writing. */