Re: a better libtds

"James K. Lowden" <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
On Sun, 21 Aug 2011 11:53:51 +0200
Frediano Ziglio <[email protected]> wrote:

> 2011/8/19  <[email protected]>:
> 
> > 1.  More predictable and rational flow of control, essential for
> > thread safety.
> >
> > 2.  Clear factoring of protocol versions.
> 
> I don't understand these points that much, could you detail a bit?

The parser-generated code calls tds_poll().  It knows how to parse the
incoming bytestream.  For parsed element in the stream, it calls a
libtds callback function, which fills part of a C struct
representing the packet.  The libtds call back functions need never
know what TDS version is being used.  All version-dependent branches in
the packet parsing are described in the BNF input to the
parser-generator.  

BNF also knows the sequence of packets.  The client library request a
row from libtds with tds_get_row_packet().  If there's a row, the
parser-generated code returns it.  Before it returns, though, it looks
ahead one token.  It the next token is TDS_ROW, it halts, returning the
struct.  If the next token is TDS_DONE_PROC, it keeps going, invoking
libtds callback functions to accept rowcount and return status.  

> > 4.  Removal of iconv from TDS layer.  libtds should be transparent.
> > Charset issues are binding issues; client libraries need to support
> > access to the raw data.  Cf. dbdata() and nvarchar columns.
> 
> Yes, although clients does not expect column names encoded with wide
> character sets. And also dblib does not support wide characters.

True.  The only need for UCS2 in libtds is for metadata.  

> > 5.  Packet-based access to the network.  Data exchange between the
> > client libraries and libtds should be by packet.
> >
> >    I do not mean that each client library should chase every
> > packet 1:1 on the wire.  In particular, libtds has to scoop up the
> > DONE_IN_PROC and compute packets after e.g. the final dbnextrow().
> 
> By packet do you mean stream here, am I right ?

The client library need never touch the stream.  It passes C structs
representing packets to libtds, which either writes the struct to the
wire or fills the struct from the wire.  

> > 6.  The same state machine can inform a server implementation.
> 
> ???

If we have e.g. the LOGIN packet described in tabular form, we can
generate both a C struct with metadata for a generic packet writer (see
my message to Brian) *and* BNF for a packet parser.  

Our src/server implementation is out of date.  I hope we can use a
formal description of TDS to create a new one.  That would be useful to
write gateways.  The far side of the gateway need not even be TDS;
think of TDS<->SQLite or TDS<->Postgres.  

> The question is: how to handle tds_next_packet_type/tds_get_XXX in
> order to avoid monstrous loops and switch?

Callbacks.  :-)

> I agree filling the same structure for every stream lead to the giant
> TDSSOCKET structure and would be better if every generated stream
> handle could return data readed from wire.

Exactly.  

> I must admit C++ have very interesting feature missing in C.

Yes, but maybe not enough for this purpose.  

> Agree. Code grown and grown and some parts become ugly.

Excellent.  What do you think of RDP?  

http://www.cs.rhul.ac.uk/research/languages/projects/rdp.html

Regards, 

--jkl
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.