Re: a better libtds
"James K. Lowden" <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 18 Aug 2011 20:39:31 -0400 Brian Bruns <[email protected]> wrote: > MARSy type stuff would be easier (can have a separate state machine > for TDS+MARS), SSL/TDS isn't such a kludge, and deferred/asynchronous > I/O gets a whole lot easier. This also makes something like TDS over > RPC or named pipes much more approachable. > > I think everyone agrees the byte-by-byte read from the wire idiom that > libtds is written in is a disaster. > > Is this along the lines of what you were thinking Jim? Yes, indeed, Brian, it is. The byte-by-byte write idiom isn't much better (although it doesn't occur as much, mostly in login, bcp, and parameterized queries). It's hard to avoid because a C struct doesn't contain enough run-time information to drive a generalized packet-writer, what the Java folks call "reflection". That is, there's no way at run-time to enumerate a struct's elements, let alone their types. If, however, C structs were generated from a table describing the packet, the generator could include an array of types and addresses, viz: struct tds_member_t { TDS_TYPE type; void * addr; }; struct tds_XXX_packet { enum {tds_XXX_packet_nelem = NN}; struct tds_member_t elem[NN]; ... }; Now we need only one packet writer. Each elem is only an alias to a struct member. The packet-writer iterates over elem, and writes it to the wire according to the rules of TDS. When populating the struct, the member can be more conveniently referenced by name. It might prove convenient to use a similar structure for TDS_ROW; it could unify the structure of regular and compute rows. --jkl