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 is through 'getmulti'.
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 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.
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. */
110 /** Save the row this manager represents to the database. */
113 /** Discards any changes made to this manager. */
116 /** Wether the manager has been saved to the database or not. */
119 /** Whether a write lock could be aquired for this manager. */
122 /** Releases the lock, it is asserted at run-time that a lock was previously aquired. */
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;
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
);
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. */
203 /** Unsets the dirty field and all the dirty fields of all keys and fields. */
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. */