From d4t4full at ...176... Wed Aug 19 20:20:45 2015 From: d4t4full at ...176... (zxmarce) Date: Wed, 19 Aug 2015 11:20:45 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. Message-ID: <1440008445399-52283.post@...752...> Hi guys, first devel post. For some time now I needed to be able to use connection strings (?-la MS) in the *ODBC* component for connecting to DB Servers. In ODBC parlance, I need to use *DSN-less* connections. When this all started, I used only packaged Gambas binaries, and knew just a bit of C and nothing about Linux. I still do, but I gained some self-trust in C and also started tinkering with C unixODBC examples in the 'Net. I even made a Gambas3 class to connect using EXTERN calls to *libodbc* to see if connection with ConnStrings is possible: It is! There are two main issues with this approach: 1- My class cannot create and manipulate G3 database objects at low level. 2- Given problem 1 above, any existing DB-access program should be remade since there's no back-compatibility due to not being able to use native G3 DB components. All this made me look at the *gb.db.odbc* C sources. I downloaded them and added an IF and a Function. My modified component source calls my new internal function (*static bool is_host_a_connstring(char *host_or_cs)*) in order to see if the *.Host *property of the *Connection* object is a Host name (no embedded "*;*" or "*=*"), or a Connection String (has embedded "*;*" and/or "*=*"). Based on the outcome of the function, it calls *SQLConnect* (when a Host) as before, or *SQLDriverConnect* (when a ConnString). Those are the only changes, but more changes MAY be necessary, I do not really know. That was the only place where the component seems to use an ODBC connect call. My additions/changes were tested successfully in a C example that used SQLConnect which I turned interactive and can now connect to a DSN or using a DSN-less, ConnectionString-based approach. Now that I have the "new" *gb.db.odbc* component sources, I need three things: 1- How to compile -if possible- just my ODBC component modified. 2- Once compiled, where to install it so G3 can use it, having backed up the older one just in case. I have both, 32 and 64 bit Ubuntu 14.04 systems available for testing. 3- If my tests after compiling and using go OK, whom/where should I send the sources for further test and inclusion in the main G3 sources? TIA, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283.html Sent from the gambas-devel mailing list archive at Nabble.com. From gambas at ...1... Wed Aug 26 01:01:49 2015 From: gambas at ...1... (=?UTF-8?B?QmVub8OudCBNaW5pc2luaQ==?=) Date: Wed, 26 Aug 2015 01:01:49 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440008445399-52283.post@...752...> References: <1440008445399-52283.post@...752...> Message-ID: <55DCF3DD.9020006@...1...> Le 19/08/2015 20:20, zxmarce a ?crit : > Hi guys, first devel post. > > For some time now I needed to be able to use connection strings (?-la MS) in > the *ODBC* component for connecting to DB Servers. In ODBC parlance, I need > to use *DSN-less* connections. > > When this all started, I used only packaged Gambas binaries, and knew just a > bit of C and nothing about Linux. I still do, but I gained some self-trust > in C and also started tinkering with C unixODBC examples in the 'Net. I even > made a Gambas3 class to connect using EXTERN calls to *libodbc* to see if > connection with ConnStrings is possible: It is! > > There are two main issues with this approach: > 1- My class cannot create and manipulate G3 database objects at low level. > 2- Given problem 1 above, any existing DB-access program should be remade > since there's no back-compatibility due to not being able to use native G3 > DB components. > > All this made me look at the *gb.db.odbc* C sources. I downloaded them and > added an IF and a Function. > > My modified component source calls my new internal function (*static bool > is_host_a_connstring(char *host_or_cs)*) in order to see if the *.Host > *property of the *Connection* object is a Host name (no embedded "*;*" or > "*=*"), or a Connection String (has embedded "*;*" and/or "*=*"). Based on > the outcome of the function, it calls *SQLConnect* (when a Host) as before, > or *SQLDriverConnect* (when a ConnString). Those are the only changes, but > more changes MAY be necessary, I do not really know. That was the only place > where the component seems to use an ODBC connect call. > > My additions/changes were tested successfully in a C example that used > SQLConnect which I turned interactive and can now connect to a DSN or using > a DSN-less, ConnectionString-based approach. > > Now that I have the "new" *gb.db.odbc* component sources, I need three > things: > 1- How to compile -if possible- just my ODBC component modified. > 2- Once compiled, where to install it so G3 can use it, having backed up the > older one just in case. I have both, 32 and 64 bit Ubuntu 14.04 systems > available for testing. > 3- If my tests after compiling and using go OK, whom/where should I send the > sources for further test and inclusion in the main G3 sources? > > TIA, > zxMarce. > Hi, Sorry for the delayed answer, the new Gambas bugtracker was a bit urgent... For a small change, just send a patch to the dev. mailing-list, or the modified file. The driver is just one source file, so I can check & merge the change for you. Otherwise, generally, you must: - Use subversion. - Create a sourceforge account. - Ask me for a write access to the repository. - Checkout a local copy of the Gambas source tree. - Remove all other installation of Gambas from your system. - Do your changes in it, and do all the configuration / compilation / installation stuff in it. You are using the "development version" of Gambas now. - Once everything works, you commit your changes. Everybody else can access them, and it will be inserted in the next major release of Gambas. Regards, -- Beno?t Minisini From d4t4full at ...176... Wed Aug 26 03:22:59 2015 From: d4t4full at ...176... (zxMarce) Date: Tue, 25 Aug 2015 18:22:59 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440008445399-52283.post@...752...> References: <1440008445399-52283.post@...752...> Message-ID: <1440552179900-52451.post@...752...> Beno?t Minisini wrote > Hi, > > Sorry for the delayed answer, the new Gambas bugtracker was a bit > urgent... > > For a small change, just send a patch to the dev. mailing-list, or the > modified file. The driver is just one source file, so I can check & merge > the change for you. > > Otherwise, generally, you must: > - Use subversion. > - Create a sourceforge account. > - Ask me for a write access to the repository. > - Checkout a local copy of the Gambas source tree. > - Remove all other installation of Gambas from your system. > - Do your changes in it, and do all the configuration / compilation / > installation stuff in it. You are using the "development version" of > Gambas now. > - Once everything works, you commit your changes. Everybody else can > access them, and it will be inserted in the next major release of Gambas. > > Regards, > > -- > Beno?t Minisini Beno?t, The changes for ODBC are kinda small, but even so I think I will go with the whole SVN thingie. That way I won't bother you with further additions or corrections in case it does not work properly, or trashes the whole Gambas-DB ecosystem... Call me paranoid, but I don't like to send a component modification into the wild without testing it. It works in paper and in C, but I could not yet test it as a proper Gambas component. Just registered on SF, also as zxMarce. Do not grant me write access yet. I'll do the mod checking out the current devel SVN branch (3.8.90) and if my -limited- tests work, I'll ask you for write access. I'll plan to do my changes on a local copy on a local virtual machine, so I have both "user" and "devel" environments apart (two 32bit virtual machines). One question regarding this: My host is a 64bit Ubuntu 14.04. If I develop on 32bit, will the module run in the 64bit host? (I presume it will not, but not sure). I expect to have the virtuals up in a coupla days time. Thanks again, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283p52451.html Sent from the gambas-devel mailing list archive at Nabble.com. From d4t4full at ...176... Thu Aug 27 14:54:15 2015 From: d4t4full at ...176... (zxMarce) Date: Thu, 27 Aug 2015 05:54:15 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440552179900-52451.post@...752...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> Message-ID: <1440680055167-52511.post@...752...> Beno?t, It's alive! Mbwehehehe... Well, kind of. It does work as intended, but the connection's *.User* property must be set to something, even if it is not the real username from the connection string. Otherwise, if the *.User* property is not set: Bam! *SegFault*. This connects OK (using 'Johnny' as user name in the conn string, but not in the conn.User property): This explodes with SegFault (also using 'Johnny' as user name in the conn string): So, here's where my C drowns. I do not know the "chain of command" (I mean, what is called by who), and thus I have no way of knowing what code needs the *.User* property populated. I saw several debug blocks like this in the code but I don't know how to properly activate them, or where to look for their output once they're active: Care to throw me a 'pointer' to where I should start? I need to know what happens at low level when Gambas runs Connection.Open; I mean the whole code and file paths that end in *gb.db.odbc/src/main.c*, so I can check every step. Also, knowing this, maybe I can make some progress regarding the *RowCount = -1* that MSSQL usually returns when running a query that returns a Result. zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283p52511.html Sent from the gambas-devel mailing list archive at Nabble.com. From taboege at ...176... Thu Aug 27 15:49:55 2015 From: taboege at ...176... (Tobias Boege) Date: Thu, 27 Aug 2015 15:49:55 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440680055167-52511.post@...752...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> Message-ID: <20150827134955.GB653@...693...> On Thu, 27 Aug 2015, zxMarce wrote: > Beno??t, > > It's alive! Mbwehehehe... > Well, kind of. It does work as intended, but the connection's *.User* > property must be set to something, even if it is not the real username from > the connection string. Otherwise, if the *.User* property is not set: Bam! > *SegFault*. > > This connects OK (using 'Johnny' as user name in the conn string, but not in > the conn.User property): > > This explodes with SegFault (also using 'Johnny' as user name in the conn > string): > > So, here's where my C drowns. I do not know the "chain of command" (I mean, > what is called by who), and thus I have no way of knowing what code needs > the *.User* property populated. > I saw several debug blocks like this in the code but I don't know how to > properly activate them, or where to look for their output once they're > active: > > Care to throw me a 'pointer' to where I should start? > I need to know what happens at low level when Gambas runs Connection.Open; I > mean the whole code and file paths that end in *gb.db.odbc/src/main.c*, so I > can check every step. > Also, knowing this, maybe I can make some progress regarding the *RowCount = > -1* that MSSQL usually returns when running a query that returns a Result. > Have a look at main/lib/db. This is the gb.db component which declares the Connection class. As I don't know how far you've come with programming components in Gambas, I'll point you to things in small steps. If you are interested in Connection, open CConnection.c and look for the declaration of the class interface which you will usually find at the end of the source file: GB_DESC CConnectionDesc[] = { GB_DECLARE("_Connection", sizeof(CCONNECTION)), ... }; Notice that the class being declared is actually named "_Connection". But this is the base class for gb.db's Connection (the real Connection class is written in the Gambas part of the component and inherits _Connection). You can find the implementation of Connection.Open by parsing this interface description: it is the function CCONNECTION_open(). From there you trace your way to open_connection() where the important line is: if (DB_Open(&THIS->desc, &THIS->driver, &THIS->db)) return; DB_Open() brings you to main.c where you learn that different database types are implemented by driver structures. The gb.db.mysql component declares a driver structure for converting access to the Connection object into MySQL language, the gb.db.sqlite3 does the same for SQLite3, etc.. Similarly gb.db.odbc has a DECLARE_DRIVER statement somewhere in its main.c. There it lists ODBC-specific implementations of various methods of the Connection class. This should enable you to trace the complete path from the Connection class to your driver. I think you should not just call the user "Johnny". If there is no sensible username in ODBC, return an empty string. Also, as you may not be aware of it, I have written an article about native component programming for Gambas. It is here[0] and may be of some use for you. Regards, Tobi [0] http://www-e.uni-magdeburg.de/tboege/gambas/ -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk From gambas at ...1... Thu Aug 27 16:35:23 2015 From: gambas at ...1... (=?UTF-8?B?QmVub8OudCBNaW5pc2luaQ==?=) Date: Thu, 27 Aug 2015 16:35:23 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440680055167-52511.post@...752...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> Message-ID: <55DF202B.1030807@...1...> Le 27/08/2015 14:54, zxMarce a ?crit : > Beno?t, > > It's alive! Mbwehehehe... > Well, kind of. It does work as intended, but the connection's *.User* > property must be set to something, even if it is not the real username from > the connection string. Otherwise, if the *.User* property is not set: Bam! > *SegFault*. > > This connects OK (using 'Johnny' as user name in the conn string, but not in > the conn.User property): > > This explodes with SegFault (also using 'Johnny' as user name in the conn > string): > > So, here's where my C drowns. I do not know the "chain of command" (I mean, > what is called by who), and thus I have no way of knowing what code needs > the *.User* property populated. > I saw several debug blocks like this in the code but I don't know how to > properly activate them, or where to look for their output once they're > active: > > Care to throw me a 'pointer' to where I should start? > I need to know what happens at low level when Gambas runs Connection.Open; I > mean the whole code and file paths that end in *gb.db.odbc/src/main.c*, so I > can check every step. > Also, knowing this, maybe I can make some progress regarding the *RowCount = > -1* that MSSQL usually returns when running a query that returns a Result. > > zxMarce. > Note that I didn't write the ODBC driver, so I don't know well what the SQLxxxx ODBC functions really do. I noticed that the connection user (desc->user) is directly sent to the SQLConnect function. Maybe that function does not like getting a NULL pointer there and something must be done in that case. I suggest that you send your code: it will be easier to help you. Regards, -- Beno?t Minisini From d4t4full at ...176... Thu Aug 27 19:14:26 2015 From: d4t4full at ...176... (zxMarce) Date: Thu, 27 Aug 2015 10:14:26 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <55DF202B.1030807@...1...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> <55DF202B.1030807@...1...> Message-ID: <1440695666084-52536.post@...752...> Beno?t, No problem, I know you're not the author of the ODBC component. Precisely, one of my modifications was adding an IF to call either *SQLConnect* (normal method so far) or *SQLDriverConnect*; this is the new call, and does not use .User, .Password nor .Name, as they can all be set in the connection string. I added, then, an IF and a FUNCTION. This is the IF, in main.c's open_database: ... And this is the function that new IF calls: Thanks, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283p52536.html Sent from the gambas-devel mailing list archive at Nabble.com. From d4t4full at ...176... Thu Aug 27 19:23:37 2015 From: d4t4full at ...176... (zxMarce) Date: Thu, 27 Aug 2015 10:23:37 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <20150827134955.GB653@...693...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> <20150827134955.GB653@...693...> Message-ID: <1440696217477-52537.post@...752...> Tobias, I followed -and think understood- most of what you've written, and I plan to read the info linked to see if that clears some doubts I still have. Regarding "Johnny", it was just an example. What I meant is that if I leave a non-null-string as the .User connection property in Gambas code, the component (or gb.db, I don't know) segfaults. On the other hand, if I assign any non-null-string to the .User connection property, this string is ignored (which is OK for the mod I made, as the user name is supplied in the connection string) and the component connects successfully. It is a bad annoyance to have to preassign properties that are not actually used in a component. I think you may continue to hear/read (more nonsense) from me, it looks like you know your C and Gambas components! Thanks, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283p52537.html Sent from the gambas-devel mailing list archive at Nabble.com. From gambas at ...1... Thu Aug 27 20:03:48 2015 From: gambas at ...1... (=?UTF-8?B?QmVub8OudCBNaW5pc2luaQ==?=) Date: Thu, 27 Aug 2015 20:03:48 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1440695666084-52536.post@...752...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> <55DF202B.1030807@...1...> <1440695666084-52536.post@...752...> Message-ID: <55DF5104.70804@...1...> Le 27/08/2015 19:14, zxMarce a ?crit : > Beno?t, > > No problem, I know you're not the author of the ODBC component. Precisely, > one of my modifications was adding an IF to call either *SQLConnect* (normal > method so far) or *SQLDriverConnect*; this is the new call, and does not use > .User, .Password nor .Name, as they can all be set in the connection string. > I added, then, an IF and a FUNCTION. > > This is the IF, in main.c's open_database: > > ... And this is the function that new IF calls: > > Thanks, > zxMarce. > Please post directly to the developer mailing-list. nabble.com makes your mail unreadable by removing pictures. Or don't post pictures. Post the code as text! -- Beno?t Minisini From gambas at ...1... Thu Aug 27 20:06:48 2015 From: gambas at ...1... (=?UTF-8?B?QmVub8OudCBNaW5pc2luaQ==?=) Date: Thu, 27 Aug 2015 20:06:48 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <55DF5104.70804@...1...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> <55DF202B.1030807@...1...> <1440695666084-52536.post@...752...> <55DF5104.70804@...1...> Message-ID: <55DF51B8.6060706@...1...> Le 27/08/2015 20:03, Beno?t Minisini a ?crit : > Le 27/08/2015 19:14, zxMarce a ?crit : >> Beno?t, >> >> No problem, I know you're not the author of the ODBC component. >> Precisely, >> one of my modifications was adding an IF to call either *SQLConnect* >> (normal >> method so far) or *SQLDriverConnect*; this is the new call, and does >> not use >> .User, .Password nor .Name, as they can all be set in the connection >> string. >> I added, then, an IF and a FUNCTION. >> >> This is the IF, in main.c's open_database: >> >> ... And this is the function that new IF calls: >> >> Thanks, >> zxMarce. >> > > Please post directly to the developer mailing-list. nabble.com makes > your mail unreadable by removing pictures. > > Or don't post pictures. Post the code as text! > If your function (is_host_a_connstring) returns a boolean value, you can use 'bool' as return datatype. If you are testing a boolean value, writing that: if (xxx == TRUE) is not needed. Just write: if (xxx) Regards, -- Beno?t Minisini From d4t4full at ...176... Fri Aug 28 13:21:18 2015 From: d4t4full at ...176... (ML) Date: Fri, 28 Aug 2015 08:21:18 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <55DF51B8.6060706@...1...> References: <1440008445399-52283.post@...752...> <1440552179900-52451.post@...752...> <1440680055167-52511.post@...752...> <55DF202B.1030807@...1...> <1440695666084-52536.post@...752...> <55DF5104.70804@...1...> <55DF51B8.6060706@...1...> Message-ID: <55E0442E.4040209@...176...> *On 2015-08-27 15:06, Beno?t Minisini wrote:* > *Le 27/08/2015 20:03, Beno?t Minisini a ?crit :* >> *Le 27/08/2015 19:14, zxMarce a ?crit :* >>> Beno?t, >>> No problem, I know you're not the author of the ODBC component. >>> Precisely, one of my modifications was adding an IF to call either >>> SQLConnect (normal method so far) or SQLDriverConnect; this is the >>> new call, and does not use .User, .Password nor .Name, as they can >>> all be set in the connection string. >>> I added, then, an IF and a FUNCTION. This is the IF, in main.c's >>> open_database: >>> ... And this is the function that new IF calls: >>> Thanks, >>> zxMarce. >> Please post directly to the developer mailing-list. nabble.com makes >> your mail unreadable by removing pictures. >> Or don't post pictures. Post the code as text! > If your function (is_host_a_connstring) returns a boolean value, you > can use 'bool' as return datatype. > If you are testing a boolean value, writing that: > if (xxx == TRUE) > is not needed. Just write: > if (xxx) > Regards, Wow! I did not know Nabble removed text blocks from mails. I now also see the missing segments in my mails. I used 'Raw Text' blocks to post the code. Anyway, for post completeness, the missing if was as follows: if (is_host_a_connstring(desc->host) == TRUE) { /* zxMarce: Connect to Database (desc->host is an ODBC Connection String) */ retcode = SQLDriverConnect(odbc->odbcHandle, 0, (SQLCHAR *) desc->host, SQL_NTS, 0, 0, 0, SQL_DRIVER_NOPROMPT); /* Example - ODBC-ConnString, all one line (must assign this to the Connection.Host property in Gambas code and then call Connection.Open): "Driver=; TDS_Version=; Port=; Database=; UId=; Pwd=>" */ } else { /* Connect to Database (desc->host is an ODBC Data Source Name) */ retcode = SQLConnect(odbc->odbcHandle, (SQLCHAR *) desc->host, SQL_NTS, (SQLCHAR *) desc->user, SQL_NTS, (SQLCHAR *) desc->password, SQL_NTS); } And the missing helper function was: /* Internal function to check if the .Host property is actually an ODBC connection string. ODBC ConnStrings have one or more "ParamName=ParamValue" pairs, delimited by semicolons. The function helps the component know whether to call SQLConnect (when a host/DSN), or SQLDriverConnect (when a ConnString). zxMarce, 20150814 */ static int is_host_a_connstring(char *host_or_cs) { int length = strlen(host_or_cs); bool connstrCharFound = FALSE; int counter; char curChar; for (counter = 0; counter < length; counter++) { curChar = host_or_cs[counter]; if ((curChar == '=') | (curChar == ';')) { connstrCharFound = TRUE; break; } } return connstrCharFound; } Now I will change the function type from INT to BOOL and reform the IF. Thanks for the tip! Regards, -------------- next part -------------- An HTML attachment was scrubbed... URL: