Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_lmdb_adaptor_session.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Implementation of afw_adaptor_session interface for LMDB
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw.h"
16 #include "afw_adaptor_impl.h"
17 #include "afw_adaptor_impl_index.h"
19 #include "afw_lmdb_internal.h"
20 #include "afw_lmdb_metadata.h"
21 #include "afw_lmdb_index.h"
22 
23 /* Declares and rti/inf defines for interface afw_adaptor_session */
24 #define AFW_IMPLEMENTATION_ID "lmdb"
26 
27 
28 void afw_lmdb_adaptor_session_dump_objects(
30  MDB_txn * txn,
31  const afw_utf8_t *object_type_id,
32  const afw_query_criteria_t * criteria,
33  afw_object_cb_t callback,
34  void * context,
35  const afw_pool_t *p,
36  afw_xctx_t *xctx);
37 
38 
39 
41  afw_lmdb_adaptor_t *adaptor,
42  afw_xctx_t *xctx)
43 {
45 
47  self->pub.inf = &impl_afw_adaptor_session_inf;
48  self->pub.adaptor = (afw_adaptor_t *)adaptor;
49  self->pub.p = xctx->p;
50  self->adaptor = adaptor;
51 
52  /* create our index implementation */
53  self->indexer = afw_lmdb_adaptor_impl_index_create(self,
54  adaptor, NULL, xctx);
55 
56  /* create our journal */
57  self->journal = afw_lmdb_journal_create(self, xctx);
58  self->key_value = afw_lmdb_key_value_create(self, xctx);
59 
60  /* Return session. */
61  return self;
62 }
63 
64 
65 /*
66  * Implementation of method destroy of interface afw_adaptor_session.
67  */
68 void
70  const afw_adaptor_session_t * instance,
71  afw_xctx_t *xctx)
72 {
73 }
74 
75 
76 /*
77  * Implementation of method retrieve_objects for interface
78  * afw_adaptor_session.
79  */
80 void
82  const afw_adaptor_session_t *instance,
83  const afw_adaptor_impl_request_t *impl_request,
84  const afw_utf8_t *object_type_id,
85  const afw_query_criteria_t *criteria,
86  void *context,
87  afw_object_cb_t callback,
88  const afw_object_t *adaptor_type_specific,
89  const afw_pool_t *p,
90  afw_xctx_t *xctx)
91 {
93  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
94  MDB_txn * txn;
95 
96  if (afw_lmdb_metadata_handles(object_type_id)) {
98  self, object_type_id, criteria, xctx);
99  }
100 
101  /* open the transaction */
102  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, MDB_RDONLY, false, xctx) {
103 
104  txn = AFW_LMDB_GET_TRANSACTION();
105 
106  /* if we don't have an object_type_id, we need to do a dump */
107  if (object_type_id == NULL) {
108  /* no object_type_id, or id is a meta properties, then we need to dump */
109  afw_lmdb_adaptor_session_dump_objects(self, txn, NULL, criteria,
110  callback, context, p, xctx);
111  }
112 
113  /* determine if the filter criteria contains predicates that allow us to index */
114  else if (afw_adaptor_impl_index_sargable(self->indexer,
115  object_type_id, criteria, xctx))
116  {
117  afw_adaptor_impl_index_query(self->indexer, object_type_id,
118  criteria, callback, context, p, xctx);
119  }
120 
121  else {
122  /* the search criteria cannot help us, so we need to scan the entire
123  database and filter, if necessary. We use the object_type_id to
124  index over entries for this type */
125  afw_lmdb_adaptor_session_dump_objects(self, txn, object_type_id,
126  criteria, callback, context, p, xctx);
127  }
128  }
130 }
131 
132 
133 /*
134  * Implementation of method get_object for interface afw_adaptor_session.
135  */
136 void
138  const afw_adaptor_session_t *instance,
139  const afw_adaptor_impl_request_t *impl_request,
140  const afw_utf8_t *object_type_id,
141  const afw_utf8_t *object_id,
142  void *context,
143  afw_object_cb_t callback,
144  const afw_object_t *adaptor_type_specific,
145  const afw_pool_t *p,
146  afw_xctx_t *xctx)
147 {
149  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
150  MDB_dbi dbi;
151  MDB_txn *txn;
152  const afw_object_t *object;
153 
154  /*
155  * If object_type_id is _AdaptiveObjectType_, return a generic object type for
156  * now. This may change if the lmdb adaptor starts storing object types.
157  */
158  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
160  instance->adaptor, object_id, p, xctx);
161  callback(object, context, xctx);
162  return;
163  }
164 
165  /* begin the transaction */
166  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, MDB_RDONLY, false, xctx) {
167 
168  txn = AFW_LMDB_GET_TRANSACTION();
169 
170  /* open our database */
171  dbi = afw_lmdb_internal_open_database(adaptor,
172  txn, &afw_lmdb_s_Primary, 0, p, xctx);
173 
174  /* Callback with object. */
175  callback(
176  afw_lmdb_internal_create_object_from_entry(self,
177  object_type_id, object_id, dbi, xctx),
178  context, xctx);
179  }
181 }
182 
183 
184 
185 /*
186  * Implementation of method add_object for interface afw_adaptor_session.
187  */
188 const afw_utf8_t *
190  const afw_adaptor_session_t *instance,
191  const afw_adaptor_impl_request_t *impl_request,
192  const afw_utf8_t *object_type_id,
193  const afw_utf8_t *suggested_object_id,
194  const afw_object_t *object,
195  const afw_object_t *adaptor_type_specific,
196  afw_xctx_t *xctx)
197 {
199  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
200  MDB_dbi dbi;
201  MDB_txn *txn;
202  const afw_uuid_t *uuid;
203  const afw_utf8_t *uuid_string;
204 
205  if (suggested_object_id) {
206  /* we were given an object_id, so use it */
207  uuid_string = suggested_object_id;
208  } else {
209  /* generate a UUID for this new object */
210  uuid = afw_uuid_create(xctx->p, xctx);
211  uuid_string = afw_uuid_to_utf8(uuid, xctx->p, xctx);
212  }
213 
214  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, 0, false, xctx) {
215 
216  txn = AFW_LMDB_GET_TRANSACTION();
217 
218  /* open our primary database */
219  dbi = afw_lmdb_internal_open_database(adaptor,
220  txn, &afw_lmdb_s_Primary, MDB_CREATE, xctx->p, xctx);
221 
222  /* add the object to our primary database */
223  afw_lmdb_internal_create_entry_from_object(self,
224  object_type_id, uuid_string, object, dbi, xctx);
225 
226  /* create our indexes for this object */
227  afw_adaptor_impl_index_object(self->indexer, object_type_id,
228  object, uuid_string, xctx);
229 
231  }
233 
234  return uuid_string;
235 }
236 
237 
238 
239 /*
240  * Implementation of method modify_object for interface afw_adaptor_session.
241  */
242 void
244  const afw_adaptor_session_t *instance,
245  const afw_adaptor_impl_request_t *impl_request,
246  const afw_utf8_t *object_type_id,
247  const afw_utf8_t *object_id,
248  const afw_adaptor_modify_entry_t *const *entry,
249  const afw_object_t *adaptor_type_specific,
250  afw_xctx_t *xctx)
251 {
253  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
254  const afw_object_t *object, *new_object;
255  MDB_dbi dbi;
256  MDB_txn *txn;
257 
258  if (!object_id || !object_type_id) {
259  AFW_THROW_ERROR_Z(bad_request,
260  "Missing id or object_type.", xctx);
261  }
262 
263  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, 0, false, xctx) {
264 
265  txn = AFW_LMDB_GET_TRANSACTION(),
266 
267  /* open our primary database */
268  dbi = afw_lmdb_internal_open_database(adaptor,
269  txn, &afw_lmdb_s_Primary, 0, xctx->p, xctx);
270 
271  /* load our object into memory and apply the modifications */
272  object = afw_lmdb_internal_create_object_from_entry(self,
273  object_type_id, object_id, dbi, xctx);
274 
275  /* call common routine to modify the object */
276  new_object = afw_object_create_clone(object, xctx->p, xctx);
278  entry, new_object, xctx);
279 
280  /* Write updated object */
281  afw_lmdb_internal_replace_entry_from_object(self, object_type_id,
282  object_id, new_object, dbi, xctx);
283 
284  /* Re-index object, if necessary */
285  afw_adaptor_impl_index_reindex_object(self->indexer, object_type_id,
286  object, new_object, object_id, xctx);
287 
289  }
291 }
292 
293 
294 /*
295  * Implementation of method replace_object for interface afw_adaptor_session.
296  */
297 void
299  const afw_adaptor_session_t *instance,
300  const afw_adaptor_impl_request_t *impl_request,
301  const afw_utf8_t *object_type_id,
302  const afw_utf8_t *object_id,
303  const afw_object_t *replacement_object,
304  const afw_object_t *adaptor_type_specific,
305  afw_xctx_t *xctx)
306 {
308  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
309  const afw_object_t *old_object;
310  const afw_value_t *value;
311  MDB_dbi dbi;
312  MDB_txn *txn;
313 
314  if (!object_id || !object_type_id) {
315  AFW_THROW_ERROR_Z(bad_request,
316  "Missing id or object_type.", xctx);
317  }
318 
319  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, 0, false, xctx) {
320 
321  txn = AFW_LMDB_GET_TRANSACTION();
322 
323  /* open our primary database */
324  dbi = afw_lmdb_internal_open_database(adaptor,
325  txn, &afw_lmdb_s_Primary, 0, xctx->p, xctx);
326 
327  /* get the old object */
328  value = afw_lmdb_internal_create_value_from_entry(self,
329  object_type_id, object_id, dbi, xctx);
330 
331  if (value && !afw_value_is_object(value)) {
332  AFW_THROW_ERROR_Z(bad_request,
333  "Not a valid object.", xctx);
334  }
335 
336  old_object = afw_value_as_object(value, xctx);
337 
338  /* Write updated object */
339  afw_lmdb_internal_replace_entry_from_object(self,
340  object_type_id, object_id, replacement_object, dbi, xctx);
341 
342  /* Re-index object, if necessary */
343  afw_adaptor_impl_index_reindex_object(self->indexer, object_type_id,
344  old_object, replacement_object, object_id, xctx);
345 
347  }
349 }
350 
351 
352 /*
353  * Implementation of method delete_object for interface afw_adaptor_session.
354  */
355 void
357  const afw_adaptor_session_t *instance,
358  const afw_adaptor_impl_request_t *impl_request,
359  const afw_utf8_t *object_type_id,
360  const afw_utf8_t *object_id,
361  const afw_object_t *adaptor_type_specific,
362  afw_xctx_t *xctx)
363 {
365  afw_lmdb_adaptor_t *adaptor = (afw_lmdb_adaptor_t *)self->adaptor;
366  const afw_uuid_t *uuid;
367  const afw_object_t *object;
368  afw_memory_t raw_key;
369  MDB_dbi dbi;
370  MDB_txn *txn;
371  int rc;
372 
373  uuid = afw_uuid_from_utf8(object_id, xctx->p, xctx);
374 
375  /* open the transaction */
376  AFW_LMDB_BEGIN_TRANSACTION(adaptor, self, 0, false, xctx) {
377 
378  txn = AFW_LMDB_GET_TRANSACTION();
379 
380  dbi = afw_lmdb_internal_open_database(adaptor,
381  txn, &afw_lmdb_s_Primary, 0, xctx->p, xctx);
382 
383  object = afw_lmdb_internal_create_object_from_entry(self,
384  object_type_id, object_id, dbi, xctx);
385  if (!object) {
386  AFW_THROW_ERROR_FZ(not_found, xctx,
387  "%" AFW_UTF8_FMT " cannot be found.",
388  AFW_UTF8_FMT_ARG(object_id));
389  }
390 
391  /* remove the actual entry from the primary database */
392  afw_lmdb_internal_set_key(&raw_key, object_type_id, uuid, xctx->p, xctx);
393 
394  rc = afw_lmdb_internal_delete_entry(
395  AFW_LMDB_GET_TRANSACTION(),
396  dbi, &raw_key, NULL, xctx);
397  if (rc) {
398  AFW_THROW_ERROR_RV_Z(general, lmdb, rc,
399  "Error deleting value from primary database.", xctx);
400  }
401 
402  AFW_TRY {
403  /* remove any indexes that still exist */
404  afw_adaptor_impl_index_unindex_object(self->indexer,
405  object_type_id, object, object_id, xctx);
406  }
407  AFW_CATCH(not_found) {
409  break;
410  }
414  }
415  AFW_ENDTRY;
416 
418  }
420 }
421 
422 
423 
424 /*
425  * Implementation of method begin_transaction of interface afw_adaptor_session.
426  */
429  const afw_adaptor_session_t * instance,
430  afw_xctx_t *xctx)
431 {
433  afw_lmdb_transaction_t *transaction;
434 
435  /* create the session transaction at the time it's requested */
436  transaction = afw_lmdb_transaction_create(self, xctx);
437 
438  return (afw_adaptor_transaction_t *)transaction;
439 }
440 
441 
442 /*
443  * This routine does a sequential scan of the database, for
444  * any and all object types, if specified. When filter
445  * criteria matches, the object is returned.
446  */
447 void afw_lmdb_adaptor_session_dump_objects(
448  afw_lmdb_adaptor_session_t * session,
449  MDB_txn * txn,
450  const afw_utf8_t *object_type_id,
451  const afw_query_criteria_t * criteria,
452  afw_object_cb_t callback,
453  void * context,
454  const afw_pool_t *p,
455  afw_xctx_t *xctx)
456 {
457  const afw_object_t *object;
458  afw_utf8_t object_type;
459  const afw_pool_t *obj_p;
460  const afw_utf8_t *object_id;
461  afw_memory_t raw, rawKey;
462  afw_uuid_t uuid;
463  MDB_cursor *cursor;
464  MDB_val key, data;
465  MDB_dbi dbi;
466  int rc;
467  afw_boolean_t abandon;
468 
469  /* Open the database where our primary objects are stored */
470  dbi = afw_lmdb_internal_open_database(session->adaptor, txn,
471  &afw_lmdb_s_Primary, 0, p, xctx);
472 
473  /* Open a cursor against the object_type index database */
474  cursor = afw_lmdb_internal_open_cursor(session, dbi, xctx);
475  if (cursor == NULL) {
476  AFW_THROW_ERROR_Z(general,
477  "Error opening primary database cursor.", xctx);
478  }
479 
480  /*
481  * If we have an object_type_id, then we can take advantage
482  * of LMDB's b-tree to start at. Otherwise, start from the
483  * very beginning.
484  */
485  memset(&data, 0, sizeof(MDB_val));
486  if (object_type_id) {
487  key.mv_data = (void*)object_type_id->s;
488  key.mv_size = object_type_id->len;
489  rc = mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE);
490  } else {
491  /* else start at the very beginning */
492  memset(&key, 0, sizeof(MDB_val));
493  rc = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
494  }
495 
496  if (rc == MDB_NOTFOUND) {
497  /* no entries */
498  mdb_cursor_close(cursor);
499  callback(NULL, context, xctx);
500  return;
501  } else if (rc) {
502  mdb_cursor_close(cursor);
503  AFW_THROW_ERROR_RV_Z(general, lmdb_internal, rc,
504  "Error getting cursor for primary database.", xctx);
505  }
506 
507  /* loop until we hit the end of our cursor */
508  do {
509  raw.ptr = data.mv_data;
510  raw.size = data.mv_size;
511  rawKey.ptr = key.mv_data;
512  rawKey.size = key.mv_size;
513 
514 
515  /* create temporary pool for object memory */
516  obj_p = afw_pool_create(p, xctx);
517 
518  afw_lmdb_internal_get_key(&rawKey, &object_type, &uuid);
519  if (object_type.len == 0) {
520  /* skip objects that have no type */
521  afw_pool_release(obj_p, xctx);
522  continue;
523  }
524 
525  /* convert our uuid back into a utf8 string */
526  object_id = afw_uuid_to_utf8(&uuid, obj_p, xctx);
527 
529  session->adaptor->ubjson, &raw, NULL, &session->adaptor->pub.adaptor_id,
530  &object_type, object_id, true, obj_p, xctx);
531 
532  /* if object_type_id was specified, check it */
533  if (object_type_id) {
534  if (!afw_utf8_equal(object_type_id, &object_type)) {
535  /* Now we're onto the next object_type, so just quit */
536  mdb_cursor_close(cursor);
537  afw_object_release(object, xctx);
538  callback(NULL, context, xctx);
539  return;
540  }
541  }
542 
543  abandon = false;
544  if (afw_query_criteria_test_object(object, criteria,
545  p, xctx))
546  {
547  afw_object_meta_set_ids(object, &session->adaptor->pub.adaptor_id,
548  &object_type, object_id, xctx);
549 
550  /* we have an entry, so callback to process it */
551  abandon = callback(object, context, xctx);
552  }
553 
554  } while (!abandon && mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0);
555 
556  mdb_cursor_close(cursor);
557  callback(NULL, context, xctx);
558 }
559 
560 
561 /*
562  * Implementation of method get_journal of interface afw_adaptor_session.
563  */
564 const afw_adaptor_journal_t *
565 impl_afw_adaptor_session_get_journal_interface(
566  const afw_adaptor_session_t * instance,
567  afw_xctx_t *xctx)
568 {
570 
571  return (afw_adaptor_journal_t *)self->journal;
572 }
573 
574 
575 
576 /*
577  * Implementation of method get_key_value_interface of interface
578  * afw_adaptor_session.
579  */
582  const afw_adaptor_session_t * instance,
583  afw_xctx_t *xctx)
584 {
586 
587  return (afw_adaptor_key_value_t *)self->key_value;
588 }
589 
590 
591 /*
592  * Implementation of method get_index_interface of interface afw_adaptor_session.
593  */
596  const afw_adaptor_session_t * instance,
597  afw_xctx_t *xctx)
598 {
600 
601  return self->indexer;
602 }
603 
604 
605 
606 /*
607  * Implementation of method get_object_type_cache_interface for interface
608  * afw_adaptor_session.
609  */
611 impl_afw_adaptor_session_get_object_type_cache_interface(
612  const afw_adaptor_session_t * instance,
613  afw_xctx_t *xctx)
614 {
615  /* There is on adaptor cache. */
616  return NULL;
617 }
Adaptive Framework Core API.
Helpers for adaptor implementation development.
Helpers for afw_adaptor implementation index development.
Interface afw_interface implementation declares.
afw_lmdb_adaptor_session_t * afw_lmdb_adaptor_session_create(afw_lmdb_adaptor_t *adaptor, afw_xctx_t *xctx)
Internal create a LMDB adaptor session.
Adaptive Framework register generated (afw_lmdb) header.
Helpers for afw_adaptor implementation index development.
Adaptive Framework LMDB Adaptor Internal Header.
afw_lmdb_transaction_t * afw_lmdb_transaction_create(afw_lmdb_adaptor_session_t *session, afw_xctx_t *xctx)
Internal create a LMDB adaptor transaction.
#define AFW_LMDB_END_TRANSACTION()
End an LMDB transaction.
#define AFW_LMDB_BEGIN_TRANSACTION(adaptor, session, flags, exclusive, xctx)
Begin an LMDB transaction.
afw_lmdb_journal_t * afw_lmdb_journal_create(afw_lmdb_adaptor_session_t *session, afw_xctx_t *xctx)
Internal create a LMDB adaptor journal.
afw_lmdb_key_value_t * afw_lmdb_key_value_create(afw_lmdb_adaptor_session_t *session, afw_xctx_t *xctx)
Internal create a LMDB adaptor key/value.
#define AFW_LMDB_COMMIT_TRANSACTION()
Commit a transaction.
Adaptive Framework LMDB Adaptor Metadata handler.
const afw_list_t * afw_lmdb_metadata_retrieve_objects(afw_lmdb_adaptor_session_t *self, const afw_utf8_t *object_type_id, const afw_query_criteria_t *criteria, afw_xctx_t *xctx)
Called by afw_lmdb_adaptor_session() to retrieve metadata objects.
afw_adaptor_impl_generic_object_type_object_get(const afw_adaptor_t *adaptor, const afw_utf8_t *object_type_id, const afw_pool_t *p, afw_xctx_t *xctx)
Create a generic object type object.
void impl_afw_adaptor_session_modify_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_adaptor_modify_entry_t *const *entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_replace_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *replacement_object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_delete_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_retrieve_objects(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_query_criteria_t *criteria, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_transaction_t * impl_afw_adaptor_session_begin_transaction(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
void impl_afw_adaptor_session_destroy(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_adaptor_impl_index_t * impl_afw_adaptor_session_get_index_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_utf8_t * impl_afw_adaptor_session_add_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *suggested_object_id, const afw_object_t *object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_get_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_key_value_t * impl_afw_adaptor_session_get_key_value_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
afw_adaptor_modify_entries_apply_to_unnormalized_object(const afw_adaptor_modify_entry_t *const *entries, const afw_object_t *object, afw_xctx_t *xctx)
Apply modify entries to an unnormalized object.
#define afw_value_is_object(A_VALUE)
Macro to determine if value is evaluated object.
afw_value_as_object(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type object.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
afw_boolean_t(* afw_object_cb_t)(const afw_object_t *object, void *context, afw_xctx_t *xctx)
Typedef for afw_adaptor_session_object callback.
Definition: afw_common.h:1176
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
#define afw_content_type_raw_to_object(instance, raw, source_location, adaptor_id, object_type_id, object_id, cede_p, p, xctx)
Call method raw_to_object of interface afw_content_type.
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
#define AFW_THROW_ERROR_RV_Z(code, rv_source_id, rv, message_z, xctx)
Macro used to set error and rv in xctx and throw it.
Definition: afw_error.h:301
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#define AFW_MARK_UNHANDLED
Use in an AFW_CATCH or AFW_CATCH_UNHANDLED block to mark error as unhandled and break.
Definition: afw_error.h:750
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_CATCH(__CODE_)
Catch a particular error that occurs in a AFW_TRY block.
Definition: afw_error.h:668
#define afw_object_release(instance, xctx)
Call method release of interface afw_object.
afw_object_meta_set_ids(const afw_object_t *instance, const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, afw_xctx_t *xctx)
Set object's ids.
afw_object_create_clone(const afw_object_t *object, const afw_pool_t *p, afw_xctx_t *xctx)
Clone an object to a specified pool.
Definition: afw_memory.c:138
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_query_criteria_test_object(const afw_object_t *obj, const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Test object against query criteria.
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_uuid_from_utf8(const afw_utf8_t *s, const afw_pool_t *p, afw_xctx_t *xctx)
Convert standard format UUID utf-8 string to uuid.
Definition: afw_uuid.c:117
afw_uuid_create(const afw_pool_t *p, afw_xctx_t *xctx)
Create a UUID.
Definition: afw_uuid.c:30
afw_uuid_to_utf8(const afw_uuid_t *uuid, const afw_pool_t *p, afw_xctx_t *xctx)
Convert uuid to a standard format UUID utf-8 string.
Definition: afw_uuid.c:79
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Definition: afw_xctx.h:199
Interface afw_adaptor_impl_index public struct.
Internal request info used by afw_adaptor_impl*() functions.
Interface afw_adaptor_journal public struct.
Interface afw_adaptor_key_value public struct.
Adaptor modify entry.
Interface afw_adaptor_object_type_cache public struct.
Interface afw_adaptor public struct.
Interface afw_adaptor_session public struct.
Interface afw_adaptor_transaction public struct.
Struct for memory pointer and size.
Definition: afw_common.h:505
Interface afw_object public struct.
Interface afw_pool public struct.
Parsed query criteria.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
Interface afw_xctx public struct.