Search code examples
javasalesforcevisualforceapexsoql

Why is Apex iterating backwards over this set?


I've never worked in Java before, let alone Apex, and not much with databases, so pardon me if I'm making some really stupid mistakes.

I'm working on a VisualForce page to let staffmembers at my organization search for keywords in rich text fields across multiple records. SOQL isn't very good for long text fields, so I'm using SOSL.

The user goes to the URI of the VF page and a SOSL query is performed based on three GET parameters in the URI: and, or, and not. This lets users "save" and share their searches with other staffmembers. (Yes, I'll protect against SQL injections.)

For example:

https://abc123.visual.force.com/apex/myCustomController?and=bilbo,baggins&or=frodo,pippin,merry&not=sauron

That should yield:

FIND '(bilbo* AND baggins*) OR (frodo* OR pippin* OR merry*) AND NOT (sauron*)'...

Instead, I get this:

FIND 'AND NOT (sauron*) OR (frodo* or pippin* or merry*)(bilbo* and baggins*)'...

The urlParamTypes set keeps iterating through the outermost for loop in reverse alphabetical order.

I've tried sorting, I've tried writing it in the opposite order, and nothing works. Otherwise things seem to be going remarkably well, so it's frustrating that the thing I'm having trouble with is something that seems so silly.

Your thoughts greatly appreciated!

Public with sharing class myController{

    Public Map<String, String> urlParams {get; set;}
    Public Set<String> urlParamTypes = new Set<String>{'and','or','not'};
    Public String queryString {get; set;}
    Public List<myCustomObject> candidates {get; set;}

    Public myController(){
        urlParams = ApexPages.currentPage().getParameters();
        Integer totalParamTypes = urlParams.size();
        Integer intOfParamTypes = 0;
        for(String thisParamType : urlParamTypes){
            String thisParamString = urlParams.get(thisParamType);
            Integer intOfThisParamType = 0;
            Integer totalOfThisParamType = 0;

            if(thisParamString != null && thisParamString.length() > 0){
                intOfParamTypes++;

                if(thisParamType == 'or' && intOfParamTypes > 0){
                    queryString += ' OR ';
                }else
                if(thisParamType == 'not' && intOfParamTypes > 0){
                    queryString += ' AND NOT ';
                }

                queryString += '(' + thisParamString.replace(',', '* ' + (thisParamType == 'not' ? 'AND' : thisParamType) + ' ') + '*)';
            }

        }
        queryString = 'FIND \'' + queryString + '\' RETURNING myCustomObject (id,name)';
        List<List <myCustomObject>> searchList = search.query(queryString);
        candidates = ((List<sObject>)searchList[0]);
    }

}

Solution

  • Set does not maintain sort. The fact that the values seem to be coming out in reverse order is coincidence. Can you use List instead?