Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
VideoLAN
medialibrary
Commits
1ebc9b48
Commit
1ebc9b48
authored
Jun 21, 2018
by
Hugo Beauzée-Luyssen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Metadata: Handle metadata for multiple types
parent
0f94a8d4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
73 additions
and
50 deletions
+73
-50
include/medialibrary/IMedia.h
include/medialibrary/IMedia.h
+2
-2
include/medialibrary/IMetadata.h
include/medialibrary/IMetadata.h
+6
-2
src/Media.cpp
src/Media.cpp
+14
-9
src/Media.h
src/Media.h
+2
-2
src/MediaLibrary.cpp
src/MediaLibrary.cpp
+1
-1
src/Metadata.cpp
src/Metadata.cpp
+34
-23
src/Metadata.h
src/Metadata.h
+14
-11
No files found.
include/medialibrary/IMedia.h
View file @
1ebc9b48
...
...
@@ -34,7 +34,7 @@ namespace medialibrary
class
IAlbumTrack
;
class
IShowEpisode
;
class
ITrackInformation
;
class
IMe
diaMe
tadata
;
class
IMetadata
;
class
IMedia
{
...
...
@@ -150,7 +150,7 @@ class IMedia
/// \param type The metadata type
/// \return A reference to a wrapper object representing the metadata.
///
virtual
const
IMe
diaMe
tadata
&
metadata
(
MetadataType
type
)
const
=
0
;
virtual
const
IMetadata
&
metadata
(
MetadataType
type
)
const
=
0
;
///
/// \brief setMetadata Immediatly saves a metadata in database
///
...
...
include/medialibrary/IMetadata.h
View file @
1ebc9b48
...
...
@@ -27,10 +27,14 @@
namespace
medialibrary
{
class
IMe
diaMe
tadata
class
IMetadata
{
public:
virtual
~
IMediaMetadata
()
=
default
;
enum
class
EntityType
:
uint8_t
{
Media
=
1
,
};
virtual
~
IMetadata
()
=
default
;
virtual
bool
isSet
()
const
=
0
;
virtual
int64_t
integer
()
const
=
0
;
virtual
const
std
::
string
&
str
()
const
=
0
;
...
...
src/Media.cpp
View file @
1ebc9b48
...
...
@@ -59,7 +59,7 @@ int64_t Media::* const policy::MediaTable::PrimaryKey = &Media::m_id;
Media
::
Media
(
MediaLibraryPtr
ml
,
sqlite
::
Row
&
row
)
:
m_ml
(
ml
)
,
m_metadata
(
m_ml
)
,
m_metadata
(
m_ml
,
IMetadata
::
EntityType
::
Media
)
,
m_changed
(
false
)
{
row
>>
m_id
...
...
@@ -95,7 +95,7 @@ Media::Media( MediaLibraryPtr ml, const std::string& title, Type type )
,
m_filename
(
title
)
,
m_isFavorite
(
false
)
,
m_isPresent
(
true
)
,
m_metadata
(
m_ml
)
,
m_metadata
(
m_ml
,
IMetadata
::
EntityType
::
Media
)
,
m_changed
(
false
)
{
}
...
...
@@ -298,25 +298,28 @@ unsigned int Media::releaseDate() const
return
m_releaseDate
;
}
const
IMe
diaMe
tadata
&
Media
::
metadata
(
IMedia
::
MetadataType
type
)
const
const
IMetadata
&
Media
::
metadata
(
IMedia
::
MetadataType
type
)
const
{
using
MDType
=
typename
std
::
underlying_type
<
IMedia
::
MetadataType
>::
type
;
if
(
m_metadata
.
isReady
()
==
false
)
m_metadata
.
init
(
m_id
,
IMedia
::
NbMeta
);
return
m_metadata
.
get
(
type
);
return
m_metadata
.
get
(
static_cast
<
MDType
>
(
type
)
);
}
bool
Media
::
setMetadata
(
IMedia
::
MetadataType
type
,
const
std
::
string
&
value
)
{
using
MDType
=
typename
std
::
underlying_type
<
IMedia
::
MetadataType
>::
type
;
if
(
m_metadata
.
isReady
()
==
false
)
m_metadata
.
init
(
m_id
,
IMedia
::
NbMeta
);
return
m_metadata
.
set
(
type
,
value
);
return
m_metadata
.
set
(
static_cast
<
MDType
>
(
type
)
,
value
);
}
bool
Media
::
setMetadata
(
IMedia
::
MetadataType
type
,
int64_t
value
)
{
using
MDType
=
typename
std
::
underlying_type
<
IMedia
::
MetadataType
>::
type
;
if
(
m_metadata
.
isReady
()
==
false
)
m_metadata
.
init
(
m_id
,
IMedia
::
NbMeta
);
return
m_metadata
.
set
(
type
,
value
);
return
m_metadata
.
set
(
static_cast
<
MDType
>
(
type
)
,
value
);
}
void
Media
::
setReleaseDate
(
unsigned
int
date
)
...
...
@@ -695,12 +698,14 @@ void Media::clearHistory( MediaLibraryPtr ml )
static
const
std
::
string
req
=
"UPDATE "
+
policy
::
MediaTable
::
Name
+
" SET "
"play_count = 0,"
"last_played_date = NULL"
;
static
const
std
::
string
flushProgress
=
"DELETE FROM "
+
policy
::
MediaMetadataTable
::
Name
+
" WHERE type = ?"
;
// Clear the entire cache since quite a few items are now containing invalid info.
clear
();
using
MDType
=
typename
std
::
underlying_type
<
IMedia
::
MetadataType
>::
type
;
Metadata
::
unset
(
dbConn
,
IMetadata
::
EntityType
::
Media
,
static_cast
<
MDType
>
(
IMedia
::
MetadataType
::
Progress
)
);
sqlite
::
Tools
::
executeUpdate
(
dbConn
,
req
);
sqlite
::
Tools
::
executeDelete
(
dbConn
,
flushProgress
,
IMedia
::
MetadataType
::
Progress
);
}
}
src/Media.h
View file @
1ebc9b48
...
...
@@ -110,7 +110,7 @@ class Media : public IMedia, public DatabaseHelpers<Media, policy::MediaTable>
virtual
unsigned
int
insertionDate
()
const
override
;
virtual
unsigned
int
releaseDate
()
const
override
;
virtual
const
IMe
diaMe
tadata
&
metadata
(
MetadataType
type
)
const
override
;
virtual
const
IMetadata
&
metadata
(
MetadataType
type
)
const
override
;
virtual
bool
setMetadata
(
MetadataType
type
,
const
std
::
string
&
value
)
override
;
virtual
bool
setMetadata
(
MetadataType
type
,
int64_t
value
)
override
;
...
...
@@ -159,7 +159,7 @@ private:
mutable
Cache
<
ShowEpisodePtr
>
m_showEpisode
;
mutable
Cache
<
MoviePtr
>
m_movie
;
mutable
Cache
<
std
::
vector
<
FilePtr
>>
m_files
;
mutable
Media
Metadata
m_metadata
;
mutable
Metadata
m_metadata
;
mutable
Cache
<
std
::
shared_ptr
<
Thumbnail
>>
m_thumbnail
;
bool
m_changed
;
...
...
src/MediaLibrary.cpp
View file @
1ebc9b48
...
...
@@ -169,7 +169,7 @@ void MediaLibrary::createAllTables()
History
::
createTable
(
m_dbConnection
.
get
()
);
Settings
::
createTable
(
m_dbConnection
.
get
()
);
parser
::
Task
::
createTable
(
m_dbConnection
.
get
()
);
Media
Metadata
::
createTable
(
m_dbConnection
.
get
()
);
Metadata
::
createTable
(
m_dbConnection
.
get
()
);
}
void
MediaLibrary
::
createAllTriggers
()
...
...
src/Metadata.cpp
View file @
1ebc9b48
...
...
@@ -33,44 +33,45 @@
namespace
medialibrary
{
const
std
::
string
policy
::
Media
MetadataTable
::
Name
=
"MediaMetadata"
;
const
std
::
string
policy
::
MetadataTable
::
Name
=
"MediaMetadata"
;
Media
Metadata
::
Record
::
Record
(
IMedia
::
MetadataType
t
,
std
::
string
v
)
Metadata
::
Record
::
Record
(
uint32_t
t
,
std
::
string
v
)
:
m_type
(
t
)
,
m_value
(
std
::
move
(
v
)
)
,
m_isSet
(
true
)
{
}
Media
Metadata
::
Record
::
Record
(
IMedia
::
MetadataType
t
)
Metadata
::
Record
::
Record
(
uint32_t
t
)
:
m_type
(
t
)
,
m_isSet
(
false
)
{
}
bool
Media
Metadata
::
Record
::
isSet
()
const
bool
Metadata
::
Record
::
isSet
()
const
{
return
m_isSet
;
}
int64_t
Media
Metadata
::
Record
::
integer
()
const
int64_t
Metadata
::
Record
::
integer
()
const
{
return
atoll
(
m_value
.
c_str
()
);
}
const
std
::
string
&
Media
Metadata
::
Record
::
str
()
const
const
std
::
string
&
Metadata
::
Record
::
str
()
const
{
return
m_value
;
}
Media
Metadata
::
Media
Metadata
(
MediaLibraryPtr
ml
)
Metadata
::
Metadata
(
MediaLibraryPtr
ml
,
IMetadata
::
EntityType
entityType
)
:
m_ml
(
ml
)
,
m_entityType
(
entityType
)
,
m_nbMeta
(
0
)
,
m_entityId
(
0
)
{
}
void
Media
Metadata
::
init
(
int64_t
entityId
,
uint32_t
nbMeta
)
void
Metadata
::
init
(
int64_t
entityId
,
uint32_t
nbMeta
)
{
if
(
isReady
()
==
true
)
return
;
...
...
@@ -82,26 +83,27 @@ void MediaMetadata::init( int64_t entityId, uint32_t nbMeta )
// to another IMediaMetadata held by another thread.
// This guarantees the vector will not grow afterward.
m_records
.
reserve
(
m_nbMeta
);
static
const
std
::
string
req
=
"SELECT * FROM "
+
policy
::
Media
MetadataTable
::
Name
+
" WHERE id_media = ?"
;
static
const
std
::
string
req
=
"SELECT * FROM "
+
policy
::
MetadataTable
::
Name
+
" WHERE id_media =
? AND entity_type =
?"
;
auto
conn
=
m_ml
->
getConn
();
auto
ctx
=
conn
->
acquireReadContext
();
sqlite
::
Statement
stmt
(
conn
->
handle
(),
req
);
stmt
.
execute
(
m_entityId
);
stmt
.
execute
(
m_entityId
,
m_entityType
);
for
(
sqlite
::
Row
row
=
stmt
.
row
();
row
!=
nullptr
;
row
=
stmt
.
row
()
)
{
assert
(
row
.
load
<
int64_t
>
(
0
)
==
m_entityId
);
m_records
.
emplace_back
(
row
.
load
<
decltype
(
Record
::
m_type
)
>
(
1
),
row
.
load
<
decltype
(
Record
::
m_value
)
>
(
2
)
);
assert
(
row
.
load
<
IMetadata
::
EntityType
>
(
1
)
==
m_entityType
);
m_records
.
emplace_back
(
row
.
load
<
decltype
(
Record
::
m_type
)
>
(
2
),
row
.
load
<
decltype
(
Record
::
m_value
)
>
(
3
)
);
}
}
bool
Media
Metadata
::
isReady
()
const
bool
Metadata
::
isReady
()
const
{
return
m_nbMeta
!=
0
;
}
IMe
diaMe
tadata
&
Media
Metadata
::
get
(
IMedia
::
MetadataType
type
)
const
IMetadata
&
Metadata
::
get
(
uint32_t
type
)
const
{
assert
(
isReady
()
==
true
);
...
...
@@ -118,7 +120,7 @@ IMediaMetadata&MediaMetadata::get( IMedia::MetadataType type ) const
return
*
it
;
}
bool
Media
Metadata
::
set
(
IMedia
::
MetadataType
type
,
const
std
::
string
&
value
)
bool
Metadata
::
set
(
uint32_t
type
,
const
std
::
string
&
value
)
{
assert
(
isReady
()
==
true
);
...
...
@@ -131,9 +133,10 @@ bool MediaMetadata::set( IMedia::MetadataType type, const std::string& value )
m_records
.
emplace_back
(
type
,
value
);
try
{
static
const
std
::
string
req
=
"INSERT OR REPLACE INTO "
+
policy
::
MediaMetadataTable
::
Name
+
"(id_media, type, value) VALUES(?, ?, ?)"
;
return
sqlite
::
Tools
::
executeInsert
(
m_ml
->
getConn
(),
req
,
m_entityId
,
type
,
value
);
static
const
std
::
string
req
=
"INSERT OR REPLACE INTO "
+
policy
::
MetadataTable
::
Name
+
"(id_media, entity_type, type, value) VALUES(?, ?, ?, ?)"
;
return
sqlite
::
Tools
::
executeInsert
(
m_ml
->
getConn
(),
req
,
m_entityId
,
m_entityType
,
type
,
value
);
}
catch
(
const
sqlite
::
errors
::
Generic
&
ex
)
{
...
...
@@ -142,16 +145,24 @@ bool MediaMetadata::set( IMedia::MetadataType type, const std::string& value )
}
}
bool
Media
Metadata
::
set
(
IMedia
::
MetadataType
type
,
int64_t
value
)
bool
Metadata
::
set
(
uint32_t
type
,
int64_t
value
)
{
auto
str
=
std
::
to_string
(
value
);
return
set
(
type
,
str
);
}
void
Media
Metadata
::
createTable
(
sqlite
::
Connection
*
connection
)
void
Metadata
::
unset
(
sqlite
::
Connection
*
dbConn
,
IMetadata
::
EntityType
entityType
,
uint32_t
type
)
{
const
std
::
string
req
=
"CREATE TABLE IF NOT EXISTS "
+
policy
::
MediaMetadataTable
::
Name
+
"("
static
const
std
::
string
req
=
"DELETE FROM "
+
policy
::
MetadataTable
::
Name
+
" WHERE entity_type = ? AND type = ? "
;
sqlite
::
Tools
::
executeDelete
(
dbConn
,
req
,
entityType
,
type
);
}
void
Metadata
::
createTable
(
sqlite
::
Connection
*
connection
)
{
const
std
::
string
req
=
"CREATE TABLE IF NOT EXISTS "
+
policy
::
MetadataTable
::
Name
+
"("
"id_media INTEGER,"
"entity_type INTEGER,"
"type INTEGER,"
"value TEXT,"
"PRIMARY KEY (id_media, type)"
...
...
@@ -159,7 +170,7 @@ void MediaMetadata::createTable(sqlite::Connection* connection)
sqlite
::
Tools
::
executeRequest
(
connection
,
req
);
}
void
Media
Metadata
::
Record
::
set
(
const
std
::
string
&
value
)
void
Metadata
::
Record
::
set
(
const
std
::
string
&
value
)
{
m_value
=
value
;
m_isSet
=
true
;
...
...
src/Metadata.h
View file @
1ebc9b48
...
...
@@ -36,16 +36,16 @@ class Connection;
namespace
policy
{
struct
Media
MetadataTable
struct
MetadataTable
{
static
const
std
::
string
Name
;
};
}
class
Media
Metadata
class
Metadata
{
public:
Media
Metadata
(
MediaLibraryPtr
ml
);
Metadata
(
MediaLibraryPtr
ml
,
IMetadata
::
EntityType
entityType
);
// We have to "lazy init" this object since during containing object creation,
// we might not know the ID yet (for instance. when instantiating the
...
...
@@ -53,34 +53,37 @@ public:
void
init
(
int64_t
entityId
,
uint32_t
nbMeta
);
bool
isReady
()
const
;
IMediaMetadata
&
get
(
IMedia
::
MetadataType
type
)
const
;
bool
set
(
IMedia
::
MetadataType
type
,
const
std
::
string
&
value
);
bool
set
(
IMedia
::
MetadataType
type
,
int64_t
value
);
IMetadata
&
get
(
uint32_t
type
)
const
;
bool
set
(
uint32_t
type
,
const
std
::
string
&
value
);
bool
set
(
uint32_t
type
,
int64_t
value
);
static
void
unset
(
sqlite
::
Connection
*
dbConn
,
IMetadata
::
EntityType
entityType
,
uint32_t
type
);
static
void
createTable
(
sqlite
::
Connection
*
connection
);
private:
class
Record
:
public
IMe
diaMe
tadata
class
Record
:
public
IMetadata
{
public:
virtual
~
Record
()
=
default
;
Record
(
IMedia
::
MetadataType
t
,
std
::
string
v
);
Record
(
IMedia
::
MetadataType
t
);
Record
(
uint32_t
t
,
std
::
string
v
);
Record
(
uint32_t
t
);
virtual
bool
isSet
()
const
override
;
virtual
int64_t
integer
()
const
override
;
virtual
const
std
::
string
&
str
()
const
override
;
void
set
(
const
std
::
string
&
value
);
private:
IMedia
::
MetadataType
m_type
;
uint32_t
m_type
;
std
::
string
m_value
;
bool
m_isSet
;
friend
Media
Metadata
;
friend
Metadata
;
};
private:
MediaLibraryPtr
m_ml
;
IMetadata
::
EntityType
m_entityType
;
uint32_t
m_nbMeta
;
int64_t
m_entityId
;
mutable
std
::
vector
<
Record
>
m_records
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment