/**
  * Get the name of the lock to use specific to the database name of the current application, as a SQL-escaped string.
  */
 protected static function lockNamePostfix()
 {
     if (!self::$lockNamePostfix) {
         self::$lockNamePostfix = Convert::raw2sql('_' . DB::query('select database()')->value());
     }
     return self::$lockNamePostfix;
 }
 /**
  * Returns a single queue object according to a particular priority and freshness measure.
  * This method removes any duplicates and makes the object as "regenerating", so other calls to this method
  * don't grab the same object.
  * If we are using MySQLDatabase with InnoDB, we do row-level locking when updating the dataobject to allow for
  * distributed cache rebuilds
  * @static
  * @param $freshness
  * @param $sortOrder
  */
 protected static function get_queue_object($freshness, $interval = null, $sortOrder = array('Priority' => 'DESC', 'ID' => 'ASC'))
 {
     $className = __CLASS__;
     $queueObject = null;
     $filterQuery = array("Freshness" => $freshness);
     if ($interval) {
         $filterQuery["LastEdited:LessThan"] = $interval;
     }
     $query = self::get();
     if ($query->Count() > 0) {
         $offset = 0;
         $filteredQuery = $query->filter($filterQuery)->sort($sortOrder);
         if ($filteredQuery->Count() > 0) {
             if (DB::getConn() instanceof MySQLDatabase) {
                 //locking currently only works on MySQL
                 do {
                     $queueObject = $filteredQuery->limit(1, $offset)->first();
                     //get first item
                     if ($queueObject) {
                         $lockName = md5($queueObject->URLSegment . $className);
                     }
                     //try to locking the item's URL, keep trying new URLs until we find one that is free to lock
                     $offset++;
                 } while ($queueObject && !LockMySQL::isFreeToLock($lockName));
                 if ($queueObject) {
                     $lockSuccess = LockMySQL::getLock($lockName);
                     //acquire a lock with the URL of the queue item we have just fetched
                     if ($lockSuccess) {
                         self::remove_duplicates($queueObject->ID);
                         //remove any duplicates
                         self::mark_as_regenerating($queueObject);
                         //mark as regenerating so nothing else grabs it
                         LockMySQL::releaseLock($lockName);
                         //return the object and release the lock
                     }
                 }
             } else {
                 $queueObject = $filteredQuery->first();
                 self::remove_duplicates($queueObject->ID);
                 self::mark_as_regenerating($queueObject);
             }
         }
     }
     return $queueObject;
     //return the object or null
 }