コード例 #1
0
ファイル: SortUtils.cpp プロジェクト: evilhamster/xbmc
void SortUtils::Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute attributes, DatabaseResults& items, int limitEnd /* = -1 */, int limitStart /* = 0 */)
{
  if (sortBy != SortByNone)
  {
    // get the matching SortPreparator
    SortPreparator preparator = getPreparator(sortBy);
    if (preparator != NULL)
    {
      Fields sortingFields = GetFieldsForSorting(sortBy);

      // Prepare the string used for sorting and store it under FieldSort
      for (DatabaseResults::iterator item = items.begin(); item != items.end(); ++item)
      {
        // add all fields to the item that are required for sorting if they are currently missing
        for (Fields::const_iterator field = sortingFields.begin(); field != sortingFields.end(); ++field)
        {
          if (item->find(*field) == item->end())
            item->insert(std::pair<Field, CVariant>(*field, CVariant::ConstNullVariant));
        }

        std::wstring sortLabel;
        g_charsetConverter.utf8ToW(preparator(attributes, *item), sortLabel, false);
        item->insert(std::pair<Field, CVariant>(FieldSort, CVariant(sortLabel)));
      }

      // Do the sorting
      std::stable_sort(items.begin(), items.end(), getSorter(sortOrder, attributes));
    }
  }

  if (limitStart > 0 && (size_t)limitStart < items.size())
  {
    items.erase(items.begin(), items.begin() + limitStart);
    limitEnd -= limitStart;
  }
  if (limitEnd > 0 && (size_t)limitEnd < items.size())
    items.erase(items.begin() + limitEnd, items.end());
}
コード例 #2
0
bool DatabaseUtils::GetDatabaseResults(const MediaType &mediaType, const FieldList &fields, const std::unique_ptr<dbiplus::Dataset> &dataset, DatabaseResults &results)
{
  if (dataset->num_rows() == 0)
    return true;

  const dbiplus::result_set &resultSet = dataset->get_result_set();
  unsigned int offset = results.size();

  if (fields.empty())
  {
    DatabaseResult result;
    for (unsigned int index = 0; index < resultSet.records.size(); index++)
    {
      result[FieldRow] = index + offset;
      results.push_back(result);
    }

    return true;
  }

  if (resultSet.record_header.size() < fields.size())
    return false;

  std::vector<int> fieldIndexLookup;
  fieldIndexLookup.reserve(fields.size());
  for (FieldList::const_iterator it = fields.begin(); it != fields.end(); ++it)
    fieldIndexLookup.push_back(GetFieldIndex(*it, mediaType));

  results.reserve(resultSet.records.size() + offset);
  for (unsigned int index = 0; index < resultSet.records.size(); index++)
  {
    DatabaseResult result;
    result[FieldRow] = index + offset;

    unsigned int lookupIndex = 0;
    for (FieldList::const_iterator it = fields.begin(); it != fields.end(); ++it)
    {
      int fieldIndex = fieldIndexLookup[lookupIndex++];
      if (fieldIndex < 0)
        return false;

      std::pair<Field, CVariant> value;
      value.first = *it;
      if (!GetFieldValue(resultSet.records[index]->at(fieldIndex), value.second))
        CLog::Log(LOGWARNING, "GetDatabaseResults: unable to retrieve value of field %s", resultSet.record_header[fieldIndex].name.c_str());

      if (value.first == FieldYear &&
         (mediaType == MediaTypeTvShow || mediaType == MediaTypeEpisode))
      {
        CDateTime dateTime;
        dateTime.SetFromDBDate(value.second.asString());
        if (dateTime.IsValid())
        {
          value.second.clear();
          value.second = dateTime.GetYear();
        }
      }

      result.insert(value);
    }

    result[FieldMediaType] = mediaType;
    if (mediaType == MediaTypeMovie || mediaType == MediaTypeVideoCollection ||
        mediaType == MediaTypeTvShow || mediaType == MediaTypeMusicVideo)
      result[FieldLabel] = result.at(FieldTitle).asString();
    else if (mediaType == MediaTypeEpisode)
    {
      std::ostringstream label;
      label << (int)(result.at(FieldSeason).asInteger() * 100 + result.at(FieldEpisodeNumber).asInteger());
      label << ". ";
      label << result.at(FieldTitle).asString();
      result[FieldLabel] = label.str();
    }
    else if (mediaType == MediaTypeAlbum)
      result[FieldLabel] = result.at(FieldAlbum).asString();
    else if (mediaType == MediaTypeSong)
    {
      std::ostringstream label;
      label << (int)result.at(FieldTrackNumber).asInteger();
      label << ". ";
      label << result.at(FieldTitle).asString();
      result[FieldLabel] = label.str();
    }
    else if (mediaType == MediaTypeArtist)
      result[FieldLabel] = result.at(FieldArtist).asString();

    results.push_back(result);
  }

  return true;
}