I am writing a DSAPI application that accesses various mail,contact and task folders/views.
Like clicking on the header in the Notes Client, I want to be able to sort these views by any sorted column and then access the view collection.
I haven’t found any functions in the C++ API that will allow me to sort by any column other than the first sorted column in the view (ascending or descending).
Rather than create a new view for each sort column I would like, what other options do I have?
Do any of the C/C++ experts out there know a way to do this?
I was looking this morning and realized that perhaps I can call LNViewFolder::InsertColumn on the fly and place the column in the first position but haven’t tried it yet.
You would think that you could do the equivalent of clicking a column header to sort a view/folder.
As it is, if I want to sort a folder (say ($Inbox)), then I need to create another folder with proper sort column, move all docs to that folder, refresh index, then access folder.
I must be missing something because this is a real pain. You’d think there would be an easier way to do something as simple as sorting.
there’s no way to make use of other columns that can be sorted in ui, neither through c/c++ api nor script or whatever.
since this isn’t implemented raises the question if these additional indizes are even prebuilt on server. my guess is that this might only be done on clientside, but i’m not shure.
your suggested workaround might work, but i’m not shure if modifying views on the fly is a safe way to go. any chance you could use e.g. c-api NSFSearch (or c++ api equivalent) and handle to sort yourself (using e.g. stl classes)? this way you could even have the value you like to sort be computed using a formula…
Yes, I could do the sort myself after reading all entries in a view or folder. The problem is that I am trying to support the concept that a view might be HUGE and I don’t want to suffer the performance penalties that come with sorting with thousands or millions of entries myself. I would rather Notes do that.
So, for example, what I am doing is requesting (from my web mail app through my DSAPI filter) a chunk of 25 emails sorted ascending by date receieved (Inbox default). The user can page through or select individual chunks from an index. To do that I need to know in advance what chunks there are. I go through a view collection in leaps of 25 to create that index.
Ideally, I would be able to access the Inbox folder, sort it by whatever criteria, create my index, then access the folder top to bottom in chunks of 25.
The only solution I can think of right now is this:
Create separate views for each sort key and view or folder.
Traverse view collection forwards for ascending, backwards for descending
For folders, create generic folders for each sort key.
The ugly part here is that I must associate all of the documents from the Inbox folder to the ‘InboxBySubject’ folder, then read the contents. I must then synchronize the various sort folders so that the contents remain the same.
This is a bit brute force, but I know it will work. I was just hoping that the experts in this forum would have a better way so as to save me lots of time and effort.
I’m really disappointed that the API functions don’t have better sorting ability than just ascending or descending by date. Lotus, are you going to deal with this??? Better yet, have I missed something here and can you prove me wrong?
synchronizing these folders is quick and reliable. should be no problem at all.
what’s the reason for doing all this “manually” and not let domino display those views? but i’m not very familiar with dsapi applications…
once you’ve built these views is it really neccessary to parse complete view? why not rely on view/folder count and read just these entries?
i don’t know what average doccount of an inbox folder is, but once reading complete folder and handling indizes yourself might well be no overkill (stl classes are fast and easy to use). and it’s easy to keep views refreshed (e.g. using NSFDbGetModifiedNoteTable).
Some notes from someone who is moderatly knowledgeable about the basic C API stuff:
Both methods (one view 3 sorted columns vs. three views with 1 sorted column) will introduce exactly the same amount of indexes (ie: three). The only difference in space on the server is if you add extra non-sorted columns which is duplicated in the three views scenario.
In the C API you can easily traverse a view in either direction in the way you describe using NIFReadEntries, and you can select which sortable column you want to use for sorting using NIFSetCollation.
It’s really all spelled out in detail in the C API reference and documentation. (I’m not using the C++ API myself, so I’m not sure about that one). Did you check it out?
Introducing a scheme with introducing new columns on every lookup or folders which you have to sort yourself is pure and utter insanity and will slow your server to a crawl since it has to reindex the entire view on each and every access. Don’t even think about that.
I had scanned the api docs and reference pretty well, but missed the NIFSetCollation stuff. That’s why I was hoping someone like yourself could quickly put me in the right direction.
I am using mostly C++ API, but dipping down to C API when needed. The C++ API definitely does NOT have this functionality.
I will read through this and hopefully it solves my problem.
Yeah, I never really seriously considered inserting columns on the fly as your right, it would be insane.
Also note that NIFFSetCollation is not referenced at all in the user guide. The only docs are in the call itself (I was using the word “sort” or “sorting” to find this).
A google search of the term yields no results either…
I think you’ve overlooked the NIFSetCollation function in the C API, which basically selects which index you want to use for retrieving the view data (and yes, they get built and used).
Using NSFSearch will kill any and all notions of performance on any database containing more than a couple of documents.
It looks like NIFSetCollation will allow me to sort by any column that is already a sorted column, or has the “click on column header to sort” option set.
In the ($Inbox) view, for example, subject is not sorted, thus will not have a collation associated with it.
My options now are to:
Create one view/folder myself for each type (message,task,contact etc…) that has all of the sort columns I desire, then use the NIFReadEntries and NIFSetCollation, or
Upon DSAPI server startup, modify the ($Inbox) and other views by adding sort options and/or columns brute force. This will of course be blown away in a design refresh, but perhaps I could live with that. This would keep me from having to move items to a new folder before sorting…
Ok, so what I’ve settled on after much pondering is this:
For Folders:
Create a single folder per type (message,contacts,tasks etc.) with all sort columns defined.
Upon sort, relate all items in selected folder (can be a user created folder) to my folder for that type. First time may cause delay for view indexing.
Set Collation and traverse view.
Subsequently synchronize folder references for my sort folder if docs are added/removed from main folder. This will keep things fast.
For Views:
Create one view per type with my own sort columns defined.
Upon sort, set collation and traverse view.
Notes:
I have chosen to create my own views (in user mail file the first time he logs in). This will give me better control, and avoid backward/forward compatibility problems associated with modifying the Lotus views/folders.