Skip to Content.
Sympa Menu

freetds - Re: Is this what I need?

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Brian Bruns <camber AT umcc.ais.org>
  • To: TDS Development Group <freetds AT franklin.oit.unc.edu>
  • Subject: Re: Is this what I need?
  • Date: Tue, 29 Dec 1998 20:32:40 -0500 (EST)




On Tue, 29 Dec 1998, James Cameron wrote:

> Thanks, Brian and Sam.
>
> I've now built it on Red Hat V5.1 and am trying to modify the
> samples/tdstest.c module to prove that it works for me.
>
> In main(), there are a set of tds_set_*() calls, some of which I can
> comphrehend but others I cannot. I need to figure the mapping between
> what I put here and what I was given just then by someone who runs a
> server.
>
> They told me;
>
> Software being run is SQL 7 (presumably Microsoft SQL)
> Machine name snoad.dhcp.sno.dec.com [tds_set_host]
Actually, this is the host name of the client. It seems strange but its
the way it is.
> Standard security not NT security (means nothing to me!)
> Username fred [tds_set_user]
> Password fred [tds_set_passwd]
> Database is "pubs" [?]
>
> I've been able to match up some of these, clearly.
> But in the tdstest.c module I need to understand;
>
> tds_set_app sqsh
This is a field for the client application to identify itself. Running
SQSH would set this to 'sqsh' for instance. It should be an pseudo-unique
name, but totally optional.
> tds_set_library TDS-Library
This is set by the library layer. Let me go on a tangent for a minute.
FreeTDS is basically structured like this:

+--------------------+
| client application |
| (you write this) |
+--------------------+
|
|
+------------+ +----------+ +----------+ +--------------+
| DB Lib | | CT Lib | | ODBC | | DBI (future) |
+------------+ +----------+ +----------+ +--------------+
these are | | | |
known as CLIs \ | | /
(call level \ | | /
interfaces) \ | | /
+----------------------------------------+
| TDS core |
+----------------------------------------+
|
(TCP/IP Stack)
|
+----------------------------------------+
| Microsoft or Sybase SQL-Server |
+----------------------------------------+

So, the CLIs are existing APIs that talk to a server. The TDS code handles
all the nuances of making the socket connection to the server, sending
requests, and interpreting responses. It is fairly low level and not all
that well suited for being used directly by the client code (but it is
possible, just not avisible). In the protocol there is a field for the
client library (CLI) to tell the server what it is. As far as I'm aware
this field is not used by the server, however we set it just to be 100%.

The lesson here would be, use one of the CLIs. It will do much dirty work
for you. Currently DB-lib is the most usable, and will eventually be
call-for-call compatible with Sybases dblib. For documentation on Sybases
dblib, see http://sybooks.sybase.com and the book you are looking for is
OpenClient DB-Library/C Reference Manual.

Sorry for being long winded!
> tds_set_server JDBC
>
Ok, this is the actual server you want to connect to. This information is
stored in a file called "interfaces" in the $SYBASE directory. ($SYBASE
should be set to point at your freetds install directory
(/usr/local/freetds by default). There is an example file with the
distribution and JDBC is an internet accessible Sybase server you may use
for testing. (It was put up by sybase to test their "jConnect" product,
but it works well in other capacities too). The other thing you need in
the interfaces file is the port number that the server is listening at.

I'll also attach a minimalist dblib program to give you a feel for how
things should work:

#include <sybdb.h> /* add -I $SYBASE/include to your Makefile */
main()
{
LOGINREC *login;
DBPROCESS *dbproc;
char dbname[256];

dbinit(); /* init the library */

/* get a login structure and populate it */
login = dblogin();
DBSETLPWD(login,"sybase");
DBSETLUSER(login,"guest");

dbproc = dbopen(login, "JDBC"); /* this creates the connection */

dbcmd(dbproc,"select db_name()"); /* the SQL select */
dbsqlexec(dbproc); /* send it off to the server */
/* process each result set and each row in that set */
while (dbresults(dbproc)!=NO_MORE_RESULTS) {
/* each time a row is processed column 1 will be copied to dbname */
dbbind(dbproc,1,STRINGBIND,-1,(BYTE *) dbname);
while (dbnextrow(dbproc)!=NO_MORE_ROWS) {
printf("database name is %s\n",dbname);
}
}
dbclose(dbproc);
dbexit();
}

It's missing almost all error checking, but it'll give you a flavor for
it.

Hope this helps!

Cheers,

Brian

> Where do I put what?
> --
> James Cameron (cameron AT stl.dec.com)
>
> OpenVMS, Linux, Firewalls, Software Engineering, CGI, HTTP, X, C, FORTH,
> COBOL, BASIC, DCL, csh, bash, ksh, sh, Electronics, Microcontrollers,
> Disability Engineering, Netrek, Bicycles, Pedant, Farming, Home Control,
> Remote Area Power, Greek Scholar, Tenor Vocalist, Church Sound, Husband.
>
> "Specialisation is for insects." -- Robert Heinlein.
>










Archive powered by MHonArc 2.6.24.

Top of Page