Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_ldap_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 LDAP
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw.h"
16 #include "afw_ldap_internal.h"
17 #include "afw_ldap_metadata.h"
18 #include "afw_adaptor_impl.h"
19 
20 /* Declares and rti/inf defines for interface afw_adaptor_session */
21 #define AFW_IMPLEMENTATION_ID "ldap"
23 
24 
28  afw_xctx_t *xctx)
29 {
31 
33  self->pub.inf = &impl_afw_adaptor_session_inf;
34  self->pub.adaptor = (afw_adaptor_t *)adaptor;
35  self->pub.p = xctx->p;
36  self->adaptor = adaptor;
37 
38  /* Get active connection to LDAP. */
39  afw_ldap_internal_session_begin(self, xctx);
40 
41  /* Return session. */
42  return self;
43 }
44 
45 
46 
47 /*
48  * Implementation of method destroy of interface afw_adaptor_session.
49  */
50 void
52  const afw_adaptor_session_t * instance,
53  afw_xctx_t *xctx)
54 {
56 
57  /* Close ldap connection. */
58  afw_ldap_internal_session_end(self);
59 }
60 
61 /*
62  * Implementation of method retrieve_objects for interface
63  * afw_adaptor_session.
64  */
65 void
67  const afw_adaptor_session_t *instance,
68  const afw_adaptor_impl_request_t *impl_request,
69  const afw_utf8_t *object_type_id,
70  const afw_query_criteria_t *criteria,
71  void *context,
72  afw_object_cb_t callback,
73  const afw_object_t *adaptor_type_specific,
74  const afw_pool_t *p,
75  afw_xctx_t *xctx)
76 {
79  afw_ldap_internal_adaptor_t * adaptor =
80  (afw_ldap_internal_adaptor_t *)instance->adaptor;
81  LDAPMessage *res;
82  LDAPMessage *e;
83  const afw_utf8_t *filter;
84  const afw_utf8_t *filter_class;
85  const char *filter_z;
86  const afw_object_t *o;
87  const afw_utf8_t *object_id;
88  const afw_utf8_t *s;
89  char *base_z;
90  int msgid;
91  int rv;
92  int err;
93  afw_boolean_t abandon;
94 
95  /* If this is one of the synthetic object types, call metadata function. */
96  if (afw_ldap_metadata_handles(object_type_id))
97  {
99  self, object_type_id, criteria, context, callback, xctx);
100  return;
101  }
102 
103  /* Determine base_z using optional type specific parameter. */
104  base_z = "";
105  if (adaptor_type_specific) {
106  s = afw_object_old_get_property_as_string(adaptor_type_specific,
107  &afw_ldap_s_base, xctx);
108  if (s) {
109  base_z = (char *)afw_utf8_to_utf8_z(s, p, xctx);
110  }
111  }
112 
113  /* Determine filter_z. */
114  if (object_type_id) {
115  /* Check to see if the user wants inherited object types to be returned */
116  if (AFW_OBJECT_OPTION_IS(impl_request->options, includeDescendentObjectTypes)) {
117  filter_class = afw_utf8_printf(p, xctx,
118  "objectclass=%" AFW_UTF8_FMT,
119  AFW_UTF8_FMT_ARG(object_type_id));
120  } else {
121  filter_class = afw_utf8_printf(p, xctx,
122  "structuralobjectclass=%" AFW_UTF8_FMT,
123  AFW_UTF8_FMT_ARG(object_type_id));
124  }
125  } else {
126  filter_class = afw_utf8_printf(p, xctx, "objectclass=*");
127  }
128  if (criteria && criteria->filter) {
129  filter = afw_ldap_internal_expression_from_query_criteria(
130  self, criteria->filter, xctx);
131  filter = afw_utf8_printf(p, xctx,
132  "(&(%" AFW_UTF8_FMT ")(%" AFW_UTF8_FMT "))",
133  AFW_UTF8_FMT_ARG(filter_class), AFW_UTF8_FMT_ARG(filter));
134  } else {
135  filter = filter_class;
136  }
137  filter_z = afw_utf8_z_create(filter->s, filter->len, p, xctx);
138 
139  /* Start search. */
140  msgid = ldap_search(self->ld, base_z, LDAP_SCOPE_SUBTREE,
141  (char *)filter_z, afw_ldap_internal_allattrs, 0);
142  if (msgid < 0) {
143  ldap_get_option(self->ld, LDAP_OPT_ERROR_NUMBER, &err);
144  AFW_THROW_ERROR_RV_Z(general, ldap, err,
145  "ldap_search() failed.", xctx);
146  }
147 
148  /* Process each result. */
149  res = NULL;
150  abandon = false;
151  AFW_TRY {
152  for (;;) {
153  rv = ldap_result(self->ld, msgid, 0, &adaptor->timeout, &res);
154  if (rv < 0) {
155  ldap_get_option(self->ld, LDAP_OPT_ERROR_NUMBER, &err);
156  AFW_THROW_ERROR_RV_Z(general, ldap, err,
157  "ldap_result() failed", xctx);
158  }
159  if (rv == 0) {
160  AFW_THROW_ERROR_Z(general,
161  "ldap_result() timeout.", xctx);
162  }
163  if (rv == LDAP_RES_SEARCH_RESULT) {
164  break;
165  }
166  if (rv != LDAP_RES_SEARCH_ENTRY) {
167  AFW_THROW_ERROR_RV_Z(general, ldap, rv,
168  "ldap_result() unexpected return value", xctx);
169  }
170 
171  /* Get each entry and callback with its adaptive object representation. */
172  e = ldap_first_entry(self->ld, res);
173  while (e) {
174  object_id = afw_ldap_internal_get_object_id(self, e, true, xctx);
175  o = afw_ldap_internal_create_object_from_entry(self, object_type_id,
176  object_id, e, xctx->p, xctx);
177  /* Call callback and abandon request if requested. */
178  abandon = callback(o, context, xctx);
179  if (abandon) {
180  ldap_abandon(self->ld, msgid);
181  break;
182  }
183  e = ldap_next_entry(self->ld, e);
184  }
185 
186  /* Free res. */
187  ldap_msgfree(res);
188  res = NULL;
189 
190  /* Break if asked to abandon. */
191  if (abandon) {
192  break;
193  }
194  }
195  }
196  AFW_FINALLY{
197  /* Make sure last message is freed. */
198  if (res) {
199  ldap_msgfree(res);
200  res = NULL;
201  }
202  }
203  AFW_ENDTRY;
204 
205  /* Callback one last time with NULL object pointer. */
206  callback(NULL, context, xctx);
207 }
208 
209 
210 
211 /*
212  * Implementation of method get_object for interface afw_adaptor_session.
213  */
214 void
216  const afw_adaptor_session_t *instance,
217  const afw_adaptor_impl_request_t *impl_request,
218  const afw_utf8_t *object_type_id,
219  const afw_utf8_t *object_id,
220  void *context,
221  afw_object_cb_t callback,
222  const afw_object_t *adaptor_type_specific,
223  const afw_pool_t *p,
224  afw_xctx_t *xctx)
225 {
227  int rv;
228  LDAPMessage *res;
229  LDAPMessage *e;
230  const afw_utf8_z_t *dn_z;
231  const afw_utf8_z_t *filter_z;
232  const afw_object_t *obj;
233  int ldap_scope;
234  int count;
235 
238  /* If this is one of the synthetic object types, call metadata function. */
239  if (afw_ldap_metadata_handles(object_type_id))
240  {
242  self, object_type_id, object_id, context, callback, xctx);
243  return;
244  }
245 
246  /* Make null terminated string from object_id. */
247  dn_z = (char *)afw_utf8_to_utf8_z(object_id, p, xctx);
248 
249  /* Read entry. */
250  res = NULL;
251  ldap_scope = LDAP_SCOPE_BASE;
252  filter_z = apr_psprintf(afw_pool_get_apr_pool(xctx->p),
253  "(structuralobjectclass=%" AFW_UTF8_FMT ")",
254  AFW_UTF8_FMT_ARG(object_type_id));
255  rv = ldap_search_s(self->ld, (char *)dn_z, ldap_scope, (char *)filter_z,
256  afw_ldap_internal_allattrs, 0, &res);
257  if (res) {
258  afw_pool_register_cleanup_before(xctx->p, res, NULL,
259  afw_ldap_internal_cleanup_ldap_msgfree, xctx);
260  }
261  if (rv != LDAP_SUCCESS) {
262  AFW_THROW_ERROR_RV_Z(general, ldap, rv, "ldap_search_s() failed.",
263  xctx);
264  }
265 
266  /* Make sure exactly one entry is returned. */
267  count = ldap_count_entries(self->ld, res);
268  if (count == 0) {
269  AFW_THROW_ERROR_Z(not_found, "Not found", xctx);
270  }
271  if (count != 1) {
272  AFW_THROW_ERROR_FZ(general, xctx,
273  "Expecting ldap_search_s() to return exactly 1 entry but "
274  "%d returned",
275  count);
276  }
277 
278  /* Get entry and return it as an adaptive object. */
279  e = ldap_first_entry(self->ld, res);
280  if (!e) {
281  AFW_THROW_ERROR_Z(general,
282  "ldap_first_entry() failed.", xctx);
283  }
284 
285  /* Callback with object. */
286  obj = afw_ldap_internal_create_object_from_entry(self, object_type_id,
287  object_id, e, xctx->p, xctx);
288  callback(obj, context, xctx);
289 }
290 
291 
292 
293 /*
294  * Implementation of method add_object for interface afw_adaptor_session.
295  */
296 const afw_utf8_t *
298  const afw_adaptor_session_t *instance,
299  const afw_adaptor_impl_request_t *impl_request,
300  const afw_utf8_t *object_type_id,
301  const afw_utf8_t *suggested_object_id,
302  const afw_object_t *object,
303  const afw_object_t *adaptor_type_specific,
304  afw_xctx_t *xctx)
305 {
308  afw_ldap_metadata_t *metadata = self->adaptor->metadata;
309  const afw_pool_t *p;
310  afw_ldap_object_type_attribute_t *first_attribute;
312  apr_array_header_t *mods;
313  const afw_value_t *value;
314  const afw_utf8_t *property_name;
315  const afw_iterator_t *iterator;
316  struct berval **bvals;
317  LDAPMod *mod;
318  char *dn_z;
319  int rv;
320 
321  /* This method is not allowed for synthetic object types. */
322  if (afw_ldap_metadata_handles(object_type_id))
323  {
324  AFW_THROW_ERROR_Z(read_only, "Not allowed", xctx);
325  }
326 
327  /* This adaptor required object_id to be specified */
328  if (suggested_object_id == NULL) {
329  AFW_THROW_ERROR_Z(bad_request,
330  "An objectId is required for LDAP operations.",
331  xctx);
332  }
333 
334  /* Get first attribute for object type. */
335  first_attribute = apr_hash_get(metadata->object_type_attributes,
336  object_type_id->s, object_type_id->len);
337  if (!first_attribute) {
338  AFW_THROW_ERROR_FZ(not_found, xctx,
339  "Object type %" AFW_UTF8_FMT " not found",
340  AFW_UTF8_FMT_ARG(object_type_id));
341  }
342 
343  /* Create mods array. */
344  p = afw_pool_create(instance->p, xctx);
345  mods = apr_array_make(afw_pool_get_apr_pool(p), 10, sizeof(LDAPMod *));
346 
347  /* Add objectClass. */
348  mod = afw_pool_calloc_type(p, LDAPMod, xctx);
349  mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
350  mod->mod_type = "objectClass";
351  bvals = afw_pool_calloc(p, sizeof(struct berval *) * 2, xctx);
352  *bvals = afw_pool_calloc_type(p, struct berval, xctx);
353  (*bvals)->bv_len = (ber_len_t)object_type_id->len;
354  (*bvals)->bv_val = (char *)object_type_id->s;
355  mod->mod_vals.modv_bvals = bvals;
356  APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
357 
358  /* Loop adding properties. */
359  iterator = NULL;
360  while ((value = afw_object_get_next_property(object,
361  &iterator, &property_name, xctx)))
362  {
364  first_attribute, property_name);
365  if (!attribute || attribute->attribute_type->never_allow_write) {
366  continue;
367  }
368 
369  bvals = afw_ldap_metadata_value_to_bv(self, property_name, value,
370  xctx);
371  if (bvals) {
372  mod = afw_pool_calloc_type(p, LDAPMod, xctx);
373  mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
374  mod->mod_type = apr_pstrndup(afw_pool_get_apr_pool(p),
375  property_name->s, property_name->len);
376  mod->mod_vals.modv_bvals = bvals;
377  APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
378  }
379  }
380 
381  /* Mark end of mods with NULL. */
382  APR_ARRAY_PUSH(mods, LDAPMod *) = NULL;
383 
384  /* Make null terminated dn. */
385  dn_z = (char *)afw_utf8_to_utf8_z(suggested_object_id, p, xctx);
386 
387  /* Add object. */
388  rv = ldap_add_s(self->ld, dn_z, (LDAPMod * *)mods->elts);
389  if (rv != LDAP_SUCCESS) {
390  AFW_THROW_ERROR_RV_Z(general, ldap, rv, "ldap_add_s() failed.",
391  xctx);
392  }
393 
394  /* Release temporary pool. */
395  afw_pool_release(p, xctx);
396 
397  /* Return object id. */
398  return suggested_object_id;
399 }
400 
401 
402 
403 /*
404  * Implementation of method modify_object for interface afw_adaptor_session.
405  */
406 void
408  const afw_adaptor_session_t *instance,
409  const afw_adaptor_impl_request_t *impl_request,
410  const afw_utf8_t *object_type_id,
411  const afw_utf8_t *object_id,
412  const afw_adaptor_modify_entry_t *const *entry,
413  const afw_object_t *adaptor_type_specific,
414  afw_xctx_t *xctx)
415 {
418  afw_ldap_metadata_t *metadata = self->adaptor->metadata;
419  const afw_pool_t *p;
420  afw_ldap_object_type_attribute_t *first_attribute;
422  apr_array_header_t *mods;
423  const afw_utf8_t *property_name;
424  const afw_adaptor_modify_entry_t * const * e;
425  LDAPMod *mod;
426  char *dn_z;
427  int rv;
428 
429  /* This method is not allowed for synthetic object types. */
430  if (afw_ldap_metadata_handles(object_type_id))
431  {
432  AFW_THROW_ERROR_Z(read_only, "Not allowed", xctx);
433  }
434 
435  /* Get first attribute for object type. */
436  first_attribute = apr_hash_get(metadata->object_type_attributes,
437  object_type_id->s, object_type_id->len);
438  if (!first_attribute) {
439  AFW_THROW_ERROR_FZ(not_found, xctx,
440  "Object type %" AFW_UTF8_FMT " not found",
441  AFW_UTF8_FMT_ARG(object_type_id));
442  }
443 
444  /* Create mods. */
445  p = afw_pool_create(instance->p, xctx);
446  mods = apr_array_make(afw_pool_get_apr_pool(p), 10, sizeof(LDAPMod *));
447  afw_memory_clear(&mod);
448  for (e = entry; *e; e++) {
449 
450  /* Only entity properties allowed. */
451  if (!(*e)->first_property_name_entry ||
452  (*e)->first_property_name_entry->next)
453  {
454  AFW_THROW_ERROR_Z(general,
455  "LDAP adaptor only allows entity properties to be modified",
456  xctx);
457  }
458  property_name = &(*e)->first_property_name_entry->property_name;
459 
460  /* Get property type for property and make sure it can be written. */
462  first_attribute, property_name);
463  if (!attribute || attribute->attribute_type->never_allow_write)
464  {
465  AFW_THROW_ERROR_FZ(read_only, xctx,
466  "Property %" AFW_UTF8_FMT " can not be modified",
467  AFW_UTF8_FMT_ARG(property_name)
468  );
469  }
470 
471  /* Create and initialize mod. */
472  mod = afw_pool_calloc_type(p, LDAPMod, xctx);
473  mod->mod_type = apr_pstrndup(afw_pool_get_apr_pool(p),
474  property_name->s, property_name->len);
475  mod->mod_type = apr_pstrndup(afw_pool_get_apr_pool(p),
476  (*e)->first_property_name_entry->property_name.s,
477  (*e)->first_property_name_entry->property_name.len);
478 
479  switch ((*e)->type) {
480 
481  case afw_adaptor_modify_entry_type_add_value:
482  mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
483  mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(self,
484  property_name, (*e)->value, xctx);
485  break;
486 
487  case afw_adaptor_modify_entry_type_remove_property:
488  mod->mod_op = LDAP_MOD_DELETE;
489  break;
490 
491  case afw_adaptor_modify_entry_type_remove_value:
492  mod->mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
493  mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(self,
494  property_name, (*e)->value, xctx);
495  break;
496 
497  case afw_adaptor_modify_entry_type_set_property:
498  mod->mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
499  mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(self,
500  property_name, (*e)->value, xctx);
501  break;
502 
503  default:
504  AFW_THROW_ERROR_FZ(general, xctx,
505  "Unsupported entry type %d", (*e)->type);
506  }
507 
508  APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
509  }
510 
511  /* Mark end of mods with NULL. */
512  APR_ARRAY_PUSH(mods, LDAPMod *) = NULL;
513 
514  /* Make null terminated dn. */
515  dn_z = (char *)afw_utf8_to_utf8_z(object_id, p, xctx);
516 
517  /* Modify object. */
518  rv = ldap_modify_s(self->ld, dn_z, (LDAPMod * *)mods->elts);
519  if (rv != LDAP_SUCCESS) {
520  AFW_THROW_ERROR_RV_Z(general, ldap, rv, "ldap_modify_s() failed.",
521  xctx);
522  }
523 
524  /* Release temporary pool. */
525  afw_pool_release(p, xctx);
526 }
527 
528 
529 
530 /*
531  * Implementation of method replace_object for interface afw_adaptor_session.
532  */
533 void
535  const afw_adaptor_session_t *instance,
536  const afw_adaptor_impl_request_t *impl_request,
537  const afw_utf8_t *object_type_id,
538  const afw_utf8_t *object_id,
539  const afw_object_t *replacement_object,
540  const afw_object_t *adaptor_type_specific,
541  afw_xctx_t *xctx)
542 {
543  /*
544  * Replace doesn't make sense for LDAP because of internally maintained
545  * attributes.
546  */
547  AFW_THROW_ERROR_Z(general,
548  "LDAP adaptor does not support replace_object()",
549  xctx);
550 }
551 
552 
553 
554 /*
555  * Implementation of method delete_object for interface afw_adaptor_session.
556  */
557 void
559  const afw_adaptor_session_t *instance,
560  const afw_adaptor_impl_request_t *impl_request,
561  const afw_utf8_t *object_type_id,
562  const afw_utf8_t *object_id,
563  const afw_object_t *adaptor_type_specific,
564  afw_xctx_t *xctx)
565 {
568  char *dn_z;
569  int rv;
570 
571  /* This method is not allowed for synthetic object types. */
572  if (afw_ldap_metadata_handles(object_type_id))
573  {
574  AFW_THROW_ERROR_Z(read_only, "Not allowed.", xctx);
575  }
576 
577  /* Make null terminated dn. */
578  dn_z = (char *)afw_utf8_to_utf8_z(object_id, xctx->p, xctx);
579 
580  /* Delete object. */
581  rv = ldap_delete_s(self->ld, dn_z);
582  if (rv != LDAP_SUCCESS) {
583  AFW_THROW_ERROR_RV_Z(general, ldap, rv, "ldap_delete_s() failed.",
584  xctx);
585  }
586 }
587 
588 
589 
590 /*
591  * Implementation of method begin_transaction of interface afw_adaptor_session.
592  */
595  const afw_adaptor_session_t * instance,
596  afw_xctx_t *xctx)
597 {
598  /* LDAP does not support transactions. */
599  return NULL;
600 }
601 
602 
603 
604 /*
605  * Implementation of method get_journal of interface afw_adaptor_session.
606  */
607 const afw_adaptor_journal_t *
608 impl_afw_adaptor_session_get_journal_interface(
609  const afw_adaptor_session_t * instance,
610  afw_xctx_t *xctx)
611 {
612  /* Event journal is not supported by this adaptor. */
613  return NULL;
614 }
615 
616 
617 
618 /*
619  * Implementation of method get_key_value_interface of interface
620  * afw_adaptor_session.
621  */
624  const afw_adaptor_session_t * instance,
625  afw_xctx_t *xctx)
626 {
627  /* Key value interface is not supported by this adaptor. */
628  return NULL;
629 }
630 
631 /*
632  * Implementation of method get_index_interface of interface afw_adaptor_session.
633  */
636  const afw_adaptor_session_t * instance,
637  afw_xctx_t *xctx)
638 {
639  /* Index interface is not supported by this adaptor. */
640  return NULL;
641 }
642 
643 
644 /*
645  * Implementation of method get_object_type_cache_interface for interface
646  * afw_adaptor_session.
647  */
649 impl_afw_adaptor_session_get_object_type_cache_interface(
650  const afw_adaptor_session_t * instance,
651  afw_xctx_t *xctx)
652 {
655 
657  &self->object_type_cache,
659  instance, true, xctx);
660 
661  return &self->object_type_cache;
662 }
Adaptive Framework Core API.
Helpers for adaptor implementation development.
Interface afw_interface implementation declares.
afw_ldap_internal_adaptor_session_t * afw_ldap_internal_adaptor_session_create(afw_ldap_internal_adaptor_t *adaptor, afw_xctx_t *xctx)
Internal create an LDAP adaptor session.
Adaptive Framework LDAP Internal Header
void afw_ldap_metadata_retrieve_objects(afw_ldap_internal_adaptor_session_t *self, const afw_utf8_t *object_type_id, const afw_query_criteria_t *criteria, void *context, afw_object_cb_t callback, afw_xctx_t *xctx)
Called by afw_ldap_adaptor_session() to retrieve metadata objects.
void afw_ldap_metadata_get_object(afw_ldap_internal_adaptor_session_t *self, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, void *context, afw_object_cb_t callback, afw_xctx_t *xctx)
Called by afw_ldap_adaptor_session() to get a metadata object.
afw_ldap_object_type_attribute_t * afw_ldap_metadata_get_object_type_attribute(afw_ldap_object_type_attribute_t *first, const afw_utf8_t *name)
Return afw_ldap_object_type_attribute_t * for name.
Adaptive Framework LDAP Metadata Header.
afw_adaptor_impl_object_type_cache_initialize(afw_adaptor_object_type_cache_t *object_type_cache, const afw_adaptor_object_type_cache_inf_t *inf, const afw_adaptor_session_t *session, afw_boolean_t all_object_types_immutable, afw_xctx_t *xctx)
Initialize object type cache instance.
afw_adaptor_impl_object_type_cache_inf
inf for an implementation of afw_adaptor_object_type_cache.
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)
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
#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
struct afw_iterator_s afw_iterator_t
_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
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
Definition: afw_common.h:523
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#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_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_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
#define AFW_OBJECT_OPTION_IS(_options, _option)
Test mask.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_register_cleanup_before(instance, data, data2, cleanup, xctx)
Call method register_cleanup_before of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_utf8_z_create(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Create a NFC Normalized zero terminated UTF-8 string in specified pool.
Definition: afw_utf8.c:366
const afw_utf8_z_t * afw_utf8_to_utf8_z(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Convert utf8 to utf8_z in specified pool.
Definition: afw_utf8.h:529
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
Definition: afw_utf8.c:459
#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.
const afw_object_options_t * options
Object options.
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.
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.