From taboege at ...176... Sun Oct 4 21:21:50 2015 From: taboege at ...176... (Tobias Boege) Date: Sun, 4 Oct 2015 21:21:50 +0200 Subject: [Gambas-devel] Implement Wizard.Refresh() Message-ID: <20151004192150.GE739@...693...> Hi Benoit, in my current project, I use a (two-step) Wizard where one step contains a CheckBox that determines if the next step is enabled or not (an optional preview). The Wizard does not draw itself new (e.g. the "Next" button should become an "OK" button if the current step suddenly is the last one) auto- matically if I change the value of Wizard[Index].Enabled. The attached patch simply puts the (not yet implemented) Wizard.Refresh() method in charge. The user is expected to call it after making a change to the enabledness of steps. If you say this is OK, I will commit the changes myself. Regards, Tobi -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk -------------- next part -------------- A non-text attachment was scrubbed... Name: Wizard-Refresh.patch Type: text/x-diff Size: 340 bytes Desc: not available URL: From gambas at ...1... Sun Oct 4 21:45:58 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Sun, 4 Oct 2015 21:45:58 +0200 Subject: [Gambas-devel] Implement Wizard.Refresh() In-Reply-To: <20151004192150.GE739@...693...> References: <20151004192150.GE739@...693...> Message-ID: <561181F6.3000502@...1...> Le 04/10/2015 21:21, Tobias Boege a ?crit : > Hi Benoit, > > in my current project, I use a (two-step) Wizard where one step contains a > CheckBox that determines if the next step is enabled or not (an optional > preview). The Wizard does not draw itself new (e.g. the "Next" button should > become an "OK" button if the current step suddenly is the last one) auto- > matically if I change the value of Wizard[Index].Enabled. > > The attached patch simply puts the (not yet implemented) Wizard.Refresh() > method in charge. The user is expected to call it after making a change to > the enabledness of steps. If you say this is OK, I will commit the changes > myself. > > Regards, > Tobi > Refresh is already a method of the inherited Control class, you shouldn't use that name... -- Beno?t Minisini From taboege at ...176... Sun Oct 4 22:05:37 2015 From: taboege at ...176... (Tobias Boege) Date: Sun, 4 Oct 2015 22:05:37 +0200 Subject: [Gambas-devel] Implement Wizard.Refresh() In-Reply-To: <561181F6.3000502@...1...> References: <20151004192150.GE739@...693...> <561181F6.3000502@...1...> Message-ID: <20151004200537.GF739@...693...> On Sun, 04 Oct 2015, Beno??t Minisini wrote: > Le 04/10/2015 21:21, Tobias Boege a ?crit : > > Hi Benoit, > > > > in my current project, I use a (two-step) Wizard where one step contains a > > CheckBox that determines if the next step is enabled or not (an optional > > preview). The Wizard does not draw itself new (e.g. the "Next" button should > > become an "OK" button if the current step suddenly is the last one) auto- > > matically if I change the value of Wizard[Index].Enabled. > > > > The attached patch simply puts the (not yet implemented) Wizard.Refresh() > > method in charge. The user is expected to call it after making a change to > > the enabledness of steps. If you say this is OK, I will commit the changes > > myself. > > > > Regards, > > Tobi > > > > Refresh is already a method of the inherited Control class, you > shouldn't use that name... > ... or call Super.Refresh() in the custom Wizard.Refresh() method? If that is also not good, please propose an alternate name. Your names are usually better than mine. -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk From gambas at ...1... Sun Oct 4 22:30:37 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Sun, 4 Oct 2015 22:30:37 +0200 Subject: [Gambas-devel] Implement Wizard.Refresh() In-Reply-To: <20151004200537.GF739@...693...> References: <20151004192150.GE739@...693...> <561181F6.3000502@...1...> <20151004200537.GF739@...693...> Message-ID: <56118C6D.8030805@...1...> Le 04/10/2015 22:05, Tobias Boege a ?crit : > On Sun, 04 Oct 2015, Beno??t Minisini wrote: >> Le 04/10/2015 21:21, Tobias Boege a ?crit : >>> Hi Benoit, >>> >>> in my current project, I use a (two-step) Wizard where one step contains a >>> CheckBox that determines if the next step is enabled or not (an optional >>> preview). The Wizard does not draw itself new (e.g. the "Next" button should >>> become an "OK" button if the current step suddenly is the last one) auto- >>> matically if I change the value of Wizard[Index].Enabled. >>> >>> The attached patch simply puts the (not yet implemented) Wizard.Refresh() >>> method in charge. The user is expected to call it after making a change to >>> the enabledness of steps. If you say this is OK, I will commit the changes >>> myself. >>> >>> Regards, >>> Tobi >>> >> >> Refresh is already a method of the inherited Control class, you >> shouldn't use that name... >> > > ... or call Super.Refresh() in the custom Wizard.Refresh() method? If that > is also not good, please propose an alternate name. Your names are usually > better than mine. > Let's call it "Update" then... Even if Control.Refresh() is useless for compound controls, it's not a good idea to override it with something not related at all. Regards, -- Beno?t Minisini From taboege at ...176... Mon Oct 5 17:39:30 2015 From: taboege at ...176... (Tobias Boege) Date: Mon, 5 Oct 2015 17:39:30 +0200 Subject: [Gambas-devel] gb.xml.html: MatchFilter() causes infinite loop Message-ID: <20151005153930.GA657@...693...> Hi Adrien, attached is a project with a simple HTML file which causes XmlElement's MatchFilter() method to enter an infinite loop. The project code tests of a given node whether it matches the ".title" selector. To trigger the infinite loop, the node apparently must have a "class" attribute such as class="title nowrap" Since this is my last week of holidays, I thought I'd have some fun and hunt the bug myself. It was in element.cpp:XMLElement_AttributeContains(). Because I didn't understand your string search code there, I rewrote it from scratch. But I don't have many gb.xml projects lying around to test it. It fixes the infinite loop in my current project, though, and delivers the expected results. I will commit the changes to trunk now and would like you to confirm that it doesn't break things elsewhere. Regards, Tobi -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk -------------- next part -------------- A non-text attachment was scrubbed... Name: xml-matchfilter-infinite-loop-0.0.1.tar.gz Type: application/octet-stream Size: 4556 bytes Desc: not available URL: From d4t4full at ...176... Mon Oct 5 17:25:39 2015 From: d4t4full at ...176... (zxMarce) Date: Mon, 5 Oct 2015 08:25:39 -0700 (MST) Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56041E4F.8050806@...176...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> Message-ID: <1444058739325-53761.post@...752...> Beno?t, Still working on this, sorry it took so long; real-life got in the way. As stated, it works with data-retrieving loops. But the IDE's Connection Wizard and at least two data-bound controls (the only ones I tried) fail when filling in their data. Here's a screen shot of a quick-test I made: Just if you cannot see the image or if it fails to upload, the ODBC databound control shows "DataView.TableView_Data.420: Null object" in every field of every row. I had two connections made in the IDE. One uses ODBC against a MSSQL server, the other uses MySQL against a DB I created on localhost. Both have the same table definition, but I limited MySQL to 2 records instead of the 57 MSSQL had (it's even stranger that the ODBC-bound controls "knew" the Result had 57 records, but failed to show any data at all) As you can see, the data-bound control gets the error "DataView.TableView_Data.420: Null object", while MySQL works as expected. I still have to try the MySQL-ODBC connector, but I pre-assume it will fail the same way it does with MSSQL. Hope this helps make data-bound controls work. As usual, if I can help in any way, just say the word. I'll be beautifying ODBC's main.c module next. TIA, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Change-to-gb-db-odbc-to-use-ODBC-Connection-Strings-tp52283p53761.html Sent from the gambas-devel mailing list archive at Nabble.com. From gambas at ...1... Mon Oct 5 18:30:00 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Mon, 5 Oct 2015 18:30:00 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <1444058739325-53761.post@...752...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> Message-ID: <5612A588.3050001@...1...> Le 05/10/2015 17:25, zxMarce a ?crit : > Beno?t, > > Still working on this, sorry it took so long; real-life got in the way. > > As stated, it works with data-retrieving loops. But the IDE's Connection > Wizard and at least two data-bound controls (the only ones I tried) fail > when filling in their data. > > Here's a screen shot of a quick-test I made: > > > > Just if you cannot see the image or if it fails to upload, the ODBC > databound control shows "DataView.TableView_Data.420: Null object" in every > field of every row. > > I had two connections made in the IDE. One uses ODBC against a MSSQL server, > the other uses MySQL against a DB I created on localhost. Both have the same > table definition, but I limited MySQL to 2 records instead of the 57 MSSQL > had (it's even stranger that the ODBC-bound controls "knew" the Result had > 57 records, but failed to show any data at all) > > As you can see, the data-bound control gets the error > "DataView.TableView_Data.420: Null object", while MySQL works as expected. > > I still have to try the MySQL-ODBC connector, but I pre-assume it will fail > the same way it does with MSSQL. > > Hope this helps make data-bound controls work. As usual, if I can help in > any way, just say the word. I'll be beautifying ODBC's main.c module next. > > TIA, > zxMarce. > gb.db.form controls assume that the Result can be seeked at any index. They can't deal with move-forward Result, and I guess the error comes from that. -- Beno?t Minisini From d4t4full at ...176... Fri Oct 9 20:50:01 2015 From: d4t4full at ...176... (ML) Date: Fri, 9 Oct 2015 15:50:01 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <5612A588.3050001@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> Message-ID: <56180C59.2070501@...176...> *On 2015-10-05 13:30, Beno?t Minisini wrote:* > *Le 05/10/2015 17:25, zxMarce a ?crit :* >> Beno?t, >> Still working on this, sorry it took so long; real-life got in the way. >> As stated, it works with data-retrieving loops. But the IDE's >> Connection Wizard and at least two data-bound controls (the only ones >> I tried) fail when filling in their data. >> Here's a screen shot of a quick-test I made: >> >> Just if you cannot see the image or if it fails to upload, the ODBC >> databound control shows "DataView.TableView_Data.420: Null object" in >> every field of every row. >> I had two connections made in the IDE. One uses ODBC against a MSSQL >> server, the other uses MySQL against a DB I created on localhost. >> Both have the same table definition, but I limited MySQL to 2 records >> instead of the 57 MSSQL had (it's even stranger that the ODBC-bound >> controls "knew" the Result had 57 records, but failed to show any >> data at all) >> As you can see, the data-bound control gets the error >> "DataView.TableView_Data.420: Null object", while MySQL works as >> expected. >> I still have to try the MySQL-ODBC connector, but I pre-assume it >> will fail the same way it does with MSSQL. >> Hope this helps make data-bound controls work. As usual, if I can >> help in any way, just say the word. I'll be beautifying ODBC's main.c >> module next. >> TIA, >> zxMarce. > > gb.db.form controls assume that the Result can be seeked at any index. > They can't deal with move-forward Result, and I guess the error comes > from that. Beno?t, I like to think of this as a challenge. And I'll tell you why: If Gambas supports ODBC, then -ideally- there would no more specialized RDBM interfaces to develop as long as the one you want to connect to supports ODBC! That said, I developed what you would call a hack to get a query's resulting RowCount. It took me some time, research, and now I'm bleeding C... I replaced the call to SQLRowCount with a call to a routine that: 1- Makes sure the result has an associated cursor. 2- Tells ODBC not to retrieve data (lightning faster on big result sets) 3- Remembers the "current row index" (i.e: Which is the 'current data row') 4- Makes the cursor jump to the last row and fetches its RowIndex 5- Jumps the cursor back to the remembered 'current row' 6- Tells ODBC to retrieve data again 7- Returns the RowIndex from step 4 8- If for any reason this cannot be done, the routine returns -1 as RowCount, effectively mimicking SQLRowCount() Not tested it thoroughly, but I noticed 2 good things: 1- The red NULL OBJECT errors from the Database Conn Wizard dissappeared, and there were as many rows as needed in its grid. There's no data shown (cells are empty), but the columns and their titles were there. 2- My ODBC test program works as before, no changes noticed, and no errors. Please tell me your thoughts. I'm still researching ODBC to see if I can make it less problematic. Regards, zxMarce. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gambas at ...1... Fri Oct 9 21:19:13 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Fri, 9 Oct 2015 21:19:13 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56180C59.2070501@...176...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> Message-ID: <56181331.8020206@...1...> Le 09/10/2015 20:50, ML a ?crit : > *On 2015-10-05 13:30, Beno?t Minisini wrote:* >> *Le 05/10/2015 17:25, zxMarce a ?crit :* >>> Beno?t, >>> Still working on this, sorry it took so long; real-life got in the way. >>> As stated, it works with data-retrieving loops. But the IDE's >>> Connection Wizard and at least two data-bound controls (the only ones >>> I tried) fail when filling in their data. >>> Here's a screen shot of a quick-test I made: >>> >>> Just if you cannot see the image or if it fails to upload, the ODBC >>> databound control shows "DataView.TableView_Data.420: Null object" in >>> every field of every row. >>> I had two connections made in the IDE. One uses ODBC against a MSSQL >>> server, the other uses MySQL against a DB I created on localhost. >>> Both have the same table definition, but I limited MySQL to 2 records >>> instead of the 57 MSSQL had (it's even stranger that the ODBC-bound >>> controls "knew" the Result had 57 records, but failed to show any >>> data at all) >>> As you can see, the data-bound control gets the error >>> "DataView.TableView_Data.420: Null object", while MySQL works as >>> expected. >>> I still have to try the MySQL-ODBC connector, but I pre-assume it >>> will fail the same way it does with MSSQL. >>> Hope this helps make data-bound controls work. As usual, if I can >>> help in any way, just say the word. I'll be beautifying ODBC's main.c >>> module next. >>> TIA, >>> zxMarce. >> >> gb.db.form controls assume that the Result can be seeked at any index. >> They can't deal with move-forward Result, and I guess the error comes >> from that. > > Beno?t, > I like to think of this as a challenge. And I'll tell you why: If Gambas > supports ODBC, then -ideally- there would no more specialized RDBM > interfaces to develop as long as the one you want to connect to supports > ODBC! > That said, I developed what you would call a hack to get a query's > resulting RowCount. It took me some time, research, and now I'm bleeding > C... > > I replaced the call to SQLRowCount with a call to a routine that: > > 1- Makes sure the result has an associated cursor. > 2- Tells ODBC not to retrieve data (lightning faster on big result sets) > 3- Remembers the "current row index" (i.e: Which is the 'current data > row') > 4- Makes the cursor jump to the last row and fetches its RowIndex > 5- Jumps the cursor back to the remembered 'current row' > 6- Tells ODBC to retrieve data again > 7- Returns the RowIndex from step 4 > 8- If for any reason this cannot be done, the routine returns -1 as > RowCount, effectively mimicking SQLRowCount() > > Not tested it thoroughly, but I noticed 2 good things: > > 1- The red NULL OBJECT errors from the Database Conn Wizard > dissappeared, and there were as many rows as needed in its grid. There's > no data shown (cells are empty), but the columns and their titles were > there. > 2- My ODBC test program works as before, no changes noticed, and no > errors. > > Please tell me your thoughts. I'm still researching ODBC to see if I can > make it less problematic. > Regards, > zxMarce. > The problem is that I don't know what ODBC really does. Other database backends get the entire result contents in memory, or act as if. This is the reason why Gambas database drivers can get the row count and jump to any row from its index without problem. Apparently ODBC does not load the entire result in memory (you get records one by one), and this has to be simulated somewhere: at the Gambas database driver level, at the gb.db component level, or in gb.db.form. It's what you have done to get the row count. (I don't understand why SQLRowCount() does not already do that). I guess you compute the row count once and cache it in the query_init() function? Now you have to make query_fill() return the row data for any index, if you want gb.db.form to work out of the box. But I don't think it is possible in all cases - maybe some ODBC driver are really forward-only. In that case, it's the gb.db.form component that must be modified (I don't want gb.db to simulate that, because it may be interesting in some cases to have forward-only result, it is faster and use less memory). As gb.db.form accesses tables by chunk of 256 rows (see the source code of DataTable in gb.db.form), maybe he could maintain a cache for the 256 rows contents as soon as he knows that the Result is forward-only. He would know that for sure if the Result count is -1. So you should compute the row count in the ODBC database driver only if you are sure that you can access a result row randomly. Regards, -- Beno?t Minisini From d4t4full at ...176... Sat Oct 10 03:03:19 2015 From: d4t4full at ...176... (ML) Date: Fri, 9 Oct 2015 22:03:19 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56181331.8020206@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> Message-ID: <561863D7.9060905@...176...> *On 10/09/2015 04:19 PM, Beno?t Minisini wrote:* > *Le 09/10/2015 20:50, ML a ?crit : * >> *On 2015-10-05 13:30, Beno?t Minisini wrote: * >>> *Le 05/10/2015 17:25, zxMarce a ?crit : * >>>> Beno?t, >>>> Still working on this, sorry it took so long; real-life got in the way. >>>> As stated, it works with data-retrieving loops. But the IDE's >>>> Connection Wizard and at least two data-bound controls (the only >>>> ones I tried) fail when filling in their data. >>>> Here's a screen shot of a quick-test I made: >>>> >>>> Just if you cannot see the image or if it fails to upload, the ODBC >>>> databound control shows "DataView.TableView_Data.420: Null object" >>>> in every field of every row. >>>> I had two connections made in the IDE. One uses ODBC against a >>>> MSSQL server, the other uses MySQL against a DB I created on localhost. >>>> Both have the same table definition, but I limited MySQL to 2 >>>> records instead of the 57 MSSQL had (it's even stranger that the >>>> ODBC-bound controls "knew" the Result had 57 records, but failed to >>>> show any data at all). >>>> As you can see, the data-bound control gets the error >>>> "DataView.TableView_Data.420: Null object", while MySQL works as >>>> expected. >>>> I still have to try the MySQL-ODBC connector, but I pre-assume it >>>> will fail the same way it does with MSSQL. >>>> Hope this helps make data-bound controls work. As usual, if I can >>>> help in any way, just say the word. I'll be beautifying ODBC's >>>> main.c module next. >>>> TIA, >>>> zxMarce. >>> >>> gb.db.form controls assume that the Result can be seeked at any index. >>> They can't deal with move-forward Result, and I guess the error >>> comes from that. >> >> Beno?t, >> I like to think of this as a challenge. And I'll tell you why: If >> Gambas supports ODBC, then -ideally- there would no more specialized >> RDBMS interfaces to develop as long as the one you want to connect to >> supports ODBC! >> That said, I developed what you would call a hack to get a query's >> resulting RowCount. It took me some time, research, and now I'm >> bleeding C... >> >> I replaced the call to SQLRowCount with a call to a routine that: >> >> 1- Makes sure the result has an associated cursor. >> 2- Tells ODBC not to retrieve data (lightning faster on big result >> sets) >> 3- Remembers the "current row index" (i.e: Which is the 'current >> data row') >> 4- Makes the cursor jump to the last row and fetches its RowIndex >> 5- Jumps the cursor back to the remembered 'current row' >> 6- Tells ODBC to retrieve data again >> 7- Returns the RowIndex from step 4 >> 8- If for any reason this cannot be done, the routine returns -1 >> as RowCount, effectively mimicking SQLRowCount() >> >> Not tested it thoroughly, but I noticed 2 good things: >> >> 1- The red NULL OBJECT errors from the Database Conn Wizard >> dissappeared, and there were as many rows as needed in its grid. >> There's no data shown (cells are empty), but the columns and their >> titles were there. >> 2- My ODBC test program works as before, no changes noticed, and >> no errors. >> >> Please tell me your thoughts. I'm still researching ODBC to see if I >> can make it less problematic. >> Regards, >> zxMarce. > The problem is that I don't know what ODBC really does. > Other database backends get the entire result contents in memory, or > act as if. This is the reason why Gambas database drivers can get the > row count and jump to any row from its index without problem. > Apparently ODBC does not load the entire result in memory (you get > records one by one), and this has to be simulated somewhere: at the > Gambas database driver level, at the gb.db component level, or in > gb.db.form. > It's what you have done to get the row count. (I don't understand why > SQLRowCount() does not already do that). > I guess you compute the row count once and cache it in the > query_init() function? > Now you have to make query_fill() return the row data for any index, > if you want gb.db.form to work out of the box. > But I don't think it is possible in all cases - maybe some ODBC driver > are really forward-only. > In that case, it's the gb.db.form component that must be modified (I > don't want gb.db to simulate that, because it may be interesting in > some cases to have forward-only result, it is faster and use less memory). > As gb.db.form accesses tables by chunk of 256 rows (see the source > code of DataTable in gb.db.form), maybe he could maintain a cache for > the 256 rows contents as soon as he knows that the Result is forward-only. > He would know that for sure if the Result count is -1. So you should > compute the row count in the ODBC database driver only if you are sure > that you can access a result row randomly. > Regards, Beno?t, Regarding ODBC in general: I'm no ODBC expert, but from what I read ODBC (Open DataBase Connectivity) is an open ISO/IEC standard for middleware that maps and routes standard SQL queries to a freaking wide variety of RDBMS systems. Some of these RDBMSs are IBM's DB2, MySQL, MSSql, Oracle and many others. It does so by using dynamically loaded drivers. By themselves, unixODBC, iODBC, MSODBC, etc are pretty much useless, as they need a driver to connect and send/receive data to/from the RDBMS. ODBC -in any supported processing platform (Win, Linux, Mac, RaspberryPi, etc)- has a Driver Manager. You can also specify the driver and parameters to connect to a RDBMS in a variety of ways (user/system INI files, connection strings, and even mixed modes), and then ODBC presents the application with a standard set of calls to achieve practically whatever you need on the RDBMS. Then, ODBC and the selected driver map these calls to requests that the RDBMS understand and process. Lastly, ODBC and the driver reinterpret what the RDBMS responds back to the app in a standardized way. The whole idea is, from the app point of view, no (or few) code changes to get the same results no matter the RDBMS or processing platform your app uses. The only problem you might encounter is an RDBMS that does not have feature X and your program relies on that feature. In these cases, the ODBC/Driver couple may just respond with an error, or may even go to some extent to emulate the feature in software. But even so I think it is worth supporting it. So, as I said, as long as your preferred RDBMS has an available ODBC driver, you should only need to use it through ODBC and if you switch to another RDBMS (MySQL, MSSql, Oracle, DB2, etc), you should NOT have to touch your app. Just change the driver in the connection string or INI file(s), and you're all set. Regarding record fetching: You're correct assuming ODBC fetches records one at a time. You can also fetch a block of (consecutive) rows at any given time. Regarding SQLRowCount(): The issue with this call is that it is documented as returning records affected by INSERT, MERGE, DELETE, or UPDATE queries only. Any SELECT query will not have a record count. I have a slight idea why (see next paragraph on concurrency). And, apparently, the consortium that rules ODBC does not like you to have the whole data chunk in memory (my guess). ODBC is designed so you get data sequentially, and stop when ODBC tells you back "NO (more) DATA". But not all is lost. ODBC gives you cursors (some drivers implement more cursor functionality than others, though). Cursors are like C pointers. They keep track of rows in a returned rowset. You can use cursors to seek rows, which is what I did. Problem is, cursors MAY change as data is added/removed (by other users of the RDBMS, although I'm not 100% sure of this), and therefore your RowCount, if cached, may not be reliable. This may be one of the problems the designers of ODBC had to take into account when making SQLRowCount() not return a count for SELECTs: Most modern RDBMSs are multiuser, and more than one user may be working at the same time in the same table(s); conflicts should be taken into account! Regarding gb.db.form: Wow... This may be over my head, but I think the approach I took is OK and row count is reliable, at least for the time the query was run. I'll try to see if I can make query_fill() fetch any row. Regards, -------------- next part -------------- An HTML attachment was scrubbed... URL: From gambas at ...1... Sat Oct 10 03:31:54 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Sat, 10 Oct 2015 03:31:54 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <561863D7.9060905@...176...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <561863D7.9060905@...176...> Message-ID: <56186A8A.3060407@...1...> Le 10/10/2015 03:03, ML a ?crit : > > Regarding ODBC in general: > I'm no ODBC expert, but from what I read ODBC (Open DataBase > Connectivity) is an open ISO/IEC standard for middleware that maps and > routes standard SQL queries to a freaking wide variety of RDBMS systems. > Some of these RDBMSs are IBM's DB2, MySQL, MSSql, Oracle and many > others. It does so by using dynamically loaded drivers. By themselves, > unixODBC, iODBC, MSODBC, etc are pretty much useless, as they need a > driver to connect and send/receive data to/from the RDBMS. > > ODBC -in any supported processing platform (Win, Linux, Mac, > RaspberryPi, etc)- has a Driver Manager. You can also specify the driver > and parameters to connect to a RDBMS in a variety of ways (user/system > INI files, connection strings, and even mixed modes), and then ODBC > presents the application with a standard set of calls to achieve > practically whatever you need on the RDBMS. Then, ODBC and the selected > driver map these calls to requests that the RDBMS understand and > process. Lastly, ODBC and the driver reinterpret what the RDBMS responds > back to the app in a standardized way. > > The whole idea is, from the app point of view, no (or few) code changes > to get the same results no matter the RDBMS or processing platform your > app uses. The only problem you might encounter is an RDBMS that does not > have feature X and your program relies on that feature. In these cases, > the ODBC/Driver couple may just respond with an error, or may even go to > some extent to emulate the feature in software. But even so I think it > is worth supporting it. > > So, as I said, as long as your preferred RDBMS has an available ODBC > driver, you should only need to use it through ODBC and if you switch to > another RDBMS (MySQL, MSSql, Oracle, DB2, etc), you should NOT have to > touch your app. Just change the driver in the connection string or INI > file(s), and you're all set. > > > Regarding record fetching: > You're correct assuming ODBC fetches records one at a time. You can also > fetch a block of (consecutive) rows at any given time. > > > Regarding SQLRowCount(): > The issue with this call is that it is documented as returning records > affected by INSERT, MERGE, DELETE, or UPDATE queries only. Any SELECT > query will not have a record count. I have a slight idea why (see next > paragraph on concurrency). And, apparently, the consortium that rules > ODBC does not like you to have the whole data chunk in memory (my > guess). ODBC is designed so you get data sequentially, and stop when > ODBC tells you back "NO (more) DATA". OK. I thought, because of its name and the way it was used in the driver, that SQLRowCount() was returning the number of rows in a query result. > > But not all is lost. ODBC gives you cursors (some drivers implement more > cursor functionality than others, though). Cursors are like C pointers. > They keep track of rows in a returned rowset. You can use cursors to > seek rows, which is what I did. Problem is, cursors MAY change as data > is added/removed (by other users of the RDBMS, although I'm not 100% > sure of this), and therefore your RowCount, if cached, may not be > reliable. This may be one of the problems the designers of ODBC had to > take into account when making SQLRowCount() not return a count for > SELECTs: Most modern RDBMSs are multiuser, and more than one user may be > working at the same time in the same table(s); conflicts should be taken > into account! > > > Regarding gb.db.form: > Wow... This may be over my head, but I think the approach I took is OK > and row count is reliable, at least for the time the query was run. I'll > try to see if I can make query_fill() fetch any row. > > Regards, > As soon as a query is issued, the query result cannot change while you look at it, even if it is returned row by row. Otherwise it would make SQL useless. In other words, a query must be an instant view of part of a database. You won't see record deletions or insertions done after the query. So if you emit a query, and move the cursor to the last row, the computed number of rows must be valid until you release the query result. Regards, -- Beno?t Minisini From d4t4full at ...176... Sat Oct 10 05:05:27 2015 From: d4t4full at ...176... (ML) Date: Sat, 10 Oct 2015 00:05:27 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56186A8A.3060407@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <561863D7.9060905@...176...> <56186A8A.3060407@...1...> Message-ID: <56188077.3070601@...176...> On 10/09/2015 10:31 PM, Beno?t Minisini wrote: > Le 10/10/2015 03:03, ML a ?crit : >> Regarding ODBC in general: >> I'm no ODBC expert, but from what I read ODBC (Open DataBase >> Connectivity) is an open ISO/IEC standard for middleware that maps >> and routes standard SQL queries to a freaking wide variety of RDBMS >> systems. Some of these RDBMSs are IBM's DB2, MySQL, MSSql, Oracle and >> many others. It does so by using dynamically loaded drivers. By >> themselves, unixODBC, iODBC, MSODBC, etc are pretty much useless, as >> they need a driver to connect and send/receive data to/from the RDBMS. >> >> ODBC -in any supported processing platform (Win, Linux, Mac, >> RaspberryPi, etc)- has a Driver Manager. You can also specify the >> driver and parameters to connect to a RDBMS in a variety of ways >> (user/system INI files, connection strings, and even mixed modes), >> and then ODBC presents the application with a standard set of calls >> to achieve practically whatever you need on the RDBMS. Then, ODBC and >> the selected driver map these calls to requests that the RDBMS >> understand and process. Lastly, ODBC and the driver reinterpret what >> the RDBMS responds back to the app in a standardized way. >> >> The whole idea is, from the app point of view, no (or few) code >> changes to get the same results no matter the RDBMS or processing >> platform your app uses. The only problem you might encounter is an >> RDBMS that does not have feature X and your program relies on that >> feature. In these cases, the ODBC/Driver couple may just respond with >> an error, or may even go to some extent to emulate the feature in >> software. But even so I think it is worth supporting it. >> >> So, as I said, as long as your preferred RDBMS has an available ODBC >> driver, you should only need to use it through ODBC and if you switch >> to another RDBMS (MySQL, MSSql, Oracle, DB2, etc), you should NOT >> have to touch your app. Just change the driver in the connection >> string or INI file(s), and you're all set. >> >> >> Regarding record fetching: >> You're correct assuming ODBC fetches records one at a time. You can >> also fetch a block of (consecutive) rows at any given time. >> >> >> Regarding SQLRowCount(): >> The issue with this call is that it is documented as returning >> records affected by INSERT, MERGE, DELETE, or UPDATE queries only. >> Any SELECT >> query will not have a record count. I have a slight idea why (see >> next paragraph on concurrency). And, apparently, the consortium that >> rules >> ODBC does not like you to have the whole data chunk in memory (my >> guess). ODBC is designed so you get data sequentially, and stop when >> ODBC tells you back "NO (more) DATA". > OK. I thought, because of its name and the way it was used in the > driver, that SQLRowCount() was returning the number of rows in a query > result. >> But not all is lost. ODBC gives you cursors (some drivers implement >> more cursor functionality than others, though). Cursors are like C >> pointers. They keep track of rows in a returned rowset. You can use >> cursors to seek rows, which is what I did. Problem is, cursors MAY >> change as data is added/removed (by other users of the RDBMS, >> although I'm not 100% sure of this), and therefore your RowCount, if >> cached, may not be reliable. This may be one of the problems the >> designers of ODBC had to take into account when making SQLRowCount() >> not return a count for SELECTs: Most modern RDBMSs are multiuser, and >> more than one user may be working at the same time in the same >> table(s); conflicts should be taken into account! >> >> >> Regarding gb.db.form: >> Wow... This may be over my head, but I think the approach I took is >> OK and row count is reliable, at least for the time the query was >> run. I'll >> try to see if I can make query_fill() fetch any row. >> >> Regards, >> > As soon as a query is issued, the query result cannot change while you > look at it, even if it is returned row by row. Otherwise it would make > SQL useless. > In other words, a query must be an instant view of part of a database. > You won't see record deletions or insertions done after the query. > So if you emit a query, and move the cursor to the last row, the > computed number of rows must be valid until you release the query result. > Regards, Beno?t, So, long story short, we both agree. Neither do I know why the function name (SQLRowsChanged would have been more useful)! All I know is -for example- *this * (IBM/DB2) and *this* (Easysoft ODBC). There are others (like Microsoft), but they say the same. Easysoft helps more by saying "Most ODBC drivers only return a meaningful number from SQLRowCount when you execute row changing SQL e.g. updates, deletes, inserts. For selects most ODBC drivers return -1". I also was lost and confused by the function call name when I saw it in the Gambas driver, but I remembered the experience from MSADO in VB6. Under MSADO, row counts were mostly -1. Only forward-only static cursors made VB's Recordsets (Gambas' Results) return a meaningful count. Lastly, I think I did not make myself clear regarding concurrent changes. I wanted to say that if somebody else adds a row, you will not see it (so, we DO agree), but at the same time, strictly speaking, your row count will be one less than the current, absolute, row count in the database. On the other hand, I don't know what would happen if you seek to a row that has been deleted. Either an informative message or error, I presume. Regards, -------------- next part -------------- An HTML attachment was scrubbed... URL: From d4t4full at ...176... Fri Oct 16 15:39:38 2015 From: d4t4full at ...176... (ML) Date: Fri, 16 Oct 2015 10:39:38 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56181331.8020206@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> Message-ID: <5620FE1A.4040704@...176...> *On 2015-10-09 16:19, Beno?t Minisini wrote:* > Le 09/10/2015 20:50, ML a ?crit : >> *On 2015-10-05 13:30, Beno?t Minisini wrote:* >>> *Le 05/10/2015 17:25, zxMarce a ?crit :* >>>> Beno?t, >>>> Still working on this, sorry it took so long; real-life got in the way. >>>> As stated, it works with data-retrieving loops. But the IDE's >>>> Connection Wizard and at least two data-bound controls (the only >>>> ones I tried) fail when filling in their data. >>>> Just if you cannot see the image or if it fails to upload, the ODBC >>>> databound control shows "DataView.TableView_Data.420: Null object" >>>> in every field of every row. >>>> I had two connections made in the IDE. One uses ODBC against a >>>> MSSQL server, the other uses MySQL against a DB I created on localhost. >>>> Both have the same table definition, but I limited MySQL to 2 >>>> records instead of the 57 MSSQL had (it's even stranger that the >>>> ODBC-bound controls "knew" the Result had 57 records, but failed to >>>> show any data at all) >>>> As you can see, the data-bound control gets the error >>>> "DataView.TableView_Data.420: Null object", while MySQL works as >>>> expected. >>>> I still have to try the MySQL-ODBC connector, but I pre-assume it >>>> will fail the same way it does with MSSQL. >>>> Hope this helps make data-bound controls work. As usual, if I can >>>> help in any way, just say the word. I'll be beautifying ODBC's >>>> main.c module next. >>>> TIA, >>>> zxMarce. >>> gb.db.form controls assume that the Result can be seeked at any index. >>> They can't deal with move-forward Result, and I guess the error >>> comes from that. >> Beno?t, >> I like to think of this as a challenge. And I'll tell you why: If >> Gambas supports ODBC, then -ideally- there would no more specialized >> RDBM interfaces to develop as long as the one you want to connect to >> supports ODBC! >> That said, I developed what you would call a hack to get a query's >> resulting RowCount. It took me some time, research, and now I'm >> bleeding C... >> I replaced the call to SQLRowCount with a call to a routine that: >> 1- Makes sure the result has an associated cursor. >> 2- Tells ODBC not to retrieve data (lightning faster on big result >> sets) >> 3- Remembers the "current row index" (i.e: Which is the 'current >> data row') >> 4- Makes the cursor jump to the last row and fetches its RowIndex >> 5- Jumps the cursor back to the remembered 'current row' >> 6- Tells ODBC to retrieve data again >> 7- Returns the RowIndex from step 4 >> 8- If for any reason this cannot be done, the routine returns -1 >> as RowCount, effectively mimicking SQLRowCount() >> Not tested it thoroughly, but I noticed 2 good things: >> 1- The red NULL OBJECT errors from the Database Conn Wizard >> dissappeared, and there were as many rows as needed in its grid. >> There's no data shown (cells are empty), but the columns and their >> titles were there. >> 2- My ODBC test program works as before, no changes noticed, and >> no errors. >> Please tell me your thoughts. I'm still researching ODBC to see if I >> can make it less problematic. >> Regards, >> zxMarce. > The problem is that I don't know what ODBC really does. > Other database backends get the entire result contents in memory, or > act as if. This is the reason why Gambas database drivers can get the > row count and jump to any row from its index without problem. > Apparently ODBC does not load the entire result in memory (you get > records one by one), and this has to be simulated somewhere: at the > Gambas database driver level, at the gb.db component level, or in > gb.db.form. > It's what you have done to get the row count. (I don't understand why > SQLRowCount() does not already do that). > I guess you compute the row count once and cache it in the > query_init() function? > Now you have to make query_fill() return the row data for any index, > if you want gb.db.form to work out of the box. > But I don't think it is possible in all cases - maybe some ODBC driver > are really forward-only. > In that case, it's the gb.db.form component that must be modified (I > don't want gb.db to simulate that, because it may be interesting in > some cases to have forward-only result, it is faster and use less memory). > As gb.db.form accesses tables by chunk of 256 rows (see the source > code of DataTable in gb.db.form), maybe he could maintain a cache for > the 256 rows contents as soon as he knows that the Result is forward-only. > He would know that for sure if the Result count is -1. So you should > compute the row count in the ODBC database driver only if you are sure > that you can access a result row randomly. > Regards, Beno?t, It took some time, but I think I have the real reason why the Wizard does not work: It returned to the red rows with error after getting an appropriate record count. The problem seems to be that the SQL query is being add a non-SQL-standard clause, "LIMIT 256". This may have something to do with the row cache you mentioned. Unfortunately, the LIMIT clause is a MySQL clause (don't know if other servers support it), it does not exist on standard SQL. There are ways (read "hacks") to get a specific 'subrowset' from a given rowset, but they depend on SQL revisions; for example, MSSQL 2005 and 2008 are the hardest, and is easier in MSSQL 2012. There's actually no one-solution-fits-all way. I think the approach to retrieve a subset of rows from a query should be different, but I don't know how that would be feasible on gb.db.form. So, in short, now ODBC returns a Result.Count if the server supports scrollable cursors (most RDMS do), but that does not help the Connection Wizard. Regards, zxMarce. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gambas at ...1... Fri Oct 16 18:26:12 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Fri, 16 Oct 2015 18:26:12 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <5620FE1A.4040704@...176...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <5620FE1A.4040704@...176...> Message-ID: <56212524.5010105@...1...> Le 16/10/2015 15:39, ML a ?crit : > Beno?t, > > It took some time, but I think I have the real reason why the Wizard > does not work: It returned to the red rows with error after getting an > appropriate record count. > > The problem seems to be that the SQL query is being add a > non-SQL-standard clause, "LIMIT 256". This may have something to do with > the row cache you mentioned. > Unfortunately, the LIMIT clause is a MySQL clause (don't know if other > servers support it), it does not exist on standard SQL. > There are ways (read "hacks") to get a specific 'subrowset' from a given > rowset, but they depend on SQL revisions; for example, MSSQL 2005 and > 2008 are the hardest, and is easier in MSSQL 2012. > > There's actually no one-solution-fits-all way. I think the approach to > retrieve a subset of rows from a query should be different, but I don't > know how that would be feasible on gb.db.form. > > So, in short, now ODBC returns a Result.Count if the server supports > scrollable cursors (most RDMS do), but that does not help the Connection > Wizard. > > Regards, > zxMarce. > LIMIT exists in MySQL, PostgreSQL, and SQLite. With, of course, some differences in the syntax. There is no such thing like real "standard SQL clause", or "standard SQL" in the real word. There is as many differences between two SQL database servers than between the HTML implementation of two web browsers! SQL sucks. :-) But I think that feature must be present in all SQL database systems. The gb.db component has a standard way for specifying that you want to limit your result set: DB.Limit(256).Exec(...) That way, it's possible to adapt that feature to gb.db.odbc. But we must find a way for the ODBC driver to know how to specify the result limit. Do you think it's possible with ODBC to make the difference, following that: https://en.wikipedia.org/wiki/Select_%28SQL%29#Result_limits ? Regards, -- Beno?t Minisini From gambas at ...1... Fri Oct 16 18:35:22 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Fri, 16 Oct 2015 18:35:22 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <56212524.5010105@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <5620FE1A.4040704@...176...> <56212524.5010105@...1...> Message-ID: <5621274A.5060605@...1...> Le 16/10/2015 18:26, Beno?t Minisini a ?crit : > Le 16/10/2015 15:39, ML a ?crit : >> Beno?t, >> >> It took some time, but I think I have the real reason why the Wizard >> does not work: It returned to the red rows with error after getting an >> appropriate record count. >> >> The problem seems to be that the SQL query is being add a >> non-SQL-standard clause, "LIMIT 256". This may have something to do with >> the row cache you mentioned. >> Unfortunately, the LIMIT clause is a MySQL clause (don't know if other >> servers support it), it does not exist on standard SQL. >> There are ways (read "hacks") to get a specific 'subrowset' from a given >> rowset, but they depend on SQL revisions; for example, MSSQL 2005 and >> 2008 are the hardest, and is easier in MSSQL 2012. >> >> There's actually no one-solution-fits-all way. I think the approach to >> retrieve a subset of rows from a query should be different, but I don't >> know how that would be feasible on gb.db.form. >> >> So, in short, now ODBC returns a Result.Count if the server supports >> scrollable cursors (most RDMS do), but that does not help the Connection >> Wizard. >> >> Regards, >> zxMarce. >> > > LIMIT exists in MySQL, PostgreSQL, and SQLite. With, of course, some > differences in the syntax. > > There is no such thing like real "standard SQL clause", or "standard > SQL" in the real word. There is as many differences between two SQL > database servers than between the HTML implementation of two web browsers! > > SQL sucks. :-) > > But I think that feature must be present in all SQL database systems. > > The gb.db component has a standard way for specifying that you want to > limit your result set: > > DB.Limit(256).Exec(...) > > That way, it's possible to adapt that feature to gb.db.odbc. But we must > find a way for the ODBC driver to know how to specify the result limit. > > Do you think it's possible with ODBC to make the difference, following > that: https://en.wikipedia.org/wiki/Select_%28SQL%29#Result_limits ? > > Regards, > ...it should be possible if you can know with ODBC which database server you connect to, and its version. Then you will be able to do the job ODBC should do for you transparently if ODBC has been something useful and intelligently designed. :-) If you can tell me how to detect that, I will modify gb.db and write the big switch code to use the good "limit" syntax according to the database server in use. Regards, -- Beno?t Minisini From gambas at ...1... Fri Oct 16 18:37:33 2015 From: gambas at ...1... (=?UTF-8?Q?Beno=c3=aet_Minisini?=) Date: Fri, 16 Oct 2015 18:37:33 +0200 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <5621274A.5060605@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <5620FE1A.4040704@...176...> <56212524.5010105@...1...> <5621274A.5060605@...1...> Message-ID: <562127CD.6000108@...1...> Le 16/10/2015 18:35, Beno?t Minisini a ?crit : >> Do you think it's possible with ODBC to make the difference, following >> that: https://en.wikipedia.org/wiki/Select_%28SQL%29#Result_limits ? >> Another useful link: http://stackoverflow.com/questions/1528604/how-universal-is-the-limit-statement-in-sql -- Beno?t Minisini From d4t4full at ...176... Fri Oct 16 19:20:06 2015 From: d4t4full at ...176... (ML) Date: Fri, 16 Oct 2015 14:20:06 -0300 Subject: [Gambas-devel] Change to gb.db.odbc to use ODBC Connection Strings. In-Reply-To: <5621274A.5060605@...1...> References: <55DF51B8.6060706@...1...> <55F6EABB.4050804@...176...> <55F8B6BB.6070302@...1...> <55F97E63.5030603@...176...> <55F9889D.3080409@...1...> <55F9B7AF.6070403@...176...> <55F9C8D9.4030809@...1...> <1442840922852-53317.post@...752...> <5603427E.5090707@...1...> <56041E4F.8050806@...176...> <1444058739325-53761.post@...752...> <5612A588.3050001@...1...> <56180C59.2070501@...176...> <56181331.8020206@...1...> <5620FE1A.4040704@...176...> <56212524.5010105@...1...> <5621274A.5060605@...1...> Message-ID: <562131C6.60604@...176...> *On 2015-10-16 13:35, Beno?t Minisini wrote:* > *Le 16/10/2015 18:26, Beno?t Minisini a ?crit :* >> *Le 16/10/2015 15:39, ML a ?crit :* >>> Beno?t, >>> It took some time, but I think I have the real reason why the Wizard >>> does not work: It returned to the red rows with error after getting >>> an appropriate record count. >>> The problem seems to be that the SQL query is being add a >>> non-SQL-standard clause, "LIMIT 256". This may have something to do >>> with the row cache you mentioned. >>> Unfortunately, the LIMIT clause is a MySQL clause (don't know if >>> other servers support it), it does not exist on standard SQL. >>> There are ways (read "hacks") to get a specific 'subrowset' from a >>> given rowset, but they depend on SQL revisions; for example, MSSQL >>> 2005 and 2008 are the hardest, and is easier in MSSQL 2012. >>> There's actually no one-solution-fits-all way. I think the approach >>> to retrieve a subset of rows from a query should be different, but I >>> don't know how that would be feasible on gb.db.form. >>> So, in short, now ODBC returns a Result.Count if the server supports >>> scrollable cursors (most RDMS do), but that does not help the >>> Connection Wizard. >>> Regards, >>> zxMarce. >> >> LIMIT exists in MySQL, PostgreSQL, and SQLite. With, of course, some >> differences in the syntax. >> There is no such thing like real "standard SQL clause", or "standard >> SQL" in the real word. There is as many differences between two SQL >> database servers than between the HTML implementation of two web >> browsers! >> SQL sucks. :-) >> But I think that feature must be present in all SQL database systems. >> The gb.db component has a standard way for specifying that you want >> to limit your result set: >> DB.Limit(256).Exec(...) >> That way, it's possible to adapt that feature to gb.db.odbc. But we >> must find a way for the ODBC driver to know how to specify the result >> limit. >> Do you think it's possible with ODBC to make the difference, >> following that: >> https://en.wikipedia.org/wiki/Select_%28SQL%29#Result_limits ? >> Regards, > > ...it should be possible if you can know with ODBC which database > server you connect to, and its version. > Then you will be able to do the job ODBC should do for you > transparently if ODBC has been something useful and intelligently > designed. :-) > If you can tell me how to detect that, I will modify gb.db and write > the big switch code to use the good "limit" syntax according to the > database server in use. > Regards, Beno?t, Well, I was speaking about SQL-92 and the like... ODBC has a way to fetch a block of rows. You can set how many. Then, it will retrieve (up to) that many rows from the rowset. You can, IIRC, also specify the starting offset. All this, of course, as long as the Driver or RDBM provides scrollable cursors. Mind you, I never tried a row-block fetch, and it will be a demanding 'challenge' to overcome. My guess is that it will take some time. Please tell me how can gb.db.odbc know whether someone used the DB.Limit() property, so I can make the next fetch a row-block fetch, and how to recognize a "go back to retrieving 1 row at a time" mode change. Related to that, one of the things that still escape me is which calls in gb.db map to which (block of) calls in gb.db.odbc. That, and which high level Gambas calls map to which gb.db (block of) calls. Regards, -------------- next part -------------- An HTML attachment was scrubbed... URL: From d4t4full at ...176... Wed Oct 21 12:53:08 2015 From: d4t4full at ...176... (zxMarce) Date: Wed, 21 Oct 2015 03:53:08 -0700 (MST) Subject: [Gambas-devel] Raspberry Pi & Gambas. Message-ID: <1445424788317-54165.post@...752...> Hi, Using the wiringPi 2 library , a C program can fiddle with the I/O pins in (I think) all Raspberry Pi (RasPi for short) models. A C program could also set "triggers" so that the program is "interrupted" whenever pin(s) change state (low-to-high or high-to-low). The first part, twiddling with output pins and reading their state is achievable in Gambas with help of EXTERN calls. Unfortunately, the interrupt part does not play along with Gambas. Some time ago (coupla months) I read why, but the reason why was over my head. Since many Gambas components are actually C adapting and rerouting things back and forth between low-level drivers and stuff to/from BASIC code (yes, I know I'm oversimplifying), I wonder if a RasPi-specific component could be developed that take advantage of the interrupts in form of Gambas Events. Point is, this component would work and be meaningful exclusively on the RasPi and not useable on -say- x86 for example. Is there any way a component can be disabled based on machine architecture? This would be the hardware-equivalent to disabling gb.qt5 on Ubuntu, for example. I have a PDF paper explaining how to create a Gambas component in C. I'm afraid it does not cover events, though. If a simple explanation is given on how to raise Events from C code, I may risk my ar$e and try to do it if the platform restriction is doable. TIA, zxMarce. -- View this message in context: http://gambas.8142.n7.nabble.com/Raspberry-Pi-Gambas-tp54165.html Sent from the gambas-devel mailing list archive at Nabble.com. From taboege at ...176... Wed Oct 21 18:40:05 2015 From: taboege at ...176... (Tobias Boege) Date: Wed, 21 Oct 2015 18:40:05 +0200 Subject: [Gambas-devel] Raspberry Pi & Gambas. In-Reply-To: <1445424788317-54165.post@...752...> References: <1445424788317-54165.post@...752...> Message-ID: <20151021164005.GA659@...693...> On Wed, 21 Oct 2015, zxMarce wrote: > Hi, > > Using the wiringPi 2 library , a C program can > fiddle with the I/O pins in (I think) all Raspberry Pi (RasPi for short) > models. A C program could also set "triggers" so that the program is > "interrupted" whenever pin(s) change state (low-to-high or high-to-low). > > The first part, twiddling with output pins and reading their state is > achievable in Gambas with help of EXTERN calls. Unfortunately, the interrupt > part does not play along with Gambas. Some time ago (coupla months) I read > why, but the reason why was over my head. > > Since many Gambas components are actually C adapting and rerouting things > back and forth between low-level drivers and stuff to/from BASIC code (yes, > I know I'm oversimplifying), I wonder if a RasPi-specific component could be > developed that take advantage of the interrupts in form of Gambas Events. > Point is, this component would work and be meaningful exclusively on the > RasPi and not useable on -say- x86 for example. Is there any way a component > can be disabled based on machine architecture? This would be the > hardware-equivalent to disabling gb.qt5 on Ubuntu, for example. > You should not decide if the component should be enabled based on the architecture but based on the existence of the wiringPi library. This library can, of course, only be present on systems of proper architecture. I have once attempted to write a gb.wiringpi component but then I noticed that I don't have the hardware to test it. All that I find of it on my current PC is the note that apparently wiringPi (back then) wanted to fork the Gambas process to watch for events (the wiringPiISR() function). This is critical because some Gambas components might not want to be forked[*]. In any case, my advice would be to let wiringPi fork the interpreter and use a pipe from the forked process (which is where wiringPi detects interrupts) to the main process. The main process can watch this pipe by using the GB.Watch() API. If an interrupt is detected in the forked process, it would write something into the pipe which identifies the interrupt source and everything else you need. The main process reads this data and raises the respective Gambas event. > I have a PDF paper explaining how to create a Gambas component in C. I'm > afraid it does not cover events, though. If a simple explanation is given on > how to raise Events from C code, I may risk my ar$e and try to do it if the > platform restriction is doable. > You can look at gb.inotify. I think it is a neat and small example of a component where events are implemented. The code is at main/lib/inotify. The GB.Watch() API is also used in gb.inotify. Regards, Tobi [*] OTOH, we have Task in gb which forks the interpreter, so it should be OK if you do that, too. Note, however, that in my current project I had a case where I started ~40 background tasks on startup and the (GUI!) project would crash with some X server error. I solved that by adding Wait instructions to start the Tasks separately. I say this only so that you're not confused when your test project crashes randomly because wiringPi forks :-) -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk