Skip to Content.
Sympa Menu

freetds - Re: DBLIB function

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Lowden, James K" <LowdenJK AT bernstein.com>
  • To: "'TDS Development Group'" <freetds AT franklin.metalab.unc.edu>
  • Subject: Re: DBLIB function
  • Date: Mon, 8 Jul 2002 15:20:23 -0400


> From: Brian Bruns [mailto:camber AT ais.org]
> Sent: July 8, 2002 2:39 PM
>
> Looks like anything that sets DBPROCESS in a stateful way is
> supposed to set the avail flag.

Brian,

I think your "implementation #2" conforms to what little the docs say, yes.
And I agree with your assessment of the API. ;)

Could you explain what's meant by "sets DBPROCESS in a stateful way"? In my
mind, and maybe only there, the dbproc is almost always in a state. That
is, it's rare in the life of a dblib program that the dbproc is available
for a new query (or bcp load). Most of the time, the dblib calls you can
make are very much circumscribed by what call was just made. From that
point of view, I don't see how dbsqlexec is any more or less "stateful" than
dbresults. But you and Sybase must have something in mind.

Knowing you, you'll probably have this all implemented by the time you read
this.

--jkl

> That looks like dbcmd, dbfcmd (dbproc->dbbuf), dbsqlexec, dbsqlsend
> (dbproc->tds->state). I wonder about dbbind(), i'm guessing
> yes. dbuse
> calls sqlexec so that is covered. Probably alot of BCP and writetext
> stuff. Most other things are read only or are single call transitions
> like dberrhandle() that return the dbproc to an available state.
>
> I dislike this call immensely. We'll support it for legacy code of
> course, but I think the API is misguided here. Especially, since the
> documentation never says what calls set the flag, and
> therefore is subject
> to change in subtle ways.
>
> Ok, for implementation #2
>
> add
>
> unsigned char avail_flag;
>
> to include/sybdb.h in the DBPROCCESS table.
>
> add
>
> dbproc->avail_flag = FALSE;
>
> at the top of functions dbcmd, dbfcmd, dbsqlexec, dbsqlsend, dbbind
> (guessing)
>
> and then you need these functions:
>
> void dbsetavail(DBPROCESS *dbproc)
> {
> if (dbproc)
> dbproc->avail_flag = TRUE;
> }
> DBBOOL DBISAVAIL(DBPROCESS *dbproc)
> {
> return dbproc->avail_flag;
> }
>
> and finally in dbopen() set
>
> avail->flag = TRUE;
>
> after the memset(). Look good to everyone?
>
>
> Brian
>
>
>
> > > From: Bill Thompson [mailto:thompbil AT exchange.uk.ml.com]
> > > Sent: July 8, 2002 12:35 PM
> > >
> > > Seriously, if we need this we'll also need dbsetavail().
> > > It looks to me like these two functions support a
> > > programmatic method of
> > > managing concurrent use of a dbprocess (rather than
> saying anything
> > > intrinsic about what is actually happening with the
> > > connection, such as a
> > > query having results pending). is that your reading of it ?
> >
> > I modified my "dbsql" utility to:
> >
> > * display the results of dbisavail() after each dblib call
> > * if it returns FALSE, call dbsetavail().
> >
> > Here's what happened on an NT platform with MS's dblib:
> >
> > $ echo select 1 union select 2 |dbsql -U LowdenJK -P %P% -S
> spquant -d
> > testdb
> > dbisavail = 1 after dbopen
> > dbisavail = 0 after dbuse
> > select 1 union select 2
> > dbisavail = 0 after dbcmd
> > dbisavail = 0 after dbsqlexec
> > dbisavail = 1 after dbresults
> > 1 columns returned.
> > dbisavail = 1 after dbnextrow
> > dbisavail = 1 after dbcolname
> > dbisavail = 1 after dbdata
> > column_name:
> > column_type: 56
> > column_size: 4
> > length: 4
> > data (first word): 0x2
> > dbisavail = 1 after dbcoltype, dbcollen, dbdatlen
> > dbisavail = 1 after dbnextrow
> > dbisavail = 1 after dbcolname
> > dbisavail = 1 after dbdata
> > column_name:
> > column_type: 56
> > column_size: 4
> > length: 4
> > data (first word): 0x1
> > dbisavail = 1 after dbcoltype, dbcollen, dbdatlen
> > dbisavail = 1 after dbnextrow == NO_MORE_ROWS
> > dbisavail = 1 after dbresults == NO_MORE_RESULTS
> >
> > It looks like the dbproc is automatically "unavailable"
> between selecting a
> > database and preparing the query for processing.
> >
> > Note well, it's of NO USE in coordinating threading without
> dbsetavail()
> > (because no dblib call implicitly sets the dbproc to
> "available"). In any
> > case dbisavail() possesses only rudimentary intelligence about the
> > "availability" of the process: In what sense is a dbproc
> "available" after
> > calling dbresults()? If results are pending, a severe
> error will occur
> > unless they are either fetched or cancelled.
> >
> > To implement this nonquickly, we need to add a member to
> DBPROCESS; its role
> > is similar to user_data, except that occasionally dblib
> will reset it.
> >
> > (Anagh, if I were you, I'd consider adding a stub implementation of
> > dbisvail() in you application that always returns TRUE. Given the
> > braindeadness of the function, that might do. Or,
> implement both in terms
> > of dbsetuserdata() and dbgetuserdata(), which we do support.)
> >
> > Best regards,
> >
> > --jkl
>
> ---
> You are currently subscribed to freetds as: [LowdenJK AT bernstein.com]
> To unsubscribe, forward this message to
> $subst('Email.Unsub')
>




Archive powered by MHonArc 2.6.24.

Top of Page