You are not logged in.

#1 2011-11-27 00:36:15

Franek
Member
Registered: 2010-05-16
Posts: 100

converting shell wildcards to SQL wildcards (in C++, if possible)

Hi!

Does anyone know of a utility or C/C++ library function (or C/C++ code snippet) to convert text strings with shell wildcards (*, ?) to SQL wildcards (%, _)? I have been ducking the web for quiet a while with no success, but I cannot imagine that no one has done this before.

I know that SQL wildcards are much more limited than shell globbing, which means that only a subset of valid shell wildcard strings can be converted to SQL syntax (only * and ?, basically). I also know about the GLOB operator in Sqlite, which lets you use * and ? in SQL queries. It is Sqlite specific, however, and I want to use only generic SQL wherever possible.

Of course this seems reasonably easy to implement by myself. There are some pitfalls concerning escaping characters, but I managed to write something that should work for all but some special cases (like \\*, which should become \\%, but becomes \*):

    inline void wildcards_shell_to_sql(Glib::ustring& input) //should be the same for std::string
    {
        //escape _ and %
        size_t pos = 0;
        while ( (pos = input.find_first_of("%_", pos)) != Glib::ustring::npos )
        {
            input.insert(pos, 1, '\\');
            std::cout << input << std::endl;
            pos += 2; //No idea why it has to be 2, not one; but empirically, it does.
        }

        //change * and ? to % and _, if not escaped; if escaped, unescape them
        pos = 0;
        while ( (pos = input.find('*', pos)) != Glib::ustring::npos )
        {
            if ( input[pos-1] != '\\' )
                input.replace(pos, 1, "%");
            else 
                input.erase(pos-1, 1);
        }
        pos = 0;
        while ( (pos = input.find('?', pos)) != Glib::ustring::npos )
        {
            if ( input[pos-1] != '\\' )
                input.replace(pos, 1, "_");
            else 
                input.erase(pos-1, 1);
        }

        //framing wildcards for better user experience //comment for buzzword placement
        input.insert(0, "%");
        input.push_back('%');
    }

Having a known-to-work library function would be nicer, though.

Offline

Board footer

Powered by FluxBB