Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
VideoLAN
medialibrary
Commits
30eaf90c
Commit
30eaf90c
authored
May 17, 2014
by
Hugo Beauzée-Luyssen
Browse files
Rework File/Label API to make it more natural
parent
090bb277
Changes
10
Hide whitespace changes
Inline
Side-by-side
include/IFile.h
View file @
30eaf90c
...
...
@@ -3,10 +3,11 @@
#include
<vector>
#include
<memory>
#include
"IMediaLibrary.h"
#include
"ITrackInformation.h"
class
IAlbumTrack
;
class
ILabel
;
class
IShowEpisode
;
class
ITrackInformation
;
...
...
@@ -21,9 +22,9 @@ class IFile
virtual
std
::
shared_ptr
<
IShowEpisode
>
showEpisode
()
=
0
;
virtual
int
playCount
()
=
0
;
virtual
const
std
::
string
&
mrl
()
=
0
;
virtual
std
::
shared_ptr
<
ILabel
>
addLabel
(
const
std
::
string
&
label
)
=
0
;
virtual
bool
removeLabel
(
const
std
::
shared_ptr
<
I
Label
>&
label
)
=
0
;
virtual
const
std
::
vector
<
std
::
shared_ptr
<
ILabel
>>
&
labels
()
=
0
;
virtual
bool
addLabel
(
LabelPtr
label
)
=
0
;
virtual
bool
removeLabel
(
Label
Ptr
label
)
=
0
;
virtual
std
::
vector
<
std
::
shared_ptr
<
ILabel
>
>
labels
()
=
0
;
};
#endif // IFILE_H
include/ILabel.h
View file @
30eaf90c
...
...
@@ -4,7 +4,7 @@
#include
<memory>
#include
<vector>
class
IFile
;
#include
"IMediaLibrary.h"
class
ILabel
{
...
...
@@ -13,9 +13,7 @@ class ILabel
virtual
unsigned
int
id
()
const
=
0
;
virtual
const
std
::
string
&
name
()
=
0
;
virtual
std
::
vector
<
std
::
shared_ptr
<
IFile
>>&
files
()
=
0
;
virtual
bool
link
(
IFile
*
file
)
=
0
;
virtual
bool
unlink
(
IFile
*
file
)
const
=
0
;
virtual
std
::
vector
<
FilePtr
>&
files
()
=
0
;
};
#endif // ILABEL_H
include/IMediaLibrary.h
View file @
30eaf90c
...
...
@@ -6,8 +6,10 @@
#include
<memory>
class
IFile
;
class
ILabel
;
typedef
std
::
shared_ptr
<
IFile
>
FilePtr
;
typedef
std
::
shared_ptr
<
ILabel
>
LabelPtr
;
class
IMediaLibrary
{
...
...
@@ -16,6 +18,7 @@ class IMediaLibrary
virtual
bool
initialize
(
const
std
::
string
&
dbPath
)
=
0
;
virtual
FilePtr
addFile
(
const
std
::
string
&
path
)
=
0
;
virtual
FilePtr
file
(
const
std
::
string
&
path
)
=
0
;
virtual
LabelPtr
createLabel
(
const
std
::
string
&
label
)
=
0
;
virtual
bool
files
(
std
::
vector
<
FilePtr
>&
res
)
=
0
;
};
...
...
src/File.cpp
View file @
30eaf90c
...
...
@@ -14,7 +14,6 @@ const std::string policy::FileTable::CacheColumn = "mrl";
File
::
File
(
sqlite3
*
dbConnection
,
sqlite3_stmt
*
stmt
)
:
m_dbConnection
(
dbConnection
)
,
m_labels
(
nullptr
)
{
m_id
=
sqlite3_column_int
(
stmt
,
0
);
m_type
=
(
Type
)
sqlite3_column_int
(
stmt
,
1
);
...
...
@@ -34,7 +33,6 @@ File::File( const std::string& mrl )
,
m_playCount
(
0
)
,
m_showEpisodeId
(
0
)
,
m_mrl
(
mrl
)
,
m_labels
(
nullptr
)
{
}
...
...
@@ -87,17 +85,14 @@ std::shared_ptr<IShowEpisode> File::showEpisode()
return
m_showEpisode
;
}
const
std
::
vector
<
std
::
shared_ptr
<
ILabel
>>
&
File
::
labels
()
std
::
vector
<
std
::
shared_ptr
<
ILabel
>
>
File
::
labels
()
{
if
(
m_labels
==
nullptr
)
{
m_labels
=
new
std
::
vector
<
std
::
shared_ptr
<
ILabel
>>
;
const
char
*
req
=
"SELECT l.* FROM Label l "
"LEFT JOIN LabelFileRelation lfr ON lfr.id_label = l.id_label "
"WHERE lfr.id_file = ?"
;
SqliteTools
::
fetchAll
<
Label
>
(
m_dbConnection
,
req
,
m_id
,
*
m_labels
);
}
return
*
m_labels
;
std
::
vector
<
std
::
shared_ptr
<
ILabel
>
>
labels
;
const
char
*
req
=
"SELECT l.* FROM Label l "
"LEFT JOIN LabelFileRelation lfr ON lfr.id_label = l.id_label "
"WHERE lfr.id_file = ?"
;
SqliteTools
::
fetchAll
<
Label
>
(
m_dbConnection
,
req
,
m_id
,
labels
);
return
labels
;
}
int
File
::
playCount
()
...
...
@@ -110,36 +105,6 @@ const std::string& File::mrl()
return
m_mrl
;
}
std
::
shared_ptr
<
ILabel
>
File
::
addLabel
(
const
std
::
string
&
label
)
{
auto
l
=
Label
::
create
(
label
);
if
(
l
->
insert
(
m_dbConnection
)
==
false
)
{
return
nullptr
;
}
l
->
link
(
this
);
return
l
;
}
bool
File
::
removeLabel
(
const
std
::
shared_ptr
<
ILabel
>&
label
)
{
if
(
m_labels
!=
false
)
{
auto
it
=
m_labels
->
begin
();
auto
ite
=
m_labels
->
end
();
while
(
it
!=
ite
)
{
if
(
(
*
it
)
->
id
()
==
label
->
id
()
)
break
;
++
it
;
}
if
(
it
==
ite
)
return
false
;
m_labels
->
erase
(
it
);
}
return
label
->
unlink
(
this
);
}
unsigned
int
File
::
id
()
const
{
return
m_id
;
...
...
@@ -160,6 +125,47 @@ bool File::createTable(sqlite3* connection)
return
SqliteTools
::
createTable
(
connection
,
req
);
}
bool
File
::
addLabel
(
LabelPtr
label
)
{
if
(
m_dbConnection
==
nullptr
||
m_id
==
0
||
label
->
id
()
==
0
)
{
std
::
cerr
<<
"Both file & label need to be inserted in database before being linked together"
<<
std
::
endl
;
return
false
;
}
const
char
*
req
=
"INSERT INTO LabelFileRelation VALUES(?, ?)"
;
sqlite3_stmt
*
stmt
;
if
(
sqlite3_prepare_v2
(
m_dbConnection
,
req
,
-
1
,
&
stmt
,
NULL
)
!=
SQLITE_OK
)
{
std
::
cerr
<<
"Failed to insert record: "
<<
sqlite3_errmsg
(
m_dbConnection
)
<<
std
::
endl
;
return
false
;
}
sqlite3_bind_int
(
stmt
,
1
,
label
->
id
()
);
sqlite3_bind_int
(
stmt
,
2
,
m_id
);
bool
res
=
sqlite3_step
(
stmt
)
==
SQLITE_DONE
;
sqlite3_finalize
(
stmt
);
return
res
;
}
bool
File
::
removeLabel
(
LabelPtr
label
)
{
if
(
m_dbConnection
==
nullptr
||
m_id
==
0
||
label
->
id
()
==
0
)
{
std
::
cerr
<<
"Can't unlink a label/file not inserted in database"
<<
std
::
endl
;
return
false
;
}
const
char
*
req
=
"DELETE FROM LabelFileRelation WHERE id_label = ? AND id_file = ?"
;
sqlite3_stmt
*
stmt
;
if
(
sqlite3_prepare_v2
(
m_dbConnection
,
req
,
-
1
,
&
stmt
,
NULL
)
!=
SQLITE_OK
)
{
std
::
cerr
<<
"Failed to remove record: "
<<
sqlite3_errmsg
(
m_dbConnection
)
<<
std
::
endl
;
return
false
;
}
sqlite3_bind_int
(
stmt
,
1
,
label
->
id
()
);
sqlite3_bind_int
(
stmt
,
2
,
m_id
);
sqlite3_step
(
stmt
);
sqlite3_finalize
(
stmt
);
return
sqlite3_changes
(
m_dbConnection
)
>
0
;
}
const
std
::
string
&
policy
::
FileCache
::
key
(
const
std
::
shared_ptr
<
File
>
self
)
{
...
...
src/File.h
View file @
30eaf90c
...
...
@@ -56,11 +56,11 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy::
virtual
std
::
shared_ptr
<
IAlbumTrack
>
albumTrack
();
virtual
unsigned
int
duration
();
virtual
std
::
shared_ptr
<
IShowEpisode
>
showEpisode
();
virtual
const
std
::
vector
<
std
::
shared_ptr
<
ILabel
>>&
labels
();
virtual
bool
addLabel
(
LabelPtr
label
);
virtual
bool
removeLabel
(
LabelPtr
label
);
virtual
std
::
vector
<
std
::
shared_ptr
<
ILabel
>
>
labels
();
virtual
int
playCount
();
virtual
const
std
::
string
&
mrl
();
virtual
std
::
shared_ptr
<
ILabel
>
addLabel
(
const
std
::
string
&
label
);
virtual
bool
removeLabel
(
const
std
::
shared_ptr
<
ILabel
>&
label
);
private:
sqlite3
*
m_dbConnection
;
...
...
@@ -78,7 +78,6 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy::
Album
*
m_album
;
std
::
shared_ptr
<
AlbumTrack
>
m_albumTrack
;
std
::
shared_ptr
<
ShowEpisode
>
m_showEpisode
;
std
::
vector
<
std
::
shared_ptr
<
ILabel
>>*
m_labels
;
friend
class
Cache
<
File
,
IFile
,
policy
::
FileTable
,
policy
::
FileCache
>
;
};
...
...
src/Label.cpp
View file @
30eaf90c
...
...
@@ -36,7 +36,7 @@ const std::string& Label::name()
return
m_name
;
}
std
::
vector
<
std
::
shared_ptr
<
I
File
>
>&
Label
::
files
()
std
::
vector
<
File
Ptr
>&
Label
::
files
()
{
if
(
m_files
==
nullptr
)
{
...
...
@@ -86,44 +86,3 @@ bool Label::createTable(sqlite3* dbConnection)
return
SqliteTools
::
createTable
(
dbConnection
,
req
);
}
bool
Label
::
link
(
IFile
*
file
)
{
if
(
m_dbConnection
==
nullptr
||
m_id
==
0
)
{
std
::
cerr
<<
"A label needs to be inserted in database before being linked to a file"
<<
std
::
endl
;
return
false
;
}
const
char
*
req
=
"INSERT INTO LabelFileRelation VALUES(?, ?)"
;
sqlite3_stmt
*
stmt
;
if
(
sqlite3_prepare_v2
(
m_dbConnection
,
req
,
-
1
,
&
stmt
,
NULL
)
!=
SQLITE_OK
)
{
std
::
cerr
<<
"Failed to insert record: "
<<
sqlite3_errmsg
(
m_dbConnection
)
<<
std
::
endl
;
return
false
;
}
sqlite3_bind_int
(
stmt
,
1
,
m_id
);
sqlite3_bind_int
(
stmt
,
2
,
file
->
id
()
);
bool
res
=
sqlite3_step
(
stmt
)
==
SQLITE_DONE
;
sqlite3_finalize
(
stmt
);
return
res
;
}
bool
Label
::
unlink
(
IFile
*
file
)
const
{
if
(
m_dbConnection
==
nullptr
||
m_id
==
0
)
{
std
::
cerr
<<
"Can't unlink a label not inserted in database"
<<
std
::
endl
;
return
false
;
}
const
char
*
req
=
"DELETE FROM LabelFileRelation WHERE id_label = ? AND id_file = ?"
;
sqlite3_stmt
*
stmt
;
if
(
sqlite3_prepare_v2
(
m_dbConnection
,
req
,
-
1
,
&
stmt
,
NULL
)
!=
SQLITE_OK
)
{
std
::
cerr
<<
"Failed to remove record: "
<<
sqlite3_errmsg
(
m_dbConnection
)
<<
std
::
endl
;
return
false
;
}
sqlite3_bind_int
(
stmt
,
1
,
m_id
);
sqlite3_bind_int
(
stmt
,
2
,
file
->
id
()
);
bool
res
=
sqlite3_step
(
stmt
)
==
SQLITE_DONE
;
sqlite3_finalize
(
stmt
);
return
res
;
}
src/Label.h
View file @
30eaf90c
...
...
@@ -28,12 +28,10 @@ class Label : public ILabel, public Cache<Label, ILabel, policy::LabelTable>
public:
virtual
unsigned
int
id
()
const
;
virtual
const
std
::
string
&
name
();
virtual
std
::
vector
<
std
::
shared_ptr
<
I
File
>
>&
files
();
virtual
std
::
vector
<
File
Ptr
>&
files
();
bool
insert
(
sqlite3
*
dbConnection
);
static
bool
createTable
(
sqlite3
*
dbConnection
);
bool
link
(
IFile
*
file
);
bool
unlink
(
IFile
*
file
)
const
;
private:
sqlite3
*
m_dbConnection
;
unsigned
int
m_id
;
...
...
src/MediaLibrary.cpp
View file @
30eaf90c
...
...
@@ -50,3 +50,13 @@ FilePtr MediaLibrary::addFile( const std::string& path )
}
return
f
;
}
LabelPtr
MediaLibrary
::
createLabel
(
const
std
::
string
&
label
)
{
auto
l
=
Label
::
create
(
label
);
if
(
l
->
insert
(
m_dbConnection
)
==
false
)
{
return
nullptr
;
}
return
l
;
}
src/MediaLibrary.h
View file @
30eaf90c
...
...
@@ -13,9 +13,9 @@ class MediaLibrary : public IMediaLibrary
virtual
bool
files
(
std
::
vector
<
FilePtr
>&
res
);
virtual
FilePtr
file
(
const
std
::
string
&
path
);
virtual
FilePtr
addFile
(
const
std
::
string
&
path
);
virtual
LabelPtr
createLabel
(
const
std
::
string
&
label
);
private:
sqlite3
*
m_dbConnection
;
};
#endif // MEDIALIBRARY_H
test/Tests.cpp
View file @
30eaf90c
...
...
@@ -59,13 +59,20 @@ TEST_F( MLTest, FetchFile )
TEST_F
(
MLTest
,
AddLabel
)
{
auto
f
=
ml
->
addFile
(
"/dev/null"
);
auto
l1
=
f
->
add
Label
(
"sea otter"
);
auto
l2
=
f
->
add
Label
(
"cony the cone"
);
auto
l1
=
ml
->
create
Label
(
"sea otter"
);
auto
l2
=
ml
->
create
Label
(
"cony the cone"
);
ASSERT_
TRU
E
(
l1
!=
NULL
);
ASSERT_
TRU
E
(
l2
!=
NULL
);
ASSERT_
N
E
(
l1
,
nullptr
);
ASSERT_
N
E
(
l2
,
nullptr
);
auto
labels
=
f
->
labels
();
ASSERT_EQ
(
labels
.
size
(),
0u
);
f
->
addLabel
(
l1
);
f
->
addLabel
(
l2
);
labels
=
f
->
labels
();
ASSERT_EQ
(
labels
.
size
(),
2u
);
ASSERT_EQ
(
labels
[
0
]
->
name
(),
"sea otter"
);
ASSERT_EQ
(
labels
[
1
]
->
name
(),
"cony the cone"
);
...
...
@@ -74,8 +81,11 @@ TEST_F( MLTest, AddLabel )
TEST_F
(
MLTest
,
RemoveLabel
)
{
auto
f
=
ml
->
addFile
(
"/dev/null"
);
auto
l1
=
f
->
addLabel
(
"sea otter"
);
auto
l2
=
f
->
addLabel
(
"cony the cone"
);
auto
l1
=
ml
->
createLabel
(
"sea otter"
);
auto
l2
=
ml
->
createLabel
(
"cony the cone"
);
f
->
addLabel
(
l1
);
f
->
addLabel
(
l2
);
auto
labels
=
f
->
labels
();
ASSERT_EQ
(
labels
.
size
(),
2u
);
...
...
@@ -110,3 +120,5 @@ TEST_F( MLTest, RemoveLabel )
labels
=
f2
->
labels
();
ASSERT_EQ
(
labels
.
size
(),
0u
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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