Hi Ross,

On Sat, Aug 29, 2009 at 07:54:06AM -0700, Ross McFarland wrote:
> but it's not optional, at least with the current setup. if you try to connect
> without providing it you'll get an error.

If you hit a case where you could not connect without a DB context,
this is a bug somewhere. I tend to follow the rule that all optional
parameters are not part of the "constructor", but this may be a case
where since it's so common we may want to add it and just allow NULL
for no DB.

> that seems cleaner. but i think auth should be a seperate call since it's
> optional in the tcp and uds cases.

Sounds good, we can keep auth separate. This makes even more sense
with drizzle, since we have no auth by default.

> seems cleaner. at that point do queries happen on the drizzle object, which
> automatically selects a connection for you?

The intent was to have a simple con object to run single queries
on. You would not be using the top level drizzle object for more
advanced uses like concurrent queries. This was just a shorthand for
a fairly common case, but I agree it breaks the OO nature. I'll be
removing this.

> right, my point is that 9 situations out of 10 you'll have to call _destroy
> anyway. if you get rid of the recursive free stuff the library would have to
> keep track of less stuff and it would be 10 out of 10. in my opinion 10 out of
> 10 is way better than 9 out of 10 b/c only you, who designed the library, will
> be able to keep track of when you're in the 9 or the 10th.

So, I certainly see your point here, and now agree with you. Object
tracking and automatic memory freeing was really designed with
libdrizzle-allocated objects in mind, not user-supplied allocated
objects (stack or user managed heap). For these more common cases
like you describe, it makes no sense to have it. This feature is
still extremely useful for advanced interfaces that allow libdrizzle
to manage all the object memory (like the language binding APIs we've
already created), so I think I'll keep it but make it optional (and
off by default).

This will allow the normal use cases like you describe to have
expected behavior and better memory warnings, but it's there for
those few applications that really need it.

> > What other information would be useful to track? Every object has
> > a (void *) member that is for the application to use however it
> > likes. This allows client-api wrappers to bind their own objects to the
> > C objects as the need, since these may not always be in scope. There
> > are even user-defined callbacks to allow you to properly destroy the
> > (void *) members when things are being cleaned up. I actually spent
> > a lot of time thinking this part through and also had feedback from
> > Monty Taylor who did a bunch of other language bindings. I'm very
> > interested to hear what else may be useful, or some other way to help
> > track objects for higher level languages.
> 
> that seems like it's tacking on a feature to solve something that shouldn't 
> be a
> problem in the first place.

If you really dig into how the other language bindings work, like PHP,
Python, ..., you'll notice some really common patterns. Sure, these
extra things did not need to be in libdrizzle, but they are there
because each of the language bindings would have needed to write
the same bit of code to manage this. There were enough use cases
(language bindings, advanced library usage, ...) where this made
sense to be an optional feature in the main library.

> i don't really like the idea, but based on the current design of objects
> referring around to other object they need it seems like libdrizzle objects 
> need
> reference counting. at least it would make more sense than forcing every 
> binding
> (and non-trivial app) to keep track of them on their own, reinventing the 
> wheel
> over and over.

So, the reference counting is really already in there. This is the
set of object lists that exist in objects (ie, all connections for
a drizzle object, ...). The external reference tracking done by the
language APIs can do this using the (void *)/callbacks I mentioned
before, there is only so much libdrizzle can do to help out there,
and I believe this interface supplies all it can. If you have the
time and interest, I would really check out how things work in the
Drizzle PHP extension as far as references go and how they relate to
C objects. Some of this will make a lot more sense.

In any case, I completely agree this is not a common case and should
not be part of any default behaviors. I may even create a separate
section in the header files to put these more advanced functions in.

> this is a pretty good example of why this process has been frustraiting to me.
> most of your answers tell me how to do whatever i'm talking about with the
> current design. i'm not claiming that these things can't be done, i'm saying
> that they're more non-obvious, error-prone, or complicated than they
> need to be.

Agreed, and this is why I'm now convinced that the automatic memory
cleanup/free will be switched to optional, and off by default. Like
I said, the use case in my header was libdrizzle-managed heap memory,
not stack.

> > Most folks actually use the behavior of waiting for the result right
> > away, it's really only more advanced apps where people handle async
> > stuff properly. Ideally people will start using the async to improve
> > their apps, which may be enough to make it the default. I'm certainly
> > up for changing this behavior, this is on the list to the mailing
> > list of what is preferred.
> 
> most probably do, but it won't hurt anyone not to and it will make it way 
> easier
> for those who want the other behavior.

Agreed, I'll be switching this around.

> if you force calling a free inbetween next calls (as your saying is probably
> really necessary) it's going to be more verbose, but then you can at least 
> skip
> the init case. i don't really like it either, but in the case of actual oo
> languages init is just the constrctor. anyway, this is essentialy an iterator
> pattern so it probably should follow a iterator semantics to make use of
> people's familiarity with the pattern.

I would argue the current iterator interface is simple for folks
to use in libdrizzle. For example, the init() does not return the
first element, it just inits it. I think you should be iterating in
the context of a higher level object (ie, result, not raw rows). For
example, your simple_port.c would change from:

    drizzle_row_initialize (&row, &query);
    drizzle_row_dump (&row, "");
    drizzle_field_initialize (&field, &row);
    drizzle_field_dump (&field, "");
    while (drizzle_field_next (&field) == DRIZZLE_RET_OK)
        drizzle_field_dump (&field, "");
    drizzle_field_destroy (&field);

    while (drizzle_row_next2 (&row) == DRIZZLE_RET_OK)
    {
        drizzle_row_dump (&row, "");
        drizzle_field_initialize (&field, &row);
        drizzle_field_dump (&field, "");
        while (drizzle_field_next (&field) == DRIZZLE_RET_OK)
            drizzle_field_dump (&field, "");
        drizzle_field_destroy (&field);
    }

To:

    drizzle_result_initialize (&result, &query);

    /* drizzle_result_next_row calls drizzle_row_init(&row) */
    while (drizzle_result_next_row (&result, &row) == DRIZZLE_RET_OK)
    {
        drizzle_row_dump (&row, "");
        /* drizzle_row_field_next calls drizzle_field_init(&field) */
        while (drizzle_row_next_field (&row, &field) == DRIZZLE_RET_OK)
        {
            drizzle_field_dump (&field, "");
            drizzle_field_destroy (&field);
        }
        drizzle_row_destroy(&row);
    }

This seems a bit cleaner to me, but again, this may just be a style
difference. It's also much easier to iterate in the context of
non-blocking I/O, since you need to keep some state between calls.

> i think, and am probably wrong, that mostly is b/c you've approached the 
> thread
> as a support request. showing me how to do things with the current library
> rather than looking at how things work/how obvious they'll be to 3rd parties.

I've actually not been thinking in terms of "how to do this the way
things are", I apologize if it came off that way. I've been approaching
this with an open mind of how to improve the current API. I was only
describing the current library in order to explain how things work
for comparison. I understand that because I've had to explain so much,
this means some changes are needed. :)

> the ideal case is that someone opens up the header(s) (and maybe an example or
> two.) then goes to town; never having to look at doc or ask a question on the
> list. i don't think anything about the problem libdrizzle is solving requires 
> a
> libarary where this couldn't be the case, but a lot of the current design
> decisions will prevent it from being. (memory management, lifetime/association
> kknowledge, naming, what object functions are on, ...)

Agreed. This is certainly what I'm striving for.

-Eric

_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to