Can cdb_get_values support elements with multiple possible types?

215 views
Skip to first unread message

Dennis McCracken

unread,
Aug 14, 2013, 2:16:09 PM8/14/13
to confd-us...@googlegroups.com
We have an odd element type which can be returned as C_INT or C_BUF.  In the case of C_BUF the string would be set to "unlimited".  I'd like to use cdb_get_values to pull all elements from the container in one RPC.  Is this possible?

-Dennis-

Jim Boucher

unread,
Aug 15, 2013, 3:31:23 PM8/15/13
to confd-us...@googlegroups.com
The cdb_get_values function just returns a confd_value_t for each leaf. I'm assuming you've used a union type to get to this situation. You'll need to use the confd_value_t's "type" field value to tell these two apart (C_INT and C_BUF). Read confd.h (or whichever header defines the enumerated values for C_xxxxxx in your release) to see how confd_value_t is defined and you'll see what I mean. 

chriss

unread,
Aug 15, 2013, 3:52:43 PM8/15/13
to confd-us...@googlegroups.com
Hi Dennis,
I agree with Jim's excellent response. In fact we do just this for certain union objects. On this note, we've been using cdb_get_values() a lot. We wrote some helper APIs which work against an array of hash tags and eliminate a lot of tedious tag-value-array-filling code. You just define a static array of hash tags. At run time the APIs dynamically construct an array of tag values, which you can pass to cdb_get_values() OR mappi_get_values(). Then you can write another helper to extract the returned tag-values into a structure to use elsewhere in the application. Good luck! - chris

Dennis McCracken

unread,
Aug 16, 2013, 7:01:27 AM8/16/13
to confd-us...@googlegroups.com
Thanks for the reply Jim.  We are indeed using a union for this leaf.  

I'm still not following your reply.  When you create an entry in the confd_tag_value_t array you need to set the type being requested.  I don't know at this point if the leaf is C_BUF or C_INT.  

CONFD_SET_TAG_PTR(&tv[j], SIP_TRUNK_GROUP_callLimit, 
                          valLimit.type,
                          &sgAdmn.ipCallLimit);

sgAdmn.ipCallLimit is an integer we want either the C_INT value or -1 stored.  

-Dennis-

Dennis McCracken

unread,
Aug 16, 2013, 7:13:48 AM8/16/13
to confd-us...@googlegroups.com
Hi Chriss,

I too am looking at wrapping cdb_get_values() in an API.  However I am taking the approach of a wrapper class that takes the form of a transaction.  We have lots of cases where C_ENUM_HASH is actually stored in a 'C' structure as a char value because we know the enumerated list is short (<255).  However cdb_get_values will return a C_ENUM_HASH as an int.  Worse, CONFD_SET_TAG_PTR is not typesafe as it casts the pointer passed in to a void*.

The use case would look something like this:

ElementQuery q;
ElementFactory f;
unsigned char value;
<more values>

q->setPath("path to container");
q->addElement(f->makeEnum("leaf name", &value));

<add more elements to the query>

q->execute();

ElementFactory contains a bunch of overloaded make functions for all the various combinations of C_types and destination types.  The magic of how the value returned from confd is stored in the destination is known by the store method in the concrete Element classes.

-Dennis-

Jim Boucher

unread,
Aug 16, 2013, 3:25:45 PM8/16/13
to confd-us...@googlegroups.com
Hi Denis,
   Good point. I was thinking of the cdb_get_objects / maapi_get_object functions where you don't need to specify a type. I'm guessing you don't want to use this option due to this data not being part of a list or whatever. Is that right? At its ugliest, I'm guessing you can use C_NOEXISTS to skip this value and do a separate cdb_get() to get the specific union element. I agree that there should be a more elegant way. Did you see anything in the list of types for C_xxxx in the confd.h header that might be more generic (like a C_UNION or whatnot)?
Cheers,

Jim

Dennis McCracken

unread,
Aug 19, 2013, 8:40:50 AM8/19/13
to confd-us...@googlegroups.com
You are right Jim, I should be using cdb_get_objects. Thanks!

-Dennis-

Per Hedeland

unread,
Aug 19, 2013, 2:51:43 PM8/19/13
to confd-us...@googlegroups.com


On Friday, August 16, 2013 9:25:45 PM UTC+2, Jim Boucher wrote:
Hi Denis,
   Good point. I was thinking of the cdb_get_objects / maapi_get_object functions where you don't need to specify a type. I'm guessing you don't want to use this option due to this data not being part of a list or whatever. Is that right? At its ugliest, I'm guessing you can use C_NOEXISTS to skip this value and do a separate cdb_get() to get the specific union element.

You can indeed use C_NOEXISTS in the cdb_get_values() array, but it doesn't mean "skip this value". Allow me to quote the documentation...

       o   C_NOEXISTS means that the value should be read from CDB and stored
           in the array.

       o   C_PTR also means that the value should be read from CDB, but
           instead gives the expected type and a pointer to the type-specific
           variable where the value should be stored. Thus this gives a
           functionality similar to the type safe versions of cdb_get().

I.e. C_NOEXISTS works fine for retrieving the value of a union with different "primary" member types, but neither C_PTR nor cdb_get_<type>() does - in both cases you need to both give the specific C_XXX type (implicit in the name of the function for cdb_get_<type>()) and pass a pointer to a variable where the "plain" value should be stored, and neither is doable for such a union. And yes, you can mix C_NOEXISTS and C_PTR in the same cdb_get_values() call if you want to.

--Per Hedeland

Reply all
Reply to author
Forward
0 new messages