1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
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. *
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. *
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 ***************************************************************************/
23 * @file SavableManager.h
24 * This file container the SavableManager class.
26 * @see SavableManager.
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
;
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.
57 class SavableManager
: public boost::enable_shared_from_this
<SavableManager
>
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.
66 * @param values The values to filter on.
67 * @return A SavableManagers bucket containing the retreived data.
70 static SavableManagersPtr
getmulti(FieldValuesPtr values
);
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.
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.
83 static SavableManagersPtr
getmulti(FieldValuesPtr values
, const Joins
& joins
);
86 * Select multiple entries from the database restricting with the specified mask.
88 * This method uses the specified mask to make the call to the database.
89 * This is the preferred method of selection multiple rows from the database.
91 * @param mask The mask to use.
92 * @return A SavableManagers bucket containing the retreived data.
95 static SavableManagersPtr
getmulti(SelectionMaskPtr mask
);
97 /** Returns a new manager for the specified table, it is not yet stored in the database. */
98 static SavableManagerPtr
getnew(TableImplPtr table
);
100 /** Returns a manager for the specified table using the specified key. */
101 static SavableManagerPtr
bykey(KeyValuePtr key
);
103 /** Returns a manager using the specified keys, these are asserted to be all the keys for this table.*/
104 static SavableManagerPtr
bykeys(KeysPtr keys
);
106 /** Returns a manager using the specified value, this value should uniquely identify an entry. */
107 static SavableManagerPtr
byvalue(ValuePtr value
);
109 /** Wrapper that looks up a manager by the specified value and returns the keys. */
110 static KeysPtr
lookupvalue(ValuePtr value
);
112 /** Count how many entries there are that satisfy this mask. */
113 static size_t count(SelectionMaskPtr mask
);
115 /** Count how many entries there are for the given keys set. */
116 static size_t count(KeysPtr keys
);
119 /** Remove the row this manager represents from the databse. */
122 /** Save the row this manager represents to the database. */
125 /** Discards any changes made to this manager. */
128 /** Wether the manager has been saved to the database or not. */
131 /** Whether a write lock could be aquired for this manager. */
134 /** Releases the lock, it is asserted at run-time that a lock was previously aquired. */
138 /** Binds the keys of this manager to the specified statement. */
139 void bindKeys(sqlite3
* db
, sqlite3_stmt
* stmt
, const int startpos
= 1) const;
141 /** Binds the fields of this manager to the specified statement. */
142 void bindFields(sqlite3
* db
, sqlite3_stmt
* stmt
, const int startpos
= 1) const;
144 /** First binds the keys and then the fields of this manager to the specified statement. */
145 void bindUpdate(sqlite3
* db
, sqlite3_stmt
* stmt
) const;
147 /** Binds the lookup field of this manager to the specified statement. */
148 void bindLookup(sqlite3
* db
, sqlite3_stmt
* stmt
) const;
152 * Parse an insertion from the database.
154 * Only valid on a table with a singular primary key.
155 * That is, sqlite3_last_insert_rowid must return the id of the inserted row.
157 void parseInsert(sqlite3
* db
);
159 /** Read in this managers fields from a selection from the database. */
160 void parseSelect(sqlite3_stmt
* stmt
, const int startpos
= 0);
162 /** Read in the keys and the fields for this manager from a lookup from the database. */
163 void parseLookup(sqlite3_stmt
* stmt
);
166 /** Returns the table this manager belongs to. */
167 TableImplPtr
getTable() const;
169 /** Returns the value of the specified field of the row this manager represents . */
170 ValuePtr
getValue(FieldImplPtr field
) const;
172 /** Returns the keys in this manager. */
173 KeysPtr
getKeys() const;
175 /** Returns the size of the primary keys for this manager. */
176 size_t primaryKeySize() const;
179 /** Returns a string representation of this manager. */
180 std::string
toString();
182 /** Returns an array of strings, one for each field in this row. */
183 Strings
fieldList() const;
185 /** Returns a string representation of the valueus of this manager compared to the database. */
186 std::string
getDiff() const;
188 /** Wether any changes been made to this manager that have not been saved to the databse yet. */
189 bool isDirty() const;
192 /** Sets this managers keys to the specified values, it is asserted at runtime that a lock has been aquired. */
193 void setKeys(KeysPtr keys
);
195 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
196 void setValue(ValuePtr value
);
198 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
199 void setValue(FieldImplPtr field
, cstring value
);
201 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
202 void setValue(FieldImplPtr field
, value_type value
);
204 /** Sets the specified field of this manager to the specified value, it is asserted at runtime that a lock has been aquired. */
205 void setValue(KeyImplPtr field
, value_type value
);
208 /** This is a managed class, use the factory methods insteaed of this constructor to create a new instance. */
209 SavableManager(TableImplPtr table
);
211 /** Destructor, a noop. */
215 /** Unsets the dirty field and all the dirty fields of all keys and fields. */
219 /** Cache the specified manager. */
220 static void doFullCache(SavableManagerPtr manager
);
222 /** Uncache the specified manager. */
223 static void doUncache(SavableManagerPtr manager
);
225 /** Recache the specified manager. */
226 static void doRecache(SavableManagerPtr manager
);
228 /** Construct a map from the specified manager. */
229 static KeyFieldMap
constructMap(SavableManagerPtr keys
);
231 /** Construct a map from the specified keys bucket. */
232 static KeyFieldMap
constructMap(KeysPtr keys
);
234 /** Construct a pair from a value object. */
235 static TextFieldPair
constructPair(FieldValuePtr value
);
237 /** Returns a string presentation of a KeyField map. */
238 static std::string
fromMap(const KeyFieldMap
& map
);
241 static ByKeyCache ms_byKeyCache
; /**< Lookup to retreive managers by the keys. */
242 static ByValueCache ms_byValueCache
; /**< Lookup to retreive managers by value. */
245 friend SmartPtrDelete(SavableManager
);
246 friend class SelectionMask
;
248 TableImplPtr m_table
; /**< The table this manager belongs to. */
249 ValuePtr m_lookupvalue
; /**< The value the lookup will use. */
251 FieldValueMap m_fields
; /**< The value of this manager. */
252 FieldValueMap m_orig
; /**< The values of this manager as they currently are in the database. */
254 bool m_newentry
; /**< Whether this manager is saved to the database yet. */
255 bool m_locked
; /**< Whether this manager is locked for writing. */