Imported Upstream version 1.0beta1
[platform/upstream/syncevolution.git] / src / synthesis / src / sysync_SDK / Sources / sync_dbapi.h
1 /*
2  *  File:    sync_dbapi.h
3  *
4  *  Author:  Beat Forster (bfo@synthesis.ch)
5  *
6  *  C/C++    Programming interface between the
7  *           Synthesis SyncML engine and
8  *           the database layer for plug-ins
9  *
10  *  Copyright (c) 2005-2009 by Synthesis AG (www.synthesis.ch)
11  *
12  */
13
14 /*
15  * This is the calling interface between the Synthesis SyncML engine
16  * and a customized module "sync_dbapi".
17  * The same interface can be used either for Standard C or for C++.
18  * And there is a equivalent interface for JNI (Java Native Interface).
19  * Normally the customized module will be compiled as DLL and will
20  * be called by the SyncML engine. A linkable library is available
21  * (for C++) as well.
22  *
23  * For more detailed information about the DBApi interface
24  * please consult the SDK_manual.pdf which contains a tutorial,
25  * detailed descriptions and some example code.
26  *
27  * The flow for accessing the datastores is always the same:
28  * The SyncML engine will call these routines step by step
29  *
30  *  DATASTORE ACCESS FLOW
31  *  =====================
32  *
33  *   1)  CreateContext
34  *   2) [ContextSupport]   (optional)
35  *   3) [FilterSupport]    (optional)
36  *   4) [Read Admin Data]  (optional)
37  *
38  *   5)  StartDataRead
39  *   6)  do ReadNextItem while (aStatus!=ReadNextItem_EOF);
40  *   7)  any number of random calls to:
41  *         -  ReadItem
42  *         -  ReadBlob
43  *         - [AdaptItem]   (optional)
44  *   8)  EndDataRead
45  *
46  *   9)  StartDataWrite
47  *  10)  any number of random calls to:
48  *         -  InsertItem
49  *         -  UpdateItem
50  *         -  DeleteItem
51  *         -  DeleteSyncSet
52  *         -  ReadItem
53  *         -  WriteBlob
54  *         -  ReadBlob
55  *         -  DeleteBlob
56  *         - [AdaptItem]      (optional)
57  *         -  FinalizeLocalID (at the end)
58  *  11)  EndDataWrite
59  *
60  *  12) [Write Admin Data] (optional)
61  *  13)  DeleteContext
62  *
63  *
64  *  NOTE: 'DisposeObj' calls can occur anywhere between any statement
65  *        of the flow above (but not before 'CreateContext' and not after
66  *        'DeleteContext'). The SyncML engine is responsible for
67  *        disposing all <aItemData> and <aItemID> objects after use.
68  *
69  *  NOTE: Returned errors (value > 0) will influence the flow
70  *        Error at 1)      will not call any further step.
71  *          "   "  2)..3)  these functions do not return errors
72  *          "   "  5)..10) will cause an 'EndDataWrite' call with
73  *                         <success> = false, then 'DeleteContext'.
74  *          "   "  4)
75  *                11)..12) 'DeleteContext' will be called afterwards.
76  *
77  *  The module must be able to handle several contexts in parallel.
78  *  All routines will have an <aContext> parameter (assigned by
79  *  'CreateContext'), which allows to identify the correct context.
80  *  Routines can be called from different threads, but they are
81  *  always sequential for each context. If the thread changes,
82  *  'ThreadMayChangeNow' will notify the module about this issue.
83  *  This routine can left empty and ignored, if not used.
84  *
85  *  NOTE: As the SyncML engine calls the plug-in multithreaded,
86  *        all global structure accesses must be thread save.
87  */
88
89
90 #ifndef SYNC_DBAPI_H
91 #define SYNC_DBAPI_H
92
93 /* Global declarations */
94 #include "sync_dbapidef.h"
95
96
97 #if defined __cplusplus
98   /* combine the definitions of different namespaces */
99   using sysync::sInt32;
100   using sysync::uInt32;
101   using sysync::CContext;
102   using sysync::CVersion;
103   using sysync::TSyError;
104   using sysync::ItemID;
105   using sysync::MapID;
106   using sysync::cItemID;
107   using sysync::cMapID;
108   using sysync::appCharP;
109   using sysync::cAppCharP;
110   using sysync::appPointer;
111   using sysync::memSize;
112   using sysync::KeyH;
113   using sysync::SDK_Interface_Struct;
114   using sysync::DB_Callback;
115   using sysync::UI_Call_In;
116 #endif
117
118
119 /* C/C++ and DLL/library support
120  * SYSYNC_ENGINE     : true ( within the engine itself )         / false ( outside )
121  * SYSYNC_ENGINE_TEST: true ( within a test engine module )      / false ( outside )
122  * DBAPI_LINKED      : true ( at standalone APP, e.g. "helloX" ) / false ( within engine/within DLL )
123  * PLUGIN_INFO       : true ( within "plugin_info" program )     / false ( everywhere else )
124  */
125 #if !defined SYSYNC_ENGINE && !defined SYSYNC_ENGINE_TEST && !defined DBAPI_LINKED && !defined PLUGIN_INFO && !defined DLL_EXPORT
126   #define DLL_EXPORT 1
127 #endif
128
129 #undef    _ENTRY_ /* could be defined already here */
130 #ifdef DLL_EXPORT
131   #define _ENTRY_ ENGINE_ENTRY
132 #else
133   #define _ENTRY_
134 #endif
135
136
137 /* -- MODULE -------------------------------------------------------------------- */
138 /*! Create a module context \<mContext>
139  *  This routine will be called as the 2nd call, when the module will be connected.
140  *  (The 1st call is a 'Module_Version( 0 )' call outside any context).
141  *
142  *  It will be called not only once, but once for each session and datastore context,
143  *  as defined at the XML config file. This routine can return error 20028 (LOCERR_ALREADY),
144  *  if already created. This will be treated not as an error. For this case, it must
145  *  return the same \<mContext> as for the former call(s).
146  *
147  *  NOTE: The module context can exist once and can be shared for all plug-in accesses.
148  *        This can either be done with an allocated global variable at the plug-in or
149  *        even better using the "GlobContext" structure provided by the SyncML engine.
150  *        Please note, that write access to such a common module context structure must
151  *        be thread-safe, when accessed from the session or datastore context.
152  *        All the 'Module_CreateContext' calls for this module will be called
153  *        sequentially by one thread. The plug-in programmer is responsible not to
154  *        re-initialize the context for subsequent calls.
155  *
156  * If the module name at the XML config file is defined as "aaa!bbb!ccc" it will be passed
157  * as "aaa" to \<moduleName> and "bbb!ccc" to \<subName>. This mechanism can be used to
158  * cascade plug-in modules, where the next module gets "bbb" as \<moduleName> and "ccc" as
159  * \<subName>. The JNI plug-in for Java is using this structure to address the JNI plug-in
160  * and its assigned Java class. Error 20034 (LOCERR_UNKSUBSYSTEM) should be returned in case
161  * the subsystem does not exist, no error if no subsystem has been chosen at all.
162  *
163  *
164  *  @param  <mContext>     Returns a value, which allows to identify this module context.
165  *                         Allowed values: Anything except 0, which is reserved for no context.
166  *  @param  <moduleName>   Name of this plug-in
167  *  @param  <subName>      Name of sub module (if available)
168  *  @param  <mContextName> Name of the (datastore) context, e.g. "contacts";
169  *                         this string is empty for calll concerning the session.
170  *  @param  <mCB>          DB_Callback structure for module logging
171  *
172  *  @return  error code     if context could not be created       (e.g. not enough memory)
173  *           LOCERR_ALREADY if global module context already exists (not treated as error)
174  *           0              if context successfully created.
175  */
176 _ENTRY_ TSyError Module_CreateContext( CContext *mContext, cAppCharP   moduleName,
177                                                            cAppCharP      subName,
178                                                            cAppCharP mContextName,
179                                                          DB_Callback mCB );
180
181
182
183 /*! Get the module's version.
184  *
185  *  NOTE: The SyncML will take decisions depending on this version number, so
186  *  the plug-in developer should not change the values at the delivered sample code.
187  *  Plugin_Version( short buildNumber ) of 'SDK_util' should be used.
188  *  The \<buildNumber> can be defined by the user.
189  *
190  *  NOTE: This function can be called by the engine outside any context with
191  *  \<mContext> = 0. For this case, any callback is not permitted (as no DB_Callback
192  *  is available).
193  *
194  *  @param  <mContext>      The module context ( 0, if none ).
195  *  @return current version as SDK_VERSION_MAJOR | SDK_VERSION_MINOR)
196  *                           | SDK_SUBVERSION    | buildNumber
197  */
198 _ENTRY_ CVersion Module_Version( CContext mContext );
199
200
201
202 /*! Get the module's capabilities
203  *  Currently the SyncML engine currently understands and supports:
204  *   - "plugin_sessionauth"
205  *   - "plugin_deviceadmin"
206  *   - "plugin_datastoreadmin"
207  *   - "plugin_datastore"
208  *
209  *  If one of these identifiers will be defined as "no" ( e.g. "plugin_sessionauth:no" ),
210  *  the according routines will not be connected and used.
211  *
212  *  NOTE: The \<mCapabilities> can be allocated with "StrAlloc" (SDK_util.h) for C/C++
213  *
214  *  @param  <mContext>      The module context.
215  *  @param  <mCapabilities> Returns the module's capabilities as multiline
216  *                          aa:bb\<CRLF>cc:dd[\<CRLF>]
217  *  @return  error code
218  */
219 _ENTRY_ TSyError Module_Capabilities( CContext mContext, appCharP *mCapabilities );
220
221
222
223 /*! The module's config params will be sent to the plug-in.
224  *  It can be used for access path definitions or other things.
225  *  The \<plugin_params> can be defined individually for each session and datastore.
226  *  The SyncML engine checks the syntax, but not the content.
227  *  This routine should return an error 20010 (LOCERR_CFGPARSE), if one of
228  *  these parameters is not supported.
229  *
230  *  EXAMPLE: Definition at XML config file:\n
231  *             \<plugin_params>\n
232  *               \<datapath>/var/log/sysync\</datapath>\n
233  *               \<ultimate_answer>42\</ultimate_answer>\n
234  *             \</plugin_params>
235  *
236  *           will be passed as:\n
237  *             "datapath:/var/log/sysync\n
238  *              ultimate_answer:42"
239  *
240  *  NOTE: Module_PluginParams will be called ALWAYS for each module context,
241  *        even if no plug-in parameter is defined. This allows to react consistently
242  *        on parameters, which are not always available.
243  *
244  *  @param  <mContext>      The module context.
245  *  @param  <mConfigParams> The plugin params as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
246  *  @param  <engineVersion> The SyncML engine's version
247  *  @return  error code
248  */
249 _ENTRY_ TSyError Module_PluginParams( CContext mContext, cAppCharP mConfigParams,
250                                                           CVersion engineVersion );
251
252
253
254 /*! Disposes memory, which has been allocated within the module context.
255  *  (At the moment this is only the capabilities string).
256  *  'Module_DisposeObj' can occur at any time within \<mContext>.
257  *
258  *  NOTE: - If \<mCapabilities> has been allocated with "StrAlloc", use "Str_Dispose"
259  *          (SDK_util.h) to release the memory again.
260  *        - If it is defined as const within the plugin module (the module
261  *          itself knows about !), this routine can be implemented empty.
262  *
263  *  @param  <mContext>  The module context.
264  *  @param  <memory>    Dispose allocated memory.
265  *  @return  -
266  */
267 _ENTRY_ void Module_DisposeObj( CContext mContext, void* memory );
268
269
270
271 /*! This routine will be called as the last call, before this module is disconnected.
272  *  The SyncML engine will call 'Module_DisposeObj' (if required) before this call
273  *
274  *  NOTE: This routine will be called ONLY, if the server stops in a controlled way.
275  *        Its good programming practice not to wait for this 'DeleteContext' call.
276  *
277  *  @param  <mContext>  The module context.
278  *  @return  error code
279  */
280 _ENTRY_ TSyError Module_DeleteContext( CContext mContext );
281
282
283
284
285 /* -- SESSION ------------------------------------------------------------------- */
286 /*! By default the session context will be handled by the ODBC interface.
287  *  The session context of this plug-in module will be used only,
288  *  if \<server type="plugin"> and \<plugin_module> is defined
289  *  ( \<plugin_module>name_of_the_plugin\</plugin_module> ).
290  *  \<plugin_params> can be defined individually.
291  *
292  *  @param  <sContext>    Returns a value, which allows to identify this session context.
293  *  @param  <sessionName> Name of this session
294  *  @param  <sCB>         DB_Callback structure for session logging
295  *
296  *  @result  error code, if context could not be created (e.g. not enough memory)
297  *           0           if context successfully created,
298  *
299  *  Flags (at the XML config file):
300  *  - \<plugin_deviceadmin>yes\</plugin_deviceadmin>: "Session_CheckDevice", "Session_GetNonce"
301  *                                                    "Session_SaveNonce" and
302  *                                                    "Session_SaveDeviceInfo" will be used.
303  *
304  *  - \<plugin_sessionauth>yes\</plugin_sessionauth>: "Session_PasswordMode",
305  *                                                    "Session_Login" and "Session_Logout" will be used.
306  */
307 _ENTRY_ TSyError Session_CreateContext( CContext *sContext, cAppCharP sessionName,
308                                                           DB_Callback sCB );
309
310
311
312 /*! This function adapts itemData
313  *
314  *  @param  <sContext>    The session context
315  *  @param  <sItemData1>  The 1st item's data
316  *  @param  <sItemData2>  The 2nd item's data
317  *  @param  <sLocalVars>  The local vars
318  *  @param  <sIdentifier> To identify, where it is called
319  *
320  *  @return  error code
321  *
322  *  NOTE:   The memory for adapted strings must be allocated locally.
323  *          The SyncML engine will call 'DisposeObj' later, to release again its memory.
324  *          One or more strings can be returned unchanged as well.
325  */
326 _ENTRY_ TSyError Session_AdaptItem( CContext sContext, appCharP *sItemData1,
327                                                        appCharP *sItemData2,
328                                                        appCharP *sLocalVars,
329                                                          uInt32  sIdentifier );
330
331
332 /*! Check the database entry of \<aDeviceID> and return its \<nonce> string.
333  *  If \<aDeviceID> is not yet available at the plug-in, return "" for \<nonce>
334  *
335  *  @param  <sContext>   The session context
336  *  @param  <aDeviceID>  The assigned device ID string
337  *  @param  <sDevKey>    The device key string (will be used for datastore accesses later)
338  *  @param  <nonce>      The nonce string of the last session
339  *                       If \<aDeviceID> is not yet available, return "" for \<nonce>
340  *                       and error code 0.
341  *
342  *  @result  error code 403 (Forbidden), if plugin_deviceadmin is not supported;
343  *                        0, if successful
344  *
345  *  USED ONLY WITH \<plugin_deviceadmin>
346  */
347 _ENTRY_ TSyError Session_CheckDevice( CContext sContext, cAppCharP  aDeviceID,
348                                                           appCharP *sDevKey,
349                                                           appCharP *nonce );
350
351
352 /*! Get a new nonce from the database. If this routine returns an error,
353  *  the SyncML engine will create its own nonce.
354  *
355  *  @param  <sContext>   The session context
356  *  @param  <nonce>      A valid new nonce value (for the assigned device ID).
357  *
358  *  @return  error code 404 (NotFound), if no \<nonce> has been generated;
359  *                       0, if a valid \<nonce> has been generated
360  *
361  *  USED ONLY WITH \<plugin_deviceadmin>
362  */
363 _ENTRY_ TSyError Session_GetNonce( CContext sContext, appCharP *nonce );
364
365
366
367 /*! Save the new nonce (which will be expected to be returned in the
368  *  next session for this device ID.
369  *
370  *  @param  <sContext>   The session context
371  *  @param  <nonce>      New \<nonce> for the next session (of the assigned device ID)
372  *
373  *  @result  error code 403 (Forbidden), if plugin_deviceadmin is not supported;
374  *                        0,             if successful
375  *
376  *  USED ONLY WITH \<plugin_deviceadmin>
377  */
378 _ENTRY_ TSyError Session_SaveNonce( CContext sContext, cAppCharP nonce );
379
380
381
382 /*! Save the device info for \<sContext>
383  *
384  *  @param  <sContext>     The session context
385  *  @param  <aDeviceInfo>  More information about the assigned device (for DB and logging)
386  *
387  *  @result  error code 403 (Forbidden), if plugin_deviceadmin is not supported;
388  *                        0,             if successful
389  *
390  *  USED ONLY WITH \<plugin_deviceadmin>
391  */
392 _ENTRY_ TSyError Session_SaveDeviceInfo( CContext sContext, cAppCharP aDeviceInfo );
393
394
395
396 /*! Get the current DB time of \<sContext>
397  *
398  *  @param  <sContext>       The session context
399  *  @param  <currentDBTime>  The current time of the plugin's DB (as ISO8601 format).
400  *
401  *  @result  error code 403 (Forbidden), if plugin_deviceadmin is not supported;
402  *                      404 (NotFound),  if not available -> the engine creates its own time
403  *                        0,             if successful
404  */
405 _ENTRY_ TSyError Session_GetDBTime( CContext sContext, appCharP *currentDBTime );
406
407
408
409 /*--------------------------------------------------------------------------------*/
410 /*! Get the password mode.
411  *  There are currently 4 different password modes supported.
412  *
413  *  @param <sContext>          The session context
414  *
415  *  @result
416  *    - Password_ClrText_IN  : 'SessionLogin' will get    clear text password
417  *    - Password_ClrText_OUT :        "       must return clear text password
418  *    - Password_MD5_OUT     :        "       must return MD5 coded  password
419  *    - Password_MD5_Nonce_IN:        "       will get    MD5B64(MD5B64(user:pwd):nonce)
420  *
421  *  USED ONLY WITH \<plugin_sessionauth>
422  */
423 _ENTRY_ sInt32 Session_PasswordMode( CContext sContext );
424
425
426 /*! Get \<sUsrKey> of \<sUsername>,\<sPassword> in the session context.
427  *
428  *  @param  <sContext>   The session context
429  *  @param  <sUsername>  The user name ...
430  *  @param  <sPassword>  ... and the password. \<sPassword> is an input parameter
431                          for 'Password_ClrTxt_IN' mode and an output parameter for
432  *                       'Password_ClrText_OUT' and 'Password_MD5_OUT' modes.
433  *  @param  <sUsrKey>    Returns the internal reference key, which will be passed to
434  *                       to the datastore contexts later.
435  *
436  *  @result  error code 403 (Forbidden), if plugin_sessionauth is not supported;
437  *                        0, if successful
438  *
439  *  USED ONLY WITH \<plugin_sessionauth>
440  */
441 _ENTRY_ TSyError Session_Login( CContext sContext, cAppCharP  sUsername,
442                                                     appCharP *sPassword,
443                                                     appCharP *sUsrKey );
444
445
446 /*! Logout for this session context
447  *
448  *  @param  <sContext>  The session context
449  *
450  *  @result  error code 403 (Forbidden), if plugin_sessionauth is not supported;
451  *                        0, if successful
452  *
453  *  USED ONLY WITH \<plugin_sessionauth>
454  */
455 _ENTRY_ TSyError Session_Logout( CContext sContext );
456
457
458
459 /*! Disposes memory, which has been allocated within the session context.
460  *  'Session_DisposeObj' can occur at any time within \<sContext>.
461  *
462  *  @param  <sContext>  The session context.
463  *  @param  <memory>    Dispose allocated memory.
464  *
465  *  @return  -
466  */
467 _ENTRY_ void Session_DisposeObj( CContext sContext, void* memory );
468
469
470
471 /*! Due to the architecture of the SyncML engine, the system may run in a multithread
472  *  environment. The consequence is that each routine of this plugin module can be
473  *  called by a different thread. Normally this is not a problem, nevertheless
474  *  this routine notifies about thread changes in \<sContext>.
475  *  It can be ignored ( =implemented empty), if not really needed.
476  *
477  *  @param  <sContext>      The session context
478  *  @return  -
479  */
480 _ENTRY_ void Session_ThreadMayChangeNow( CContext sContext );
481
482
483
484 /*! Writes the context of all items to dbg output path
485  *  This routine is implemented for debug purposes only and will NOT BE CALLED by the
486  *  SyncML engine. Can be implemented empty
487  *
488  *  @param  <sContext>      The session context
489  *  @param  <allFields>     true : all fields, also empty ones, will be displayed;
490  *                          false: only fields <> "" will be shown
491  *  @param  <specificItem>  ""   : all items will be shown;
492  *                          else   shows the \<specificItem>
493  *
494  *  @return  -
495  */
496 _ENTRY_ void Session_DispItems( CContext sContext, bool allFields, cAppCharP specificItem );
497
498
499
500 /*! Delete a session context.
501  *  No access to \<sContext> will be done after this call
502  *
503  *  @param  <sContext>  The session context
504  *  @return  error code, if context could not be deleted.
505  */
506 _ENTRY_ TSyError Session_DeleteContext( CContext sContext );
507
508
509
510
511 /* -- OPEN ---------------------------------------------------------------------- */
512 /*! This routine is called to create a new context for a datastore access.
513  *  It must allocate all resources for this context and initialize the \<aContext>
514  *  parameter with a value that allows re-identifying the context.
515  *  \<aContext> can either be a pointer to the local context structure or any key
516  *  value which allows to re-identify the context later.
517  *  Subsequent calls related to this context will pass the \<aContext> value as returned
518  *  from CreateContext. The context must be valid until 'DeleteContext' is called.
519  *  \<plugin_params> can be defined individually.
520  *
521  *  NOTE:   The SyncML engine treats \<aContext> simply as a key. The only condition
522  *          is uniqueness for all datastore contexts. Even \<aContext> = 0 can be used.
523  *
524  *  @param  <aContext>     Returns a value, which allows to identify this datastore context.
525  *  @param  <aContextName> Allows to identify the context, if more than one must be
526  *                         handled. \<contextName> is defined at the XML configuration.
527  *  @param  <aCB>          DB_Callback structure for datatstore logging.
528  *  @param  <sDevKey>      The result of 'Session_CheckDevice' comes in here.
529  *  @param  <sUsrKey>      The result of 'Session_Login'       comes in here.
530  *
531  *  @return  error code, if context could not be created (e.g. not enough memory),
532  *           0           if context successfully created.
533  */
534 _ENTRY_ TSyError CreateContext( CContext *aContext, cAppCharP aContextName, DB_Callback aCB,
535                                                     cAppCharP sDevKey,
536                                                     cAppCharP sUsrKey );
537
538
539 /*! This function asks for specific context configurations
540  *
541  *  @param  <aContext>      The datastore context
542  *  @param  <aSupportRules> The SyncML sends a list of support rules.
543  *                          This function has to reply, up to which rule,
544  *                          contexts are supported (and switched on now).
545  *                          Data is formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
546  *
547  *  @return  Up to \<n> fields are supported (and switched on) for this context.
548  *           If 0 will be returned, no field of \<aSupportRules> is supported.
549  *
550  */
551 _ENTRY_ uInt32 ContextSupport( CContext aContext, cAppCharP aSupportRules );
552
553
554
555 /*! This function asks for filter support.
556  *
557  *  @param  <aContext>      The datastore context
558  *  @param  <aFilterRules>  The SyncML sends a list of filter rules.
559  *                          This function has to reply, up to which rule,
560  *                          filters are supported (and switched on now).
561  *                          Data is formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
562  *
563  *  @return  Up to \<n> filters are supported (and switched on) for this context
564  *           If 0 will be returned, no field of \<aFilterRules> are supported.
565  */
566 _ENTRY_ uInt32 FilterSupport( CContext aContext, cAppCharP aFilterRules );
567
568
569
570 /* -- GENERAL ------------------------------------------------------------------- */
571 /*! Due to the architecture of the SyncML engine, the system may run in a multithread
572  *  environment. The consequence is that each routine of this API module can be
573  *  called by a different thread. Normally this is not a problem, nevertheless
574  *  this routine notifies about thread changes in \<aContext>.
575  *  It can be ignored ( =implemented empty), if not really needed.
576  *
577  *  @param  <aContext>  The datastore context.
578  *
579  *  @result  -
580  */
581 _ENTRY_ void ThreadMayChangeNow( CContext aContext );
582
583
584
585 /*! This functions writes \<logData> for this context
586  *  Can be implemented empty, if not needed.
587  *
588  *  @param  <aContext>  The datastore context.
589  *  @param  <logData>   Logging information, formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
590  *
591  *  @result  -
592  */
593 _ENTRY_ void WriteLogData( CContext aContext, cAppCharP logData );
594
595
596
597 /*! Writes the context of all items to dbg output path
598  *  This routine is implemented for debug purposes only and will NOT BE CALLED by the
599  *  SyncML engine. Can be implemented empty, if not needed.
600  *
601  *  @param  <aContext>      The datastore context.
602  *  @param  <allFields>
603  *                          - true : all fields, also empty ones, will be displayed;
604  *                          - false: only fields <> "" will be shown
605  *  @param  <specificItem>
606  *                          - ""   : all items will be shown;
607  *                          - else : shows the \<specificItem>
608  *
609  *  @return  -
610  */
611 _ENTRY_ void DispItems( CContext aContext, bool allFields, cAppCharP specificItem );
612
613
614
615 /* -- ADMINISTRATION ------------------------------------------------------------ */
616 /* This section contains the 'admin read' and 'admin write' routines. */
617
618 /*! This function gets the stored information about the record with the four paramters:
619  *  \<sDevKey>, \<sUsrKey>, \<aLocDB>, \<aRemDB>.
620  *
621  *  - \<plugin_deviceadmin>yes\</plugin_deviceadmin>: Admin/Map routines will be used.
622  *
623  *  @param  <aContext>   The datastore context
624  *  @param  <aLocDB>     Name of the local  DB
625  *  @param  <aRemDB>     Name of the remote DB
626  *  @param  <adminData>  The data, saved with the last 'SaveAdminData' call
627  *
628  *  @return  error code 404 (NotFound), if record is not (yet) available,
629  *                        0 (no error)  if admin data found
630  *
631  *  NOTE: \<sDevKey> and \<sUsrKey> have been passed with 'CreateContext' already.
632  *        The plug-in module must have stored them within the datastore context.
633  *
634  *  USED ONLY WITH \<plugin_datastoredadmin>
635  */
636 _ENTRY_ TSyError LoadAdminData( CContext aContext, cAppCharP aLocDB,
637                                                    cAppCharP aRemDB, appCharP *adminData );
638
639
640
641 /*! This functions stores the new \<adminData> for this context
642  *
643  *  @param  <aContext>   The datastore context
644  *  @param  <adminData>  The new set of admin data to be stored, will be loaded again
645  *                       with the next 'LoadAdminData' call.
646  *
647  *  @result  error code, if data could not be saved (e.g. not enough memory);
648  *                       0 if successfully created.
649  *
650  *  USED ONLY WITH \<plugin_datastoredadmin>
651  */
652 _ENTRY_ TSyError SaveAdminData( CContext aContext, cAppCharP adminData );
653
654
655
656 /*! Map table handling: Get the next map item of this context.
657  *  If \<aFirst> is true, the routine must start to return the first element
658  *
659  *  @param  <aContext>   The datastore context
660  *  @param  <mID>        MapID ( with \<localID>,\<remoteID>, <flags> and \<ident> ).
661  *  @param  <aFirst>     Starting with the first MapID. When creating a context,
662  *                       the first call will get the first MapID, even if \<aFirst>
663  *                       is false.
664  *
665  *  @return
666  *          - true:  as long as there is a MapID available, which must be assigned to <mID>
667  *          - false: if there is no more MapID. Nothing must be assigned to <mID>
668  *
669  *  USED ONLY WITH \<plugin_datastoredadmin>
670  */
671 _ENTRY_ bool ReadNextMapItem( CContext aContext, MapID mID, bool aFirst );
672
673
674 /*! Map table handling: Insert a map item of this context
675  *
676  *  @param  <aContext>   The datastore context
677  *  @param  <mID>        MapID ( with \<localID>,\<remoteID>, \<flags> and \<ident> ).
678  *
679  *  @return  error code, if this MapID can't be inserted, or if already existing
680  *
681  *  USED ONLY WITH \<plugin_datastoredadmin>
682  */
683 _ENTRY_ TSyError InsertMapItem( CContext aContext, cMapID mID );
684
685
686 /*! Map table handling: Update a map item of this context
687  *
688  *  @param  <aContext>   The datastore context
689  *  @param  <mID>        MapID ( with \<localID>,\<remoteID>, \<flags> and \<ident> ).
690  *                       If there is already a MapID element with \<localID> and \<ident>,
691  *                       it will be updated, else created.
692  *
693  *  @return  error code, if this MapID can't be updated (e.g. not yet existing).
694  *
695  *  USED ONLY WITH \<plugin_datastoredadmin>
696  */
697 _ENTRY_ TSyError UpdateMapItem( CContext aContext, cMapID mID );
698
699
700 /*! Map table handling: Delete a map item of this context
701  *
702  *  @param  <aContext>   The datastore context
703  *  @param  <mID>        MapID ( with \<localID>,\<remoteID>, \<flags> and \<ident> ).
704  *
705  *  @return  error code, if this MapID can't deleted,
706  *                    or if this MapID does not exist.
707  *
708  *  USED ONLY WITH \<plugin_datastoredadmin>
709  */
710 _ENTRY_ TSyError DeleteMapItem( CContext aContext, cMapID mID );
711
712
713
714
715 /* -- READ ---------------------------------------------------------------------- */
716 /*! This routine initializes reading from the database
717  *  StartDataRead must prepare the database to return the objects of this context.
718  *
719  *  @param  <aContext>     The datastore context.
720  *  @param  <lastToken>    The value which has been returned by this module
721  *                         at the last "EndDataWrite" call will be given.
722  *                         It will be "", when called the first time.
723  *                         Normally this token is an ISO8601 formatted string
724  *                         which represents the module's current time (at the
725  *                         beginning of a session). It will be used to decide at
726  *                         'ReadNextItem' whether a record has been changed.
727  *  @param   <resumeToken> Token for Suspend/Resume mode.
728  *
729  *  @return  error code
730  */
731 _ENTRY_ TSyError StartDataRead( CContext aContext, cAppCharP   lastToken,
732                                                    cAppCharP resumeToken );
733
734
735
736 /*! This routine reads the next ItemID from the database.
737  *  \<allfields>    of 'ContextSupport' ( "ReadNextItem:allfields" ) and
738  *  \<aFilterRules> of 'FilterSupport' must be considered.
739  *  If \<aFirst> is true, the routine must return the first element (again).
740  *
741  *  @param  <aContext>  The datastore context.
742  *  @param  <aID>       The assigned ItemID in the database;
743  *                      will be ignored by the SyncML engine, if \<aStatus> = 0
744  *  @param  <aItemData> The data, formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>];
745  *                      will be ignored by the SyncML engine, if \<aStatus> = 0
746  *  @param  <aStatus>
747  *                      - ReadItem_EOF       ( =0 ) for none ( =eof ),
748  *                      - ReadItem_Changed   ( =1 ) for a changed item,
749  *                      - ReadItem_Unchanged ( =2 ) for unchanged item.
750  *                      - ReadItem_Resumed   ( =3 ) for a changed item (since resumed)
751  *  @param  <aFirst>
752  *                      - true:  the routine must return the first element
753  *                      - false: the routine must return the next  element
754  *
755  *  @return  error code, if not ok. No datasets found is a success as well !
756  *
757  *
758  *  NOTE:   The memory for \<aID> and \<aItemData> must be allocated locally.
759  *          The SyncML engine will call 'DisposeObj' later for these objects to
760  *          release the memory again. It needn't to be allocated, if \<aStatus>
761  *          is ReadItem_EOF.
762  *
763  *  NOTE:   By default, the SyncML engine asks for \<aID> only.
764  *          \<aItemData> can be returned, if anyway available or
765  *          \<aItemData> must be returned, if the engine asks for it
766  *          (when calling "ReadNextItem:allfields" at 'ContextSupport' with \<allfields>).
767  */
768 _ENTRY_ TSyError ReadNextItem     ( CContext aContext, ItemID aID, appCharP *aItemData,
769                                      sInt32 *aStatus,    bool aFirst );
770
771 /*! This is the equivalent to 'ReadNextItem', but using a key instead of a data string */
772 _ENTRY_ TSyError ReadNextItemAsKey( CContext aContext, ItemID aID,     KeyH aItemKey,
773                                      sInt32 *aStatus,    bool aFirst );
774
775
776
777 /*! This routine reads the contents of a specific ItemID \<aID> from the database.
778  *
779  *  @param  <aContext>  The datastore context.
780  *  @param  <aID>       The assigned ItemID in the database
781  *  @param  <aItemData> Returns the data, formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
782  *
783  *  @return  error code, if not ok ( e.g. invalid \<aItemID> )
784  *
785  *
786  *  NOTE:   The memory for \<aItemData> must be allocated locally.
787  *          The SyncML engine will call 'DisposeObj' later for \<aItemData>,
788  *          to release again its memory.
789  */
790 _ENTRY_ TSyError ReadItem     ( CContext aContext, cItemID aID, appCharP *aItemData );
791
792 /*! This is the equivalent to 'ReadItem', but using a key instead of a data string */
793 _ENTRY_ TSyError ReadItemAsKey( CContext aContext, cItemID aID,     KeyH aItemKey );
794
795
796
797 /*! This routine reads the specific binary logic block \<aID>,\<aBlobID>
798  *  from the database.
799  *
800  *  @param  <aContext>  The datastore context.
801  *  @param  <aID>       ItemID ( with \<item>,\<parent> ).
802  *  @param  <aBlobID>   The assigned ID of the blob.
803  *
804  *  @param  <aBlkPtr>   Position and size (in bytes) of the blob block.
805  *  @param  <aBlkSize>
806  *                      - Input:  Maximum size (in bytes) of the blob block to be read.
807  *                                If \<blkSize> is 0, the result size is not limited.
808  *                      - Output: Size (in bytes) of the blob block.
809  *                                \<blkSize> must not be larger than its input value.
810  *  @param  <aTotSize>  Total size of the blob (in bytes), can be also 0,
811  *                      if not available, e.g. for a stream.
812  *
813  *  @param  <aFirst>    (Input)
814  *                      - true : Engine asks for the first block of this blob.
815  *                      - false: Engine asks for the next  block of this blob.
816  *
817  *  @param  <aLast>     (Output)
818  *                      - true : This is the last part (or the whole) blob.
819  *                      - false: More blocks will follow.
820  *
821  *  @return  error code, if not ok ( e.g. invalid \<aItemID>,\<aBlobID> )
822  *
823  *
824  *  NOTE 1) The memory at \<blkPtr>,\<blkSize> must be allocated locally.
825  *          The SyncML engine will call 'DisposeObj' later for \<blkPtr>,
826  *          to release the memory.
827  *
828  *  NOTE 2) Empty blobs are allowed, \<blkSize> and \<totSize> must be set to 0,
829  *          \<blkPtr> can be undefined, \<aLast> must be true.
830  *          No 'DisposeObj' call is required for this case.
831  *
832  *  NOTE 3) The SyncML engine can change to read another blob before
833  *          having read the whole blob. It will never resume reading of this
834  *          incomplete blob, but start reading again with \<aFirst> = true.
835  */
836 _ENTRY_ TSyError ReadBlob( CContext aContext, cItemID  aID,   cAppCharP  aBlobID,
837                                            appPointer *aBlkPtr, memSize *aBlkSize,
838                                                                 memSize *aTotSize,
839                                                  bool  aFirst,     bool *aLast );
840
841
842
843 /*! This routine terminates the read from database phase
844  *  It can be used e.g. for termination of a transaction.
845  *  In standard case it can be implemented empty, returning simply a value LOCERR_OK = 0.
846  *
847  *  @param  <aContext>   The datastore context.
848  *  @return  error code
849  */
850 _ENTRY_ TSyError EndDataRead( CContext aContext );
851
852
853
854
855 /* -- WRITE --------------------------------------------------------------------- */
856 /*! This routine initializes writing to the database
857  *
858  *  @param  <aContext>   The datastore context.
859  *  @return  error code, if not ok (e.g. invalid select options)
860  */
861 _ENTRY_ TSyError StartDataWrite( CContext aContext );
862
863
864
865 /*! This routine inserts a new dataset to the database. The assigned
866  *  new ItemID \<aId> will be returned.
867  *
868  *  @param  <aContext>   The datastore context.
869  *  @param  <aItemData>  The data, formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
870  *  @param  <aID>        Database key of the new dataset.
871  *
872  *  @return  error code
873  *             - LOCERR_OK     (   =0 ), if successful
874  *             - DB_DataMerged ( =207 ), if successful, but "ReadItem" requested to
875  *                                                      inform about updates
876  *             - DB_Forbidden  ( =403 ), if \<aItemData> can't be resolved
877  *             - DB_Full       ( =420 ), if not enough space in the DB
878  *             - ... or any other SyncML error code, see Reference Manual
879  *
880  *  NOTE:   The memory for \<aItemID> must be allocated locally.
881  *          The SyncML engine will call 'DisposeObj' later for \<aItemID>,
882  *          to release the memory
883  *
884  */
885 _ENTRY_ TSyError InsertItem     ( CContext aContext, cAppCharP aItemData, ItemID aID );
886
887 /*! This is the equivalent to 'InsertItem', but using a key instead of a data string */
888 _ENTRY_ TSyError InsertItemAsKey( CContext aContext,      KeyH aItemKey,  ItemID aID );
889
890
891
892 /*! This routine updates an existing dataset of the database
893  *
894  *  @param  <aContext>   The datastore context.
895  *  @param  <aItemData>  The data, formatted as multiline aa:bb\<CRLF>cc:dd[\<CRLF>]
896  *  @param  <aID>        Database key of dataset to be updated
897  *  @param  <updID>
898  *                       - Input:  NULL is assigned as default value to
899  *                                 \<updID.item> and \<updID.parent>.
900  *                       - Output: The updated database key for \<aID>.
901  *                                 Can be NULL,  if the same as \<aID>
902  *
903  *  @return  error code
904  *             - LOCERR_OK    (   =0 ), if successful
905  *             - DB_Forbidden ( =403 ), if \<aItemData> can't be resolved
906  *             - DB_NotFound  ( =404 ), if unknown  \<aID>
907  *             - DB_Full      ( =420 ), if not enough space in the DB
908  *             - ... or any other SyncML error code, see Reference Manual
909  *
910  *
911  *  NOTE:   \<updID> must either contain NULL references ( if the same as \<aID> ),
912  *          or the memory for \<updID.item>,\<updID.parent> must be allocated locally.
913  *          The SyncML engine will call 'DisposeObj' later for \<updID.item> and
914  *          \<updID.parent> to release the memory.
915  *          \<updID.parent> can be NULL, if the hierarchical model is not supported.
916  */
917 _ENTRY_ TSyError UpdateItem     ( CContext aContext, cAppCharP aItemData, cItemID   aID,
918                                                                            ItemID updID );
919
920 /*! This is the equivalent to 'UpdateItem', but using a key instead of a data string */
921 _ENTRY_ TSyError UpdateItemAsKey( CContext aContext,      KeyH aItemKey,  cItemID   aID,
922                                                                            ItemID updID );
923
924
925
926 /*! This routine moves \<aID.item> from \<aID.parent> to \<newParID>
927  *
928  *  @param  <aContext>  The datastore context.
929  *  @param  <aID>       ItemID ( with \<item>,\<parent> ) to be moved.
930  *  @param  <newParID>  New parent ID for \<aID>
931  *
932  *  @return  error code
933  *             - LOCERR_OK    (   =0 ), if successful
934  *             - DB_NotFound  ( =404 ), if unknown  \<newParID>
935  *             - DB_Full      ( =420 ), if not enough space in the DB
936  *             - ... or any other SyncML error code, see Reference Manual
937  */
938 _ENTRY_ TSyError MoveItem( CContext aContext, cItemID aID, cAppCharP newParID );
939
940
941
942 /*! This routine deletes a dataset from the database
943  *
944  *  @param  <aContext>  The datastore context.
945  *  @param  <aID>       ItemID ( with \<item>,\<parent> ) to be deleted.
946  *
947  *  @return  error code
948  *             - LOCERR_OK    (   =0 ), if successful
949  *             - DB_NotFound  ( =404 ), if unknown \<aItemID>
950  *             - ... or any other SyncML error code, see Reference Manual
951  */
952 _ENTRY_ TSyError DeleteItem( CContext aContext, cItemID aID );
953
954
955
956
957 /*! This routine updates a temporary <aID> to an <updID> at the end
958  *  For cached systems which assign IDs at the end of a run.
959  *
960  *  @param  <aContext>   The datastore context.
961  *  @param  <aID>        Database key of dataset to be updated
962  *  @param  <updID>
963  *                       - Input:  NULL is assigned as default value to
964  *                                 \<updID.item> and \<updID.parent>.
965  *                       - Output: The updated database key for \<aID>.
966  *                                 Can be NULL,  if the same as \<aID>
967  *
968  *  @return  error code
969  *             - LOCERR_OK     (     =0 ), if successful
970  *             - DB_Forbidden  (   =403 ), if \<aItemData> can't be resolved
971  *             - DB_NotFound   (   =404 ), if unknown \<aID>
972  *             - LOCERR_NOTIMP ( =20030 ), if no finalizing is needed at all
973  *             - ... or any other SyncML error code, see Reference Manual
974  *
975  *  NOTE:   \<updID> must either contain NULL references ( if the same as \<aID> ),
976  *          or the memory for \<updID.item> must be allocated locally.
977  *          The SyncML engine will call 'DisposeObj' later for \<updID.item>
978  *          to release the memory. \<updID.parent>should be always NULL.
979  */
980 _ENTRY_ TSyError FinalizeLocalID( CContext aContext, cItemID aID, ItemID updID );
981
982
983
984
985 /*! This routine deletes all datasets from the database
986  *
987  *  @param  <aContext>  The datastore context.
988  *
989  *  @return  error code
990  *             - LOCERR_OK     (     =0 ), if successful
991  *             - LOCERR_NOTIMP ( =20030 ). For this case, the engine removes all items directly
992  *             - ... or any other SyncML error code, see Reference Manual
993  */
994 _ENTRY_ TSyError DeleteSyncSet( CContext aContext );
995
996
997
998
999 /*! This routine writes the specific binary logic block \<blobID> to the database.
1000  *
1001  *  @param  <aContext>  The datastore context.
1002  *  @param  <aID>       ItemID ( with \<item>,\<parent> ).
1003  *  @param  <aBlobID>   The assigned ID of the blob.
1004  *
1005  *  @param  <aBlkPtr>
1006  *  @param  <aBlkSize>  Position and size (in bytes) of the blob block.
1007  *  @param  <aTotSize>  Total size of the blob (in bytes),
1008  *                      Can be also 0, if not available, e.g. for a stream.
1009  *
1010  *  @param  <aFirst>
1011  *                      - true : this is the first block of the blob.
1012  *                      - false: this is the next  block.
1013  *  @param  <aLast>
1014  *                      - true : this is the last  block.
1015  *                      - false: more blocks will follow.
1016  *
1017  *  @return  error code, if not ok ( e.g. invalid \<aID>,\<aBlobID> )
1018  *
1019  *  NOTE:   Empty blobs are possible, \<blkSize> and \<totSize> will be set to 0,
1020  *          \<blkPtr> will be NULL, \<aFirst> and \<aLast> will be true.
1021  */
1022 _ENTRY_ TSyError WriteBlob( CContext aContext, cItemID aID,   cAppCharP aBlobID,
1023                                             appPointer aBlkPtr, memSize aBlkSize,
1024                                                                 memSize aTotSize,
1025                                                   bool aFirst,     bool aLast );
1026
1027
1028 /*! This routine deletes the specific binary logic block \<blobID> at the database.
1029  *
1030  *  @param  <aContext>  The datastore context.
1031  *  @param  <aID>       ItemID ( with \<item>,\<parent> ).
1032  *  @param  <aBlobID>   The assigned ID of the blob.
1033  *
1034  *  @return  error code, if not ok ( e.g. invalid \<aID>,\<aBlobID> )
1035  */
1036 _ENTRY_ TSyError DeleteBlob( CContext aContext, cItemID aID, cAppCharP aBlobID );
1037
1038
1039 /*! Advises the database to finsish the running transaction
1040  *
1041  *  @param  <aContext>   The datastore context.
1042  *  @param  <success>
1043  *                       - true:  All former actions were successful,
1044  *                                so the database can commit
1045  *                       - false: The transaction was not successful,
1046  *                                so the database may rollback or ignore the transaction.
1047  *
1048  *  @param  <newToken>   An internally generated string value, which
1049  *                       will be used to identify changed database records.
1050  *                       It is normally an ISO8601 formatted string, which
1051  *                       represents the module's current time (at the
1052  *                       time the 'StartDataRead' of this context has been
1053  *                       called). All changed records of the currrent context
1054  *                       must get this token as timestamp as as well.
1055  *                       The SyncML engine will return this value with the
1056  *                       'StartDataRead' call within the next session.
1057  *                       It must return NULL in case of no \<success>.
1058  *
1059  *  @return  error code, if operation can't be performed. No \<success> is not an error.
1060  *
1061  *
1062  *  NOTE: By default, the SyncML engine expects an ISO8601 string for \<newToken>.
1063  *        But the SyncML engine can be configured to treat this value completely
1064  *        opaque, if implemented in a different way.
1065  *
1066  *        The \<newToken> must be allocated locally and will be
1067  *        disposed with a 'DisposeObj' call later by the SyncML engine.
1068  */
1069 _ENTRY_ TSyError EndDataWrite( CContext aContext, bool success, appCharP *newToken );
1070
1071
1072
1073 /* ---- ADAPT ITEM -------------------------------------------------------------- */
1074 /*! This function adapts aItemData
1075  *
1076  *  @param  <aContext>      The datastore context
1077  *  @param  <aItemData1>    The 1st item's data
1078  *  @param  <aItemData2>    The 2nd item's data
1079  *  @param  <aLocalVars>    The local vars
1080  *  @param  <aIdentifier>   To identify, where it is called
1081  *
1082  *  @return  error code
1083  *
1084  *  NOTE:   The memory for adapted strings must be allocated locally.
1085  *          The SyncML engine will call 'DisposeObj' later, to release again its memory.
1086  *          One or more strings can be returned unchanged as well.
1087  */
1088 _ENTRY_ TSyError AdaptItem( CContext aContext, appCharP *aItemData1,
1089                                                appCharP *aItemData2,
1090                                                appCharP *aLocalVars,
1091                                                  uInt32  aIdentifier );
1092
1093
1094 /* -- DISPOSE / CLOSE ----------------------------------------------------------- */
1095 /*! Disposes memory, which has been allocated within the datastore context.
1096  *  'DisposeObj' can occur at any time within \<aContext>.
1097  *
1098  *  @param  <aContext>  The datastore context.
1099  *  @param  <memory>    Dispose allocated memory.
1100  *
1101  *  @return  -
1102  *
1103  */
1104 _ENTRY_ void DisposeObj( CContext aContext, void* memory );
1105
1106
1107
1108 /*! This routine is called to delete a context, that was previously created with
1109  *  'CreateContext'. The DB Module must free all resources related to this context.
1110  *  No calls with \<aContext> will be done after calling this routine, so the
1111  *  assigned structure, allocated at 'CreateContext' can be released here.
1112  *
1113  *  @param  <aContext>   The datastore context.
1114  *
1115  *  @result  error code, if context could not be deleted ( e.g. not existing \<aContext> ).
1116  */
1117 _ENTRY_ TSyError DeleteContext( CContext aContext );
1118
1119
1120 #endif
1121 /* eof */