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
38a2b060
Commit
38a2b060
authored
Jan 21, 2016
by
Hugo Beauzée-Luyssen
Browse files
Use a common search method for all media
parent
18602f8b
Changes
8
Hide whitespace changes
Inline
Side-by-side
include/IMediaLibrary.h
View file @
38a2b060
...
...
@@ -115,7 +115,7 @@ class IMediaLibrary
/**
* Search
*/
virtual
std
::
vector
<
MediaPtr
>
search
AlbumTracks
(
const
std
::
string
&
title
)
const
=
0
;
virtual
std
::
vector
<
MediaPtr
>
search
Media
(
const
std
::
string
&
pattern
)
const
=
0
;
virtual
std
::
vector
<
PlaylistPtr
>
searchPlaylists
(
const
std
::
string
&
name
)
const
=
0
;
virtual
std
::
vector
<
AlbumPtr
>
searchAlbums
(
const
std
::
string
&
pattern
)
const
=
0
;
...
...
src/AlbumTrack.cpp
View file @
38a2b060
...
...
@@ -112,25 +112,9 @@ bool AlbumTrack::createTable( DBConnection dbConnection )
" BEGIN"
" UPDATE "
+
policy
::
AlbumTrackTable
::
Name
+
" SET is_present = new.is_present WHERE media_id = new.id_media;"
" END"
;
static
const
std
::
string
vtableReq
=
"CREATE VIRTUAL TABLE IF NOT EXISTS "
+
policy
::
AlbumTrackTable
::
Name
+
"Fts USING FTS3("
"title"
")"
;
static
const
std
::
string
vtableTrigger
=
"CREATE TRIGGER IF NOT EXISTS delete_fts_track"
" AFTER DELETE ON "
+
policy
::
MediaTable
::
Name
+
" BEGIN"
" DELETE FROM "
+
policy
::
AlbumTrackTable
::
Name
+
"Fts WHERE rowid = old.id_media;"
" END"
;
static
const
std
::
string
vtableTrigger2
=
"CREATE TRIGGER IF NOT EXISTS update_fts_track"
" AFTER UPDATE OF title ON "
+
policy
::
MediaTable
::
Name
+
" BEGIN"
" UPDATE "
+
policy
::
AlbumTrackTable
::
Name
+
"Fts SET title = new.title WHERE rowid = new.id_media;"
" END"
;
return
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
req
)
&&
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
triggerReq
)
&&
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
vtableReq
)
&&
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
vtableTrigger
)
&&
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
vtableTrigger2
);
sqlite
::
Tools
::
executeRequest
(
dbConnection
,
triggerReq
);
}
std
::
shared_ptr
<
AlbumTrack
>
AlbumTrack
::
create
(
DBConnection
dbConnection
,
unsigned
int
albumId
,
const
Media
&
media
,
unsigned
int
trackNb
,
unsigned
int
discNumber
)
...
...
@@ -141,9 +125,6 @@ std::shared_ptr<AlbumTrack> AlbumTrack::create( DBConnection dbConnection, unsig
if
(
insert
(
dbConnection
,
self
,
req
,
media
.
id
(),
trackNb
,
albumId
,
discNumber
)
==
false
)
return
nullptr
;
self
->
m_dbConnection
=
dbConnection
;
static
const
std
::
string
ftsReq
=
"INSERT INTO "
+
policy
::
AlbumTrackTable
::
Name
+
"Fts"
"(rowid, title) VALUES(?, ?)"
;
sqlite
::
Tools
::
insert
(
dbConnection
,
ftsReq
,
self
->
m_id
,
media
.
title
()
);
return
self
;
}
...
...
@@ -161,14 +142,6 @@ std::vector<AlbumTrackPtr> AlbumTrack::fromGenre( DBConnection dbConn, unsigned
return
fetchAll
<
IAlbumTrack
>
(
dbConn
,
req
,
genreId
);
}
std
::
vector
<
MediaPtr
>
AlbumTrack
::
search
(
DBConnection
dbConn
,
const
std
::
string
&
title
)
{
static
const
std
::
string
req
=
"SELECT * FROM "
+
policy
::
MediaTable
::
Name
+
" WHERE"
" id_media IN (SELECT rowid FROM "
+
policy
::
AlbumTrackTable
::
Name
+
"Fts"
" WHERE title MATCH ?)"
;
return
Media
::
fetchAll
<
IMedia
>
(
dbConn
,
req
,
title
+
"*"
);
}
GenrePtr
AlbumTrack
::
genre
()
{
auto
l
=
m_genre
.
lock
();
...
...
src/Media.cpp
View file @
38a2b060
...
...
@@ -346,7 +346,12 @@ bool Media::createTable( DBConnection connection )
"title TEXT,"
"is_present BOOLEAN NOT NULL DEFAULT 1"
")"
;
return
sqlite
::
Tools
::
executeRequest
(
connection
,
req
);
static
const
std
::
string
vtableReq
=
"CREATE VIRTUAL TABLE IF NOT EXISTS "
+
policy
::
MediaTable
::
Name
+
"Fts USING FTS3("
"title"
")"
;
return
sqlite
::
Tools
::
executeRequest
(
connection
,
req
)
&&
sqlite
::
Tools
::
executeRequest
(
connection
,
vtableReq
);
}
bool
Media
::
createTriggers
(
DBConnection
connection
)
...
...
@@ -365,8 +370,27 @@ bool Media::createTriggers( DBConnection connection )
"(SELECT COUNT(id_file) FROM "
+
policy
::
FileTable
::
Name
+
" WHERE media_id=old.media_id) = 0"
" AND id_media=old.media_id;"
" END;"
;
static
const
std
::
string
vtableInsertTrigger
=
"CREATE TRIGGER IF NOT EXISTS insert_media_fts"
" AFTER INSERT ON "
+
policy
::
MediaTable
::
Name
+
" BEGIN"
" INSERT INTO "
+
policy
::
MediaTable
::
Name
+
"Fts(rowid,title) VALUES(new.id_media, new.title);"
" END"
;
static
const
std
::
string
vtableDeleteTrigger
=
"CREATE TRIGGER IF NOT EXISTS delete_media_fts"
" AFTER DELETE ON "
+
policy
::
MediaTable
::
Name
+
" BEGIN"
" DELETE FROM "
+
policy
::
MediaTable
::
Name
+
"Fts WHERE rowid = old.id_media;"
" END"
;
static
const
std
::
string
vtableUpdateTitleTrigger2
=
"CREATE TRIGGER IF NOT EXISTS update_media_title_fts"
" AFTER UPDATE OF title ON "
+
policy
::
MediaTable
::
Name
+
" BEGIN"
" UPDATE "
+
policy
::
MediaTable
::
Name
+
"Fts SET title = new.title WHERE rowid = new.id_media;"
" END"
;
return
sqlite
::
Tools
::
executeRequest
(
connection
,
triggerReq
)
&&
sqlite
::
Tools
::
executeRequest
(
connection
,
triggerReq2
);
sqlite
::
Tools
::
executeRequest
(
connection
,
triggerReq2
)
&&
sqlite
::
Tools
::
executeRequest
(
connection
,
vtableInsertTrigger
)
&&
sqlite
::
Tools
::
executeRequest
(
connection
,
vtableDeleteTrigger
)
&&
sqlite
::
Tools
::
executeRequest
(
connection
,
vtableUpdateTitleTrigger2
);
}
bool
Media
::
addLabel
(
LabelPtr
label
)
...
...
@@ -390,3 +414,12 @@ bool Media::removeLabel( LabelPtr label )
const
char
*
req
=
"DELETE FROM LabelFileRelation WHERE label_id = ? AND media_id = ?"
;
return
sqlite
::
Tools
::
executeDelete
(
m_dbConnection
,
req
,
label
->
id
(),
m_id
);
}
std
::
vector
<
MediaPtr
>
Media
::
search
(
DBConnection
dbConn
,
const
std
::
string
&
title
)
{
static
const
std
::
string
req
=
"SELECT * FROM "
+
policy
::
MediaTable
::
Name
+
" WHERE"
" id_media IN (SELECT rowid FROM "
+
policy
::
MediaTable
::
Name
+
"Fts"
" WHERE "
+
policy
::
MediaTable
::
Name
+
"Fts MATCH ?)"
;
return
Media
::
fetchAll
<
IMedia
>
(
dbConn
,
req
,
title
+
"*"
);
}
src/Media.h
View file @
38a2b060
...
...
@@ -107,7 +107,10 @@ class Media : public IMedia, public DatabaseHelpers<Media, policy::MediaTable>
std
::
shared_ptr
<
File
>
addFile
(
const
fs
::
IFile
&
fileFs
,
Folder
&
parentFolder
,
fs
::
IDirectory
&
parentFolderFs
,
IFile
::
Type
type
);
void
removeFile
(
File
&
file
);
private:
static
std
::
vector
<
MediaPtr
>
search
(
DBConnection
dbConn
,
const
std
::
string
&
title
);
private:
DBConnection
m_dbConnection
;
// DB fields:
...
...
src/MediaLibrary.cpp
View file @
38a2b060
...
...
@@ -410,11 +410,11 @@ std::vector<HistoryPtr> MediaLibrary::history() const
return
History
::
fetch
(
m_dbConnection
.
get
()
);
}
std
::
vector
<
MediaPtr
>
MediaLibrary
::
search
AlbumTracks
(
const
std
::
string
&
title
)
const
std
::
vector
<
MediaPtr
>
MediaLibrary
::
search
Media
(
const
std
::
string
&
title
)
const
{
if
(
validateSearchPattern
(
title
)
==
false
)
return
{};
return
AlbumTrack
::
search
(
m_dbConnection
.
get
(),
title
);
return
Media
::
search
(
m_dbConnection
.
get
(),
title
);
}
std
::
vector
<
PlaylistPtr
>
MediaLibrary
::
searchPlaylists
(
const
std
::
string
&
name
)
const
...
...
src/MediaLibrary.h
View file @
38a2b060
...
...
@@ -90,7 +90,7 @@ class MediaLibrary : public IMediaLibrary
virtual
bool
addToHistory
(
const
std
::
string
&
mrl
);
virtual
std
::
vector
<
HistoryPtr
>
history
()
const
;
virtual
std
::
vector
<
MediaPtr
>
search
AlbumTracks
(
const
std
::
string
&
title
)
const
override
;
virtual
std
::
vector
<
MediaPtr
>
search
Media
(
const
std
::
string
&
title
)
const
override
;
virtual
std
::
vector
<
PlaylistPtr
>
searchPlaylists
(
const
std
::
string
&
name
)
const
override
;
virtual
std
::
vector
<
AlbumPtr
>
searchAlbums
(
const
std
::
string
&
pattern
)
const
override
;
...
...
test/unittest/AlbumTrackTests.cpp
View file @
38a2b060
...
...
@@ -112,59 +112,3 @@ TEST_F( AlbumTracks, SetGenre )
auto
t2
=
tracks
[
0
];
ASSERT_EQ
(
t
->
genre
()
->
id
(),
t2
->
albumTrack
()
->
genre
()
->
id
()
);
}
TEST_F
(
AlbumTracks
,
Search
)
{
auto
a
=
ml
->
createAlbum
(
"album"
);
for
(
auto
i
=
1u
;
i
<=
10u
;
++
i
)
{
auto
m
=
ml
->
addFile
(
"track "
+
std
::
to_string
(
i
)
+
".mp3"
);
a
->
addTrack
(
m
,
i
,
1
);
}
auto
tracks
=
ml
->
searchAlbumTracks
(
"tra"
);
ASSERT_EQ
(
10u
,
tracks
.
size
()
);
tracks
=
ml
->
searchAlbumTracks
(
"track 1"
);
ASSERT_EQ
(
2u
,
tracks
.
size
()
);
tracks
=
ml
->
searchAlbumTracks
(
"grouik"
);
ASSERT_EQ
(
0u
,
tracks
.
size
()
);
tracks
=
ml
->
searchAlbumTracks
(
"rack"
);
ASSERT_EQ
(
0u
,
tracks
.
size
()
);
}
TEST_F
(
AlbumTracks
,
SearchAfterEdit
)
{
auto
m
=
ml
->
addFile
(
"media.mp3"
);
auto
a
=
ml
->
createAlbum
(
"album"
);
a
->
addTrack
(
m
,
1
,
1
);
auto
tracks
=
ml
->
searchAlbumTracks
(
"media"
);
ASSERT_EQ
(
1u
,
tracks
.
size
()
);
m
->
setTitle
(
"otters are awesome"
);
m
->
save
();
tracks
=
ml
->
searchAlbumTracks
(
"media"
);
ASSERT_EQ
(
0u
,
tracks
.
size
()
);
tracks
=
ml
->
searchAlbumTracks
(
"otters"
);
ASSERT_EQ
(
1u
,
tracks
.
size
()
);
}
TEST_F
(
AlbumTracks
,
SearchAfterDelete
)
{
auto
m
=
ml
->
addFile
(
"media.mp3"
);
auto
a
=
ml
->
createAlbum
(
"album"
);
a
->
addTrack
(
m
,
1
,
1
);
auto
tracks
=
ml
->
searchAlbumTracks
(
"media"
);
ASSERT_EQ
(
1u
,
tracks
.
size
()
);
auto
f
=
m
->
files
()[
0
];
m
->
removeFile
(
static_cast
<
File
&>
(
*
f
)
);
tracks
=
ml
->
searchAlbumTracks
(
"media"
);
ASSERT_EQ
(
0u
,
tracks
.
size
()
);
}
test/unittest/MediaTests.cpp
View file @
38a2b060
...
...
@@ -144,3 +144,53 @@ TEST_F( Medias, Rating )
f
=
ml
->
media
(
f
->
id
()
);
ASSERT_EQ
(
12345
,
f
->
rating
()
);
}
TEST_F
(
Medias
,
Search
)
{
for
(
auto
i
=
1u
;
i
<=
10u
;
++
i
)
{
auto
m
=
ml
->
addFile
(
"track "
+
std
::
to_string
(
i
)
+
".mp3"
);
}
auto
media
=
ml
->
searchMedia
(
"tra"
);
ASSERT_EQ
(
10u
,
media
.
size
()
);
media
=
ml
->
searchMedia
(
"track 1"
);
ASSERT_EQ
(
2u
,
media
.
size
()
);
media
=
ml
->
searchMedia
(
"grouik"
);
ASSERT_EQ
(
0u
,
media
.
size
()
);
media
=
ml
->
searchMedia
(
"rack"
);
ASSERT_EQ
(
0u
,
media
.
size
()
);
}
TEST_F
(
Medias
,
SearchAfterEdit
)
{
auto
m
=
ml
->
addFile
(
"media.mp3"
);
auto
media
=
ml
->
searchMedia
(
"media"
);
ASSERT_EQ
(
1u
,
media
.
size
()
);
m
->
setTitle
(
"otters are awesome"
);
m
->
save
();
media
=
ml
->
searchMedia
(
"media"
);
ASSERT_EQ
(
0u
,
media
.
size
()
);
media
=
ml
->
searchMedia
(
"otters"
);
ASSERT_EQ
(
1u
,
media
.
size
()
);
}
TEST_F
(
Medias
,
SearchAfterDelete
)
{
auto
m
=
ml
->
addFile
(
"media.mp3"
);
auto
media
=
ml
->
searchMedia
(
"media"
);
ASSERT_EQ
(
1u
,
media
.
size
()
);
auto
f
=
m
->
files
()[
0
];
m
->
removeFile
(
static_cast
<
File
&>
(
*
f
)
);
media
=
ml
->
searchMedia
(
"media"
);
ASSERT_EQ
(
0u
,
media
.
size
()
);
}
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