Commit 815391ea authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Allow media to be sorted by main file size

Fix #4
parent 4a7318a9
......@@ -41,6 +41,7 @@ namespace fs
virtual const std::string& fullPath() const = 0;
virtual const std::string& extension() const = 0;
virtual unsigned int lastModificationDate() const = 0;
virtual unsigned int size() const = 0;
};
}
......
......@@ -55,6 +55,7 @@ public:
virtual const std::string& mrl() const = 0;
virtual Type type() const = 0;
virtual unsigned int lastModificationDate() const = 0;
virtual unsigned int size() const = 0;
};
}
......@@ -65,6 +65,7 @@ enum class SortingCriteria
InsertionDate,
LastModificationDate,
ReleaseDate,
FileSize,
};
class IMediaLibraryCb
......
......@@ -44,6 +44,7 @@ File::File( MediaLibraryPtr ml, sqlite::Row& row )
>> m_mrl
>> m_type
>> m_lastModificationDate
>> m_size
>> m_isParsed
>> m_folderId
>> m_isPresent
......@@ -57,6 +58,7 @@ File::File( MediaLibraryPtr ml, int64_t mediaId, Type type, const fs::IFile& fil
, m_mrl( isRemovable == true ? file.name() : file.fullPath() )
, m_type( type )
, m_lastModificationDate( file.lastModificationDate() )
, m_size( file.size() )
, m_isParsed( false )
, m_folderId( folderId )
, m_isPresent( true )
......@@ -94,6 +96,11 @@ unsigned int File::lastModificationDate() const
return m_lastModificationDate;
}
unsigned int File::size() const
{
return m_size;
}
bool File::isParsed() const
{
return m_isParsed;
......@@ -132,6 +139,7 @@ bool File::createTable( DBConnection dbConnection )
"mrl TEXT,"
"type UNSIGNED INTEGER,"
"last_modification_date UNSIGNED INT,"
"size UNSIGNED INT,"
"parsed BOOLEAN NOT NULL DEFAULT 0,"
"folder_id UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
......@@ -158,10 +166,10 @@ std::shared_ptr<File> File::create( MediaLibraryPtr ml, int64_t mediaId, Type ty
{
auto self = std::make_shared<File>( ml, mediaId, type, fileFs, folderId, isRemovable );
static const std::string req = "INSERT INTO " + policy::FileTable::Name +
"(media_id, mrl, type, folder_id, last_modification_date, is_removable) VALUES(?, ?, ?, ?, ?, ?)";
"(media_id, mrl, type, folder_id, last_modification_date, size, is_removable) VALUES(?, ?, ?, ?, ?, ?, ?)";
if ( insert( ml, self, req, mediaId, self->m_mrl, type, sqlite::ForeignKey( folderId ),
self->m_lastModificationDate, isRemovable ) == false )
self->m_lastModificationDate, self->m_size, isRemovable ) == false )
return nullptr;
self->m_fullPath = fileFs.fullPath();
return self;
......
......@@ -53,6 +53,7 @@ public:
virtual const std::string& mrl() const override;
virtual Type type() const override;
virtual unsigned int lastModificationDate() const override;
virtual unsigned int size() const override;
/// Explicitely mark a media as fully parsed, meaning no metadata service needs to run anymore.
//FIXME: This lacks granularity as we don't have a straight forward way to know which service
//needs to run or not.
......@@ -88,6 +89,7 @@ private:
std::string m_mrl;
Type m_type;
unsigned int m_lastModificationDate;
unsigned int m_size;
bool m_isParsed;
int64_t m_folderId;
bool m_isPresent;
......
......@@ -363,13 +363,16 @@ void Media::removeFile( File& file )
std::vector<MediaPtr> Media::listAll( MediaLibraryPtr ml, IMedia::Type type, SortingCriteria sort, bool desc )
{
std::string req;
if ( sort == SortingCriteria::LastModificationDate )
if ( sort == SortingCriteria::LastModificationDate || sort == SortingCriteria::FileSize )
{
req = "SELECT m.* FROM " + policy::MediaTable::Name + " m INNER JOIN "
+ policy::FileTable::Name + " f ON m.id_media = f.media_id"
" WHERE m.type = ?"
" AND ( f.type = ? OR f.type = ? )"
" ORDER BY f.last_modification_date";
" AND ( f.type = ? OR f.type = ? )";
if ( sort == SortingCriteria::LastModificationDate )
req += " ORDER BY f.last_modification_date";
else
req += " ORDER BY f.size";
if ( desc == true )
req += " DESC";
return fetchAll<IMedia>( ml, req, type, File::Type::Entire, File::Type::Main );
......
......@@ -42,5 +42,10 @@ unsigned int NetworkFile::lastModificationDate() const
return 0;
}
unsigned int NetworkFile::size() const
{
return 0;
}
}
}
......@@ -33,6 +33,7 @@ class NetworkFile : public CommonFile
public:
NetworkFile( const std::string& filePath );
virtual unsigned int lastModificationDate() const override;
virtual unsigned int size() const override;
};
}
}
......@@ -39,6 +39,7 @@ File::File( const std::string& filePath, const struct stat& s )
: CommonFile( filePath )
{
m_lastModificationDate = s.st_mtime;
m_size = s.st_size;
}
unsigned int File::lastModificationDate() const
......@@ -46,6 +47,11 @@ unsigned int File::lastModificationDate() const
return m_lastModificationDate;
}
unsigned int File::size() const
{
return m_size;
}
}
}
......@@ -38,9 +38,11 @@ public:
explicit File( const std::string& filePath, const struct stat& s );
virtual unsigned int lastModificationDate() const override;
virtual unsigned int size() const override;
private:
unsigned int m_lastModificationDate;
unsigned int m_size;
};
}
......
......@@ -44,21 +44,19 @@ namespace fs
File::File( const std::string &filePath )
: CommonFile( filePath )
{
struct _stat s;
if ( _stat( m_fullPath.c_str(), &s ) != 0 )
{
LOG_ERROR( "Failed to get ", m_fullPath, " stats" );
throw std::system_error( GetLastError(), std::generic_category(), "Failed to get stats" );
}
m_lastModificationDate = s.st_mtime;
m_size = s.st_size;
}
unsigned int File::lastModificationDate() const
{
if ( m_lastModificationDate == 0 )
{
struct _stat s;
if ( _stat( m_fullPath.c_str(), &s ) != 0 )
{
LOG_ERROR( "Failed to get ", m_fullPath, " stats" );
throw std::system_error( GetLastError(), std::generic_category(), "Failed to get stats" );
}
m_lastModificationDate = s.st_mtime;
}
return m_lastModificationDate;
}
......
......@@ -38,7 +38,8 @@ public:
unsigned int lastModificationDate() const override;
private:
mutable unsigned int m_lastModificationDate;
unsigned int m_lastModificationDate;
unsigned int m_size;
};
}
......
......@@ -219,6 +219,7 @@ class NoopFile : public fs::IFile
std::string m_fileName;
std::string m_extension;
unsigned int m_lastModifDate;
unsigned int m_size;
public:
NoopFile( const std::string& file )
......@@ -226,6 +227,7 @@ public:
, m_fileName( utils::file::fileName( file ) )
, m_extension( utils::file::extension( file ) )
, m_lastModifDate( 123 )
, m_size( 321 )
{
}
......@@ -256,10 +258,20 @@ public:
return m_lastModifDate;
}
virtual unsigned int size() const
{
return m_size;
}
void setLastModificationDate( unsigned int date )
{
m_lastModifDate = date;
}
void setSize( unsigned int size )
{
m_size = size;
}
};
class NoopDevice : public fs::IDevice
......
......@@ -70,4 +70,9 @@ unsigned int File::lastModificationDate() const
return m_lastModification;
}
unsigned int File::size() const
{
return 0;
}
}
......@@ -42,6 +42,7 @@ public:
virtual const std::string& fullPath() const override;
virtual const std::string& extension() const override;
virtual unsigned int lastModificationDate() const override;
virtual unsigned int size() const override;
void markAsModified();
private:
......
......@@ -50,6 +50,7 @@ TEST_F( Files, Create )
ASSERT_FALSE( f->isParsed() );
ASSERT_EQ( "media.mkv", f->mrl() );
ASSERT_NE( 0u, f->lastModificationDate() );
ASSERT_NE( 0u, f->size() );
ASSERT_EQ( File::Type::Entire, f->type() );
}
......
......@@ -390,6 +390,28 @@ TEST_F( Medias, SortByLastModifDate )
ASSERT_EQ( m1->id(), media[0]->id() );
}
TEST_F( Medias, SortByFileSize )
{
auto file1 = std::make_shared<mock::NoopFile>( "media.mkv" );
file1->setSize( 666 );
auto m1 = ml->addFile( *file1 );
auto file2 = std::make_shared<mock::NoopFile>( "media2.mkv" );
file2->setSize( 111 );
auto m2 = ml->addFile( *file2 );
auto media = ml->videoFiles( SortingCriteria::FileSize, false );
ASSERT_EQ( 2u, media.size() );
ASSERT_EQ( m2->id(), media[0]->id() );
ASSERT_EQ( m1->id(), media[1]->id() );
media = ml->videoFiles( SortingCriteria::FileSize, true );
ASSERT_EQ( 2u, media.size() );
ASSERT_EQ( m2->id(), media[1]->id() );
ASSERT_EQ( m1->id(), media[0]->id() );
}
class FetchMedia : public Tests
{
protected:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment