Search Drupal User Profiles

It is difficult to search for users (in code) based on profile information in Drupal 6 due to the flexible nature in which the profiles module stores information. Basically profiles are stored in 2 tables.
mysql> select * from profile_fields;
+-----+------------+-------------------+-------------+---------------------+------+-----------+--------+----------+----------+------------+--------------+---------+
| fid | title      | name              | explanation | category            | page | type      | weight | required | register | visibility | autocomplete | options |
+-----+------------+-------------------+-------------+---------------------+------+-----------+--------+----------+----------+------------+--------------+---------+
|   1 | First Name | profile_firstname |             | General Information |      | textfield |      0 |        0 |        1 |          1 |            0 |         |
|   2 | Last Name  | profile_lastname  |             | General Information |      | textfield |      0 |        0 |        1 |          1 |            0 |         |                                          
+-----+------------+-------------------+-------------+---------------------+------+-----------+--------+----------+----------+------------+--------------+---------+                                          
2 rows in set (0.00 sec) 
select * from profile_values limit 4;                                                                                                                                                            
+-----+-----+---------+                                                                                                                                                                                       
| fid | uid | value   |                                                                                                                                                                                       
+-----+-----+---------+                                                                                                                                                                                       
|   1 |   1 | John    |                                                                                                                                                                                       
|   2 |   1 | Doe     |                                                                                                                                                                                       
|   1 | 115 | John    |                                                                                                                                                                                       
|   2 | 115 | Smith   |                                                                                                                                                                                       
+-----+-----+---------+                                                                                                                                                                                       
4 rows in set (0.00 sec)
With only one value per row it is difficult to create a generic function to search for multiple values at once. We could examine both tables and hard code a mysql function using multiple joins for each fid but that isn'r very reusable. Thankfully the mysql GROUP_CONCAT function comes to the rescue. Combined with a simple function to get profile field definitions it is possible to search for users based on profile information. Here are two simple functions I came up with that make it easy to search for users based on profile information in drupal
/**
 * dgs_get_profile_fields
 * @return array(name => fid)
 */
function dgs_get_profile_fields($category = null){
  if(isset($profile_fields)){
    return $profile_fields;
  }
  static $profile_fields = array();
  $sql = "SELECT * FROM {profile_fields}";
  $args = array();
  if(!empty($category)){
    $sql .= " WHERE category='%s'";
    $args= array($category);
  }
  $result = db_query($sql,$args);
  while($row = db_fetch_object($result)){
    $profile_fields[$row->name] = $row->fid;
  }
  return $profile_fields;
}

/**
 * dgs_search_profiles
 * @param(array(fieldname => fieldvalue));
 * @return an array of user uids
 */
function dgs_search_profiles($params = array()){
  //Example SQL
  //SELECT GROUP_CONCAT(fid,'=',value) as profile from profile_values GROUP BY(uid) HAVING profile like "%1=Gary%" AND profile like "%2=Varnell%";
  $profile_fields = dgs_get_profile_fields();
  $having = array();
  $args = array();
  foreach($params as $fieldname => $fieldvalue){
    $having[] = "profile LIKE '%s'";
    $args[] = "%" . $profile_fields[$fieldname] . "=$fieldvalue%";
  }
  $having = join('AND ',array_values($having));
  $result = db_query("SELECT uid,GROUP_CONCAT(fid,'=',value) as profile from profile_values GROUP BY(uid) HAVING $having",$args);
  $users = array();
  while($row = db_fetch_object($result)){
    $users[$row->uid] = user_load($row->uid);
  }
  return $users;
}
And here is a usage example
    $users = dgs_search_profiles(array('profile_firstname' => 'John','profile_lastname' => 'Doe'));
    print_r($users);
Which returns
Array
(
    [xxx] => stdClass Object
        (
            [uid] => xxx
            [name] => jdoe
            [pass] => xxxxxxxx
            [mail] => jdoe@somewhere.com
            [mode] => 0
            [sort] => 0
            [threshold] => 0
            [theme] => 
            [signature] => 
            [signature_format] => 0
            [created] => 1264712914
            [access] => 1318017735
            [login] => 1317926353
            [status] => 1
            [timezone] => -21600
            [language] => 
            [picture] => 
            [init] => xxxxx
            [data] => a:1:{s:13:"form_build_id";s:37:"form-xxxxxxxxxxxxxxxxxxxxx";}
            [form_build_id] => form-xxxxxxxxxxxxxxxxx
            [roles] => Array
                (
                    [2] => authenticated user
                    [3] => xxxxxxx
                    [5] => xxxxxxx
                )

            [profile_firstname] => John
            [profile_lastname] => Doe
        )

If you have a better solution please let me know, and as always feel free to comment.