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
3287620b
Commit
3287620b
authored
Nov 12, 2015
by
Hugo Beauzée-Luyssen
Browse files
Move SqliteTable in its own header
parent
e9f2b4d8
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/Album.h
View file @
3287620b
...
...
@@ -29,7 +29,7 @@
#include
"IMediaLibrary.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
#include
"IAlbum.h"
class
Album
;
...
...
src/AlbumTrack.h
View file @
3287620b
...
...
@@ -28,7 +28,7 @@
#include
"IAlbumTrack.h"
#include
"IMediaLibrary.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
class
Album
;
class
AlbumTrack
;
...
...
src/Artist.h
View file @
3287620b
...
...
@@ -22,7 +22,7 @@
#pragma once
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
#include
"IArtist.h"
#include
"IMediaLibrary.h"
...
...
src/AudioTrack.h
View file @
3287620b
...
...
@@ -25,7 +25,7 @@
#include
"IAudioTrack.h"
#include
"IMediaLibrary.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
class
AudioTrack
;
...
...
src/Folder.h
View file @
3287620b
...
...
@@ -22,7 +22,7 @@
#pragma once
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
#include
"IFolder.h"
#include
<sqlite3.h>
...
...
src/Label.h
View file @
3287620b
...
...
@@ -30,7 +30,7 @@ class Media;
class
Label
;
#include
"ILabel.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
namespace
policy
{
...
...
src/Media.h
View file @
3287620b
...
...
@@ -27,7 +27,7 @@
#include
<sqlite3.h>
#include
"IMedia.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
class
Album
;
...
...
src/Movie.h
View file @
3287620b
...
...
@@ -25,7 +25,7 @@
#include
"IMovie.h"
#include
<sqlite3.h>
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
class
Movie
;
...
...
src/Show.h
View file @
3287620b
...
...
@@ -25,7 +25,7 @@
#include
<sqlite3.h>
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
#include
"IMediaLibrary.h"
#include
"IShow.h"
...
...
src/ShowEpisode.h
View file @
3287620b
...
...
@@ -31,7 +31,7 @@ class ShowEpisode;
#include
"IMediaLibrary.h"
#include
"IShowEpisode.h"
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
namespace
policy
{
...
...
src/VideoTrack.h
View file @
3287620b
...
...
@@ -23,7 +23,7 @@
#ifndef VIDEOTRACK_H
#define VIDEOTRACK_H
#include
"database/
Cach
e.h"
#include
"database/
SqliteTabl
e.h"
#include
"IVideoTrack.h"
#include
<sqlite3.h>
...
...
src/database/Cache.h
View file @
3287620b
...
...
@@ -108,126 +108,4 @@ template <typename IMPL, typename CACHEPOLICY>
std
::
recursive_mutex
Cache
<
IMPL
,
CACHEPOLICY
>::
Mutex
;
/**
* This utility class eases up the implementation of caching.
*
* It is driven by 2 policy classes:
* - TABLEPOLICY describes the basics required to fetch a record. It has 2 static fields:
* - Name: the table name
* - CacheColumn: The column used to cache records.
* - CACHEPOLICY describes which column to use for caching by providing two "key" methods.
* One that takes a sqlite::Row and one that takes an instance of the type being cached
*
* The default CACHEPOLICY implementation bases itself on an unsigned int column, assumed
* to be the primary key, at index 0 of a fetch statement.
*
* Other template parameter:
* - IMPL: The actual implementation. Typically the type that inherits this class
* - INTF: An interface that express the type. This is used when fetching containers, as they
* are not polymorphic.
*
* How to use it:
* - Inherit this class and specify the template parameter & policies accordingly
* - Make this class a friend class of the class you inherit from
*/
template
<
typename
IMPL
,
typename
TABLEPOLICY
,
typename
CACHEPOLICY
=
PrimaryKeyCacheKeyPolicy
>
class
Table
{
using
_Cache
=
Cache
<
IMPL
,
CACHEPOLICY
>
;
public:
static
std
::
shared_ptr
<
IMPL
>
fetch
(
DBConnection
dbConnection
,
const
typename
CACHEPOLICY
::
KeyType
&
key
)
{
auto
l
=
_Cache
::
lock
();
auto
res
=
_Cache
::
load
(
key
);
if
(
res
!=
nullptr
)
return
res
;
static
const
std
::
string
req
=
"SELECT * FROM "
+
TABLEPOLICY
::
Name
+
" WHERE "
+
TABLEPOLICY
::
CacheColumn
+
" = ?"
;
res
=
sqlite
::
Tools
::
fetchOne
<
IMPL
>
(
dbConnection
,
req
,
key
);
if
(
res
==
nullptr
)
return
nullptr
;
_Cache
::
store
(
res
);
return
res
;
}
template
<
typename
...
Args
>
static
std
::
shared_ptr
<
IMPL
>
fetchOne
(
DBConnection
dbConnection
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
return
sqlite
::
Tools
::
fetchOne
<
IMPL
>
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
}
/*
* Will fetch all elements from the database & cache them.
*/
template
<
typename
INTF
=
IMPL
>
static
std
::
vector
<
std
::
shared_ptr
<
INTF
>>
fetchAll
(
DBConnection
dbConnection
)
{
static
const
std
::
string
req
=
"SELECT * FROM "
+
TABLEPOLICY
::
Name
;
// Lock the cache mutex before attempting to acquire a context, otherwise
// we could have a thread locking cache then DB, and a thread locking DB then cache
auto
l
=
_Cache
::
lock
();
return
sqlite
::
Tools
::
fetchAll
<
IMPL
,
INTF
>
(
dbConnection
,
req
);
}
template
<
typename
INTF
,
typename
...
Args
>
static
std
::
vector
<
std
::
shared_ptr
<
INTF
>>
fetchAll
(
DBConnection
dbConnection
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
auto
l
=
_Cache
::
lock
();
return
sqlite
::
Tools
::
fetchAll
<
IMPL
,
INTF
>
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
}
static
std
::
shared_ptr
<
IMPL
>
load
(
DBConnection
dbConnection
,
sqlite
::
Row
&
row
)
{
auto
l
=
_Cache
::
lock
();
auto
res
=
_Cache
::
load
(
row
);
if
(
res
!=
nullptr
)
return
res
;
res
=
std
::
make_shared
<
IMPL
>
(
dbConnection
,
row
);
_Cache
::
store
(
res
);
return
res
;
}
static
bool
destroy
(
DBConnection
dbConnection
,
const
typename
CACHEPOLICY
::
KeyType
&
key
)
{
auto
l
=
_Cache
::
lock
();
_Cache
::
discard
(
key
);
static
const
std
::
string
req
=
"DELETE FROM "
+
TABLEPOLICY
::
Name
+
" WHERE "
+
TABLEPOLICY
::
CacheColumn
+
" = ?"
;
return
sqlite
::
Tools
::
executeDelete
(
dbConnection
,
req
,
key
);
}
template
<
typename
T
>
static
bool
destroy
(
DBConnection
dbConnection
,
const
T
*
self
)
{
const
auto
&
key
=
CACHEPOLICY
::
key
(
self
);
return
destroy
(
dbConnection
,
key
);
}
static
void
clear
()
{
auto
l
=
_Cache
::
lock
();
_Cache
::
clear
();
}
protected:
/*
* Create a new instance of the cache class.
*/
template
<
typename
...
Args
>
static
bool
insert
(
DBConnection
dbConnection
,
std
::
shared_ptr
<
IMPL
>
self
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
auto
l
=
_Cache
::
lock
();
unsigned
int
pKey
=
sqlite
::
Tools
::
insert
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
if
(
pKey
==
0
)
return
false
;
(
self
.
get
())
->*
TABLEPOLICY
::
PrimaryKey
=
pKey
;
_Cache
::
store
(
self
);
return
true
;
}
};
#endif // CACHE_H
src/database/SqliteTable.h
0 → 100644
View file @
3287620b
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include
"Cache.h"
template
<
typename
IMPL
,
typename
TABLEPOLICY
,
typename
CACHEPOLICY
=
PrimaryKeyCacheKeyPolicy
>
class
Table
{
using
_Cache
=
Cache
<
IMPL
,
CACHEPOLICY
>
;
public:
static
std
::
shared_ptr
<
IMPL
>
fetch
(
DBConnection
dbConnection
,
const
typename
CACHEPOLICY
::
KeyType
&
key
)
{
auto
l
=
_Cache
::
lock
();
auto
res
=
_Cache
::
load
(
key
);
if
(
res
!=
nullptr
)
return
res
;
static
const
std
::
string
req
=
"SELECT * FROM "
+
TABLEPOLICY
::
Name
+
" WHERE "
+
TABLEPOLICY
::
CacheColumn
+
" = ?"
;
res
=
sqlite
::
Tools
::
fetchOne
<
IMPL
>
(
dbConnection
,
req
,
key
);
if
(
res
==
nullptr
)
return
nullptr
;
_Cache
::
store
(
res
);
return
res
;
}
template
<
typename
...
Args
>
static
std
::
shared_ptr
<
IMPL
>
fetchOne
(
DBConnection
dbConnection
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
return
sqlite
::
Tools
::
fetchOne
<
IMPL
>
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
}
/*
* Will fetch all elements from the database & cache them.
*/
template
<
typename
INTF
=
IMPL
>
static
std
::
vector
<
std
::
shared_ptr
<
INTF
>>
fetchAll
(
DBConnection
dbConnection
)
{
static
const
std
::
string
req
=
"SELECT * FROM "
+
TABLEPOLICY
::
Name
;
// Lock the cache mutex before attempting to acquire a context, otherwise
// we could have a thread locking cache then DB, and a thread locking DB then cache
auto
l
=
_Cache
::
lock
();
return
sqlite
::
Tools
::
fetchAll
<
IMPL
,
INTF
>
(
dbConnection
,
req
);
}
template
<
typename
INTF
,
typename
...
Args
>
static
std
::
vector
<
std
::
shared_ptr
<
INTF
>>
fetchAll
(
DBConnection
dbConnection
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
auto
l
=
_Cache
::
lock
();
return
sqlite
::
Tools
::
fetchAll
<
IMPL
,
INTF
>
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
}
static
std
::
shared_ptr
<
IMPL
>
load
(
DBConnection
dbConnection
,
sqlite
::
Row
&
row
)
{
auto
l
=
_Cache
::
lock
();
auto
res
=
_Cache
::
load
(
row
);
if
(
res
!=
nullptr
)
return
res
;
res
=
std
::
make_shared
<
IMPL
>
(
dbConnection
,
row
);
_Cache
::
store
(
res
);
return
res
;
}
static
bool
destroy
(
DBConnection
dbConnection
,
const
typename
CACHEPOLICY
::
KeyType
&
key
)
{
auto
l
=
_Cache
::
lock
();
_Cache
::
discard
(
key
);
static
const
std
::
string
req
=
"DELETE FROM "
+
TABLEPOLICY
::
Name
+
" WHERE "
+
TABLEPOLICY
::
CacheColumn
+
" = ?"
;
return
sqlite
::
Tools
::
executeDelete
(
dbConnection
,
req
,
key
);
}
template
<
typename
T
>
static
bool
destroy
(
DBConnection
dbConnection
,
const
T
*
self
)
{
const
auto
&
key
=
CACHEPOLICY
::
key
(
self
);
return
destroy
(
dbConnection
,
key
);
}
static
void
clear
()
{
auto
l
=
_Cache
::
lock
();
_Cache
::
clear
();
}
protected:
/*
* Create a new instance of the cache class.
*/
template
<
typename
...
Args
>
static
bool
insert
(
DBConnection
dbConnection
,
std
::
shared_ptr
<
IMPL
>
self
,
const
std
::
string
&
req
,
Args
&&
...
args
)
{
auto
l
=
_Cache
::
lock
();
unsigned
int
pKey
=
sqlite
::
Tools
::
insert
(
dbConnection
,
req
,
std
::
forward
<
Args
>
(
args
)...
);
if
(
pKey
==
0
)
return
false
;
(
self
.
get
())
->*
TABLEPOLICY
::
PrimaryKey
=
pKey
;
_Cache
::
store
(
self
);
return
true
;
}
};
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