1 /********************************************************************\
2  * qofclass.h -- API for registering parameters on objects          *
3  *                                                                  *
4  * This program is free software; you can redistribute it and/or    *
5  * modify it under the terms of the GNU General Public License as   *
6  * published by the Free Software Foundation; either version 2 of   *
7  * the License, or (at your option) any later version.              *
8  *                                                                  *
9  * This program is distributed in the hope that it will be useful,  *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
12  * GNU General Public License for more details.                     *
13  *                                                                  *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact:                        *
16  *                                                                  *
17  * Free Software Foundation           Voice:  +1-617-542-5942       *
18  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
19  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
20  *                                                                  *
21 \********************************************************************/
22 
23 /** @addtogroup Class
24   This file defines a class messaging system reminiscent of
25   traditional OO-style setter and getter interfaces to object
26   properties.  A C-language object can declare a collection
27   of setters and getters on itself that can then be used
28   to perform run-time (as opposed to compile-time) bindings
29   to the object.
30 
31   To put it differently, a QOF class is a set of parameter
32   getters and setters that are associated with an object type.
33   Given a pointer to some thing, the setters and getters can
34   be used to get and set values out of that thing.  Note
35   that the pointer to "some thing" need not be a pointer
36   to a QOF Entity or Instance (although QOF classes are
37   more interesting when used with Entities/Instances).
38   What "some thing" is defined entirely by the programmer
39   declaring a new QOF Class.
40 
41   Because a QOF Class associates getters and setters with
42   a type, one can then ask, at run time, what parameters
43   are associated with a given type, even if those parameters
44   were not known at compile time.  Thus, a QOF Class is
45   sort-of like a DynAny implementation.  QOF classes can
46   be used to provide "object introspection", i.e. asking
47   object to describe itself.
48 
49   The QOF Query subsystem depends on QOF classes having been
50   declared; the Query uses the getters to get values associated
51   with particular instances.
52 
53   A QofAccessFunc or QofSetterFunc do not need to be public
54   functions, if you need to add functions to an object with an
55   established API, define the additional QOF routines as static.
56   Only the register routine needs to be public.
57 @{ */
58 
59 /** @file qofclass.h
60     @brief API for registering parameters on objects
61     @author Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU>
62     @author Copyright (C) 2003 Linas Vepstas <linas@linas.org>
63     @author Copyright (c) 2005,2006 Neil Williams <linux@codehelp.co.uk>
64 */
65 
66 #ifndef QOF_CLASS_H
67 #define QOF_CLASS_H
68 
69 #include "qofid.h"
70 
71 #define QOF_MOD_CLASS "qof-class"
72 
73 /** \name Core types
74 
75 Core data types for objects that can be used in parameters.
76 Note that QofIdTypes may also be used and will create a
77 single reference between two known objects.
78 
79  @{
80  */
81 
82 #define QOF_TYPE_STRING    "string"
83 #define QOF_TYPE_TIME      "time"
84 #define QOF_TYPE_NUMERIC   "numeric"
85 #define QOF_TYPE_DEBCRED   "debcred"
86 #define QOF_TYPE_GUID      "guid"
87 #define QOF_TYPE_INT32     "gint32"
88 #define QOF_TYPE_INT64     "gint64"
89 #define QOF_TYPE_DOUBLE    "double"
90 #define QOF_TYPE_BOOLEAN   "boolean"
91 #define QOF_TYPE_KVP       "kvp"
92 #define QOF_TYPE_CHAR      "character"
93 /** \brief secondary collections
94 are used for one-to-many references between entities and are
95 implemented using ::QofCollection.
96 These are \b NOT the same as the main collections in the QofBook.
97 
98 -# Each ::QofCollection contains one or many entities - *all* of a single type.
99 -# The entity type within the collection can be determined at run time.
100 -# Easy conversions to GList or whatever in the param_setfcn handler.
101 -# Each parameter can have its own collection.
102 -# Each entity can have a different *type* of collection to its siblings,
103 provided that it is acceptable to the set function.
104 -# Each object decides which types are acceptable for which parameter in the
105 set functions. This is then part of the API for that object.
106 
107 QOF_TYPE_COLLECT has two functions, both related to one-to-many
108 links:
109 - Represent a reference between 2 entities with a list of acceptable types.
110         (one object linked to many types of single entities)
111 - Represent a reference between one entity and many entities of another type.
112         (one object linked to many entities of a single type.)
113 
114 If the set function can handle it, it could also be used for true one-to-many
115 links: one object linked to many entities of many types.
116 
117 n.b. Always subject to each collection holding only one type at runtime.
118 (otherwise use books).
119 
120 */
121 #define QOF_TYPE_COLLECT   "collection"
122 
123 /** @} */
124 /** Type of Paramters (String, Date, Numeric, GUID, etc.) */
125 typedef const gchar *QofType;
126 
127 typedef struct _QofParam QofParam;
128 
129 /** The QofAccessFunc defines an arbitrary function pointer
130  *  for access functions.  This is needed because C doesn't have
131  *  templates, so we just cast a lot.  Real functions must be of
132  *  the form:
133  *
134  *        param_type getter_func (object_type *self);
135  *  or
136  *        param_type getter_func (object_type *self, QofParam *param);
137  *
138  * The additional argument 'param' allows generic getter functions
139  * to be implemented, because this argument provides for a way to
140  * identify the expected getter_func return type at runtime.  It
141  * also provides a place for the user to hang additional user-defined
142  * data.
143  */
144 typedef gpointer (*QofAccessFunc) (gpointer object, const QofParam * param);
145 
146 /** The QofSetterFunc defines an function pointer for parameter
147  *  setters. Real functions must be of the form:
148  *
149  * void setter_func (object_type *self, param_type *param);
150  */
151 typedef void (*QofSetterFunc) (gpointer, gpointer);
152 
153 /** This structure is for each queriable parameter in an object
154  *
155  * -- param_name is the name of the parameter.
156  * -- param_type is the type of the parameter, which can be either another
157  *    object (QofIdType) or it can be a core data type (QofType).
158  * -- param_getfcn is the function to actually obtain the parameter
159  * -- param_setfcn is the function to actually set the parameter
160  * -- param_userdata is a place where the object author can place any
161  *    desired object-author-defined data (and thus can be used by the
162  *    author-defined setter/getter).
163  *
164  * Either the getter or the setter may be NULL.
165  *
166  *  XXX todo/fixme: need to define a destroy callback, so that when
167  * the param memory is freed, the callback can be used to release the
168  * user-defined data.
169  */
170 struct _QofParam
171 {
172 	const gchar *param_name;
173 	QofType param_type;
174 	QofAccessFunc param_getfcn;
175 	QofSetterFunc param_setfcn;
176 	gpointer param_userdata;
177 };
178 
179 /** This function is the default sort function for a particular object type */
180 typedef
181 gint (*QofSortFunc) (gconstpointer, gconstpointer);
182 
183 /** \brief registers a new object class with the Qof subsystem.
184  *
185  *  In particular, it registers the set of setters and getters for
186  *  controlling the object.   The getters are typically used by the
187  *  query subsystem to query type specific data.   Note that there
188  *  is no particular requirement for there to be a setter for every
189  *  getter or even vice-versa, nor is there any requirement for these
190  *  to map 'cleanly' or orthogonally to the underlying object.  The
191  *  parameters are really just a set of value setting and getting
192  *  routines.
193  *
194  *  The "params" argument must be a NULL-terminated array of QofParam
195  *  with a constant storage size. It may be NULL if there are no
196  *  parameters to be registered. When creating dynamic QofObjects,
197  *  ensure the array is long enough for all objects. Registration
198  *  will stop at the first NULL parameter.
199  */
200 void qof_class_register (QofIdTypeConst obj_name,
201 						 QofSortFunc default_sort_fcn,
202 						 const QofParam * params);
203 
204 /** An example:
205  \verbatim
206  #define MY_OBJ_MEMO     "memo"
207  #define MY_OBJ_VALUE    "value"
208  #define MY_OBJ_TIME     "time"
209  #define MY_OBJ_ACCOUNT  "account"
210  #define MY_OBJ_TRANS    "trans"
211 
212  static QofParam myParams[] = {
213  { MY_OBJ_MEMO, QOF_TYPE_STRING, myMemoGetter, NULL },
214  { MY_OBJ_VALUE, QOF_TYPE_NUMERIC, myValueGetter, NULL },
215  { MY_OBJ_TIME, QOF_TYPE_TIME, myTimeGetter, NULL },
216  { MY_OBJ_ACCOUNT, GNC_ID_ACCOUNT, myAccountGetter, NULL },
217  { MY_OBJ_TRANS, GNC_ID_TRANS, myTransactionGetter, NULL },
218  NULL };
219 
220  qof_class_register ("myObjectName", myObjectCompare, &myParams);
221  \endverbatim
222 */
223 
224 /** Return true if the the indicated type is registered,
225  *  else return FALSE.
226  */
227 gboolean
228 qof_class_is_registered (QofIdTypeConst obj_name);
229 
230 /** Return the core datatype of the specified object's parameter */
231 QofType
232 qof_class_get_parameter_type (QofIdTypeConst obj_name,
233 							  const gchar *param_name);
234 
235 /** Return the registered Parameter Definition for the requested parameter */
236 const QofParam *
237 qof_class_get_parameter (QofIdTypeConst obj_name,
238 						const gchar *parameter);
239 
240 /** Return the object's parameter getter function */
241 QofAccessFunc
242 qof_class_get_parameter_getter (QofIdTypeConst obj_name,
243 								const gchar *parameter);
244 
245 /** Return the object's parameter setter function */
246 QofSetterFunc
247 qof_class_get_parameter_setter (QofIdTypeConst obj_name,
248 								const gchar *parameter);
249 
250 /** Type definition for the class callback function. */
251 typedef void (*QofClassForeachCB) (QofIdTypeConst, gpointer);
252 
253 /** Call the callback once for each object class that is registered
254  *  with the system.  The 'user_data' is passed back to the callback.
255  */
256 void
257 qof_class_foreach (QofClassForeachCB, gpointer user_data);
258 
259 /** Type definition for the paramter callback function. */
260 typedef void (*QofParamForeachCB) (QofParam *, gpointer user_data);
261 
262 /** Call the callback once for each parameter on the indicated
263  *  object class.  The 'user_data' is passed back to the callback.
264  */
265 void
266 qof_class_param_foreach (QofIdTypeConst obj_name,
267 						 QofParamForeachCB, gpointer user_data);
268 
269 /** \brief List of the parameters that could be references.
270 
271 Simple check to return a GList of all parameters
272 of this object type that are not known QOF data types.
273 Used for partial QofBook support, see ::QofEntityReference
274 */
275 GList *
276 qof_class_get_referenceList (QofIdTypeConst type);
277 
278 #endif /* QOF_CLASS_H */
279 /** @} */
280 /** @} */
281