VirtualMode & MySQL

The place for threads about TimoSoft ExplorerListView.
engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

VirtualMode & MySQL

Post by engee30 » 14 Oct 2013, 20:39

Hello

I'd like to connect my ADO Database to the Listview, but in VirtualMode. It's got more than 300 000 entries, so I wouldn't like to load all of them into the listview, but have access to the database and show only those that are set to be visible. Since I've never worked with a listview that had such a feature, I need a step-by-step tutorial.
Thanks for any help.

Regards,
Pete

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 14 Oct 2013, 20:53

Well, connecting the list view directly to the database would be a bad idea because database access probably isn't as performant as required.
You should load the data from the database into an internal data structure and let the list view run against this data structure. Or at least you should implement some caching that keeps not all records in memory, but also does not access the database for each tiny bit of data.

As I neither know the structure of your database nor the details that you want to display, I cannot help you with code.

Regards
TiKu
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 14 Oct 2013, 22:25

Um, basically the database holds all records of the lottery game KENO, which grows by another 420 or so every day. I've got fields for DrawNumber, DrawDate and NumbersDrawn. Right now, I just load everything into the listview, but that takes ages. So the only thing I came up with was to use VirtualMode.
I could load a part of the database internally, but just have no idea how to bind the data with the listview. I've been looking online for some solutions, but so far I've been out of luck. Looks like it's not something easy to do.

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 14 Oct 2013, 22:31

Can you put together a small sample that fills the list view in normal mode with some sample data? I then could modify it to use virtual mode instead.
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 14 Oct 2013, 23:34

All right, I'll do that. I should upload a sample project tomorrow. Oh, I was lucky this time. I've just found an example of a virtual listview. To my surprise, I was already able to bind it with some data of 1,000,000 items stored in an array 8-)
Attachments
Virtual_ListView_Demo.zip
(24.52 KiB) Downloaded 203 times

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 15 Oct 2013, 10:38

Okay, here's a small demo. A listview connected to a db and then loaded with some data from the db.
That's basically all I need to deal with. All other functions in the code are related to the content of the listview rather than the db.
Attachments
lvwDraws.zip
(6.7 KiB) Downloaded 202 times

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 15 Oct 2013, 20:01

Hi,

I've extended your sample project. Don't forget to set the list view's VirtualMode property to True in the Form editor. This property cannot be set at runtime.
Have a look at the code that fills the cache (the CacheItemsHint is important for MySQL). Microsoft T-SQL does not support the SELECT ... LIMIT statement, therefore I load ALL items into the cache on application start-up. MySQL supports SELECT ... LIMIT and therefore can fill the cache dynamically. I could not test the code for MySQL though.
If scrolling becomes slow with the MySQL caching behavior, you could modify this behavior a bit. For instance you could extend the cached interval by ~20 items in each direction.

Regards
TiKu
Attachments
lvwDraws.zip
(8 KiB) Downloaded 194 times
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 16 Oct 2013, 10:59

Lovely jubbly. Thank you so much TiKu. Works like a charm. The time in which the data loads has now significantly improved. I haven't encoutered any lag while scrolling, so it's fine as is. However, I've got 2 more questions. Is there a nice and easy method to clear the whole cache in an instant? It takes quite some time for the application to actually end. And the other question is, how do I update the cache while the app is still running? As I said earlier, I get around 420 new entries on a daily basis. I download it all straight from the servers providing all the draws. Is it to do with just allocating new data to the cache like:

Code: Select all

cacheEntry.ID= 'new draw no. for ID'
cacheEntry.Slo = 'new date for Slo'
cacheEntry.Dra = 'new draw for Dra'
Regards,
Pete

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 16 Oct 2013, 12:32

To improve performance on application shutdown, you could try to replace the class with a user-defined type (Type CacheEntry ... End Type).

To update the cache while the app is running, just create a new cache and - when it is complete - replace the old cache with the new cache. The code in the CacheItemsHint event does exactly this, so you can learn from it.

Regards
TiKu
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 16 Oct 2013, 18:11

Okey-doke. Job done. However, I didn't change the class to a type. I had forgotten to compile the project, and had done performance tests in the IDE instead, which produced those poor readings. The cache clears easily and smoothly.
I wouldn't be myself if I didn't ask another question ;) This time I've got a problem with sorting the listview. Every time I've tried to sort it, I get this error:

Code: Select all

Run-time error '-2147467259 (80004005)':
Automation error
Is it something to do with storing the data in the cache, which makes the control confused?

UPDATE
I've just found a similar thread dealing with the same problem:
viewtopic.php?f=28&t=131
Still, I can't figure out where I should call the refresh method :?

Kind regards,
Pete

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 16 Oct 2013, 20:17

Well, in VirtualMode you need to sort the data source - in your case this is the cache. The good thing is that you can let MySQL sort the data for you. After the cache has been sorted, call the list view's Refresh method.
Or did I get you wrong and your actual question is which event to use to resort the data? This would be the ColumnClick event.

Regards
TiKu
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 16 Oct 2013, 20:32

No, you got me right. I'll have a go with your suggestion and let you know how it's worked.

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 16 Oct 2013, 21:37

I'm afraid there's no way I could handle the issue. Dealing with databases, and only recently with the cache, is quite beyond me. It's not as straighforward as it is with the code I have under ColumnClick (partly provided by you):

Code: Select all

Private Sub lvwDraws_ColumnClick(ByVal column As ExLVwLibUCtl.IListViewColumn, ByVal button As Integer, ByVal shift As Integer, ByVal x As Single, ByVal y As Single, ByVal hitTestDetails As ExLVwLibUCtl.HeaderHitTestConstants)

lvwDraws.SortOrder = IIf((lvwDraws.SortOrder = soAscending), soDescending, soAscending)

Select Case column.Index
Case 0
lvwDraws.SortItems sobCustom
Case Is > 0
lvwDraws.SortItems sobText, , , , , column.Index
End Select

End Sub

Code: Select all

Private Sub lvwDraws_CompareItems(ByVal FirstItem As ExLVwLibUCtl.IListViewItem, ByVal secondItem As ExLVwLibUCtl.IListViewItem, result As ExLVwLibUCtl.CompareResultConstants)
Dim lFirstNumber As Long
Dim lSecondNumber As Long

  lFirstNumber = ExtractIntFromText(FirstItem.Text)
  lSecondNumber = ExtractIntFromText(secondItem.Text)
  
  If lFirstNumber < lSecondNumber Then
    result = crFirstSecond
  ElseIf lFirstNumber > lSecondNumber Then
    result = crSecondFirst
  Else
    result = crEqual
  End If

End Sub

Code: Select all

Private Function ExtractIntFromText(ByVal s As String) As Long
  Dim i As Long
  Dim p As Long
  Dim ret As Long

  p = -1
  For i = Len(s) To 1 Step -1
    If IsNumeric(Mid$(s, i, 1)) Then
      p = i
    Else
      Exit For
    End If
  Next i
  If p >= 0 Then
    ret = CLng(Mid$(s, p))
  Else
    ret = -1
  End If

  ExtractIntFromText = ret
End Function
I would appreciate it if you could come up with another solution. I wouldn't like to end up using the same routine as it is used at the very startup of the app, which takes time anyway with over 300 000 items, and still counting. Looks like it is the last bit I'm stuck with. :?:

I just wish alphi (the author of the thread viewtopic.php?f=28&t=131) had provided his solution to the problem in that thread. :|

User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: Unterföhring
Contact:

Re: VirtualMode & MySQL

Post by TiKu » 16 Oct 2013, 22:01

See attached file.

Regards
TiKu
Attachments
lvwDraws.zip
(8.16 KiB) Downloaded 187 times
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!

engee30
Lt. Commander
Posts: 54
Joined: 25 Sep 2012, 19:49
Location: Swindon, UK
Contact:

Re: VirtualMode & MySQL

Post by engee30 » 16 Oct 2013, 23:33

Thanks TiKu. I really appreciate your help. This is right what I'll stick with. I couldn't think of any better idea by myself. Yours is, roughly speaking, like the one I meant in my previous post, where I wrote:
I wouldn't like to end up using the same routine as it is used at the very startup of the app
Obviously, you made some changes in the coding.
Like I said, I'm no expert in coding and the stuff, so I think I can call my project finished now. You're a person of great knowledge of VB and patience. Many thanks for your time given up helping me out.
I can't promise I won't be asking any more questions in the future, though. :)

Best regards,
Pete

Post Reply