Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
77c9081f
Commit
77c9081f
authored
Apr 24, 2019
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sticker/Database: wrap in class StickerDatabase
parent
c88d5616
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
218 additions
and
188 deletions
+218
-188
Instance.cxx
src/Instance.cxx
+2
-2
Instance.hxx
src/Instance.hxx
+11
-0
Main.cxx
src/Main.cxx
+11
-13
AllCommands.cxx
src/command/AllCommands.cxx
+2
-1
StickerCommands.cxx
src/command/StickerCommands.cxx
+20
-9
Database.cxx
src/sticker/Database.cxx
+87
-107
Database.hxx
src/sticker/Database.hxx
+55
-35
SongSticker.cxx
src/sticker/SongSticker.cxx
+18
-14
SongSticker.hxx
src/sticker/SongSticker.hxx
+12
-7
No files found.
src/Instance.cxx
View file @
77c9081f
...
...
@@ -107,9 +107,9 @@ Instance::OnDatabaseSongRemoved(const char *uri) noexcept
#ifdef ENABLE_SQLITE
/* if the song has a sticker, remove it */
if
(
sticker_enabled
())
{
if
(
HasStickerDatabase
())
{
try
{
sticker_song_delete
(
uri
);
sticker_song_delete
(
*
sticker_database
,
uri
);
}
catch
(...)
{
}
}
...
...
src/Instance.hxx
View file @
77c9081f
...
...
@@ -53,6 +53,7 @@ class ClientList;
struct
Partition
;
class
StateFile
;
class
RemoteTagCache
;
class
StickerDatabase
;
/**
* A utility class which, when used as the first base class, ensures
...
...
@@ -125,6 +126,10 @@ struct Instance final
StateFile
*
state_file
=
nullptr
;
#ifdef ENABLE_SQLITE
std
::
unique_ptr
<
StickerDatabase
>
sticker_database
;
#endif
Instance
();
~
Instance
()
noexcept
;
...
...
@@ -166,6 +171,12 @@ struct Instance final
const
Database
&
GetDatabaseOrThrow
()
const
;
#endif
#ifdef ENABLE_SQLITE
bool
HasStickerDatabase
()
noexcept
{
return
sticker_database
!=
nullptr
;
}
#endif
void
BeginShutdownUpdate
()
noexcept
;
#ifdef ENABLE_CURL
...
...
src/Main.cxx
View file @
77c9081f
...
...
@@ -237,23 +237,23 @@ InitDatabaseAndStorage(const ConfigData &config)
#endif
#ifdef ENABLE_SQLITE
/**
* Configure and initialize the sticker subsystem.
*/
static
void
glue_sticker_init
(
const
ConfigData
&
config
)
static
std
::
unique_ptr
<
StickerDatabase
>
LoadStickerDatabase
(
const
ConfigData
&
config
)
{
#ifdef ENABLE_SQLITE
auto
sticker_file
=
config
.
GetPath
(
ConfigOption
::
STICKER_FILE
);
if
(
sticker_file
.
IsNull
())
return
;
return
nullptr
;
sticker_global_init
(
std
::
move
(
sticker_file
));
#else
(
void
)
config
;
#endif
return
std
::
make_unique
<
StickerDatabase
>
(
std
::
move
(
sticker_file
));
}
#endif
static
void
glue_state_file_init
(
const
ConfigData
&
raw_config
)
{
...
...
@@ -513,7 +513,9 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
const
bool
create_db
=
InitDatabaseAndStorage
(
raw_config
);
#endif
glue_sticker_init
(
raw_config
);
#ifdef ENABLE_SQLITE
instance
->
sticker_database
=
LoadStickerDatabase
(
raw_config
);
#endif
command_init
();
...
...
@@ -625,10 +627,6 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
}
#endif
#ifdef ENABLE_SQLITE
sticker_global_finish
();
#endif
return
EXIT_SUCCESS
;
}
...
...
src/command/AllCommands.cxx
View file @
77c9081f
...
...
@@ -38,6 +38,7 @@
#include "Permission.hxx"
#include "tag/Type.h"
#include "Partition.hxx"
#include "Instance.hxx"
#include "client/Client.hxx"
#include "client/Response.hxx"
#include "util/Macros.hxx"
...
...
@@ -216,7 +217,7 @@ command_available(gcc_unused const Partition &partition,
{
#ifdef ENABLE_SQLITE
if
(
StringIsEqual
(
cmd
->
cmd
,
"sticker"
))
return
sticker_enabled
();
return
partition
.
instance
.
HasStickerDatabase
();
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
...
...
src/command/StickerCommands.cxx
View file @
77c9081f
...
...
@@ -28,6 +28,7 @@
#include "client/Client.hxx"
#include "client/Response.hxx"
#include "Partition.hxx"
#include "Instance.hxx"
#include "util/StringAPI.hxx"
#include "util/ScopeExit.hxx"
...
...
@@ -50,7 +51,9 @@ sticker_song_find_print_cb(const LightSong &song, const char *value,
}
static
CommandResult
handle_sticker_song
(
Response
&
r
,
Partition
&
partition
,
Request
args
)
handle_sticker_song
(
Response
&
r
,
Partition
&
partition
,
StickerDatabase
&
sticker_database
,
Request
args
)
{
const
Database
&
db
=
partition
.
GetDatabaseOrThrow
();
...
...
@@ -62,7 +65,8 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
assert
(
song
!=
nullptr
);
AtScopeExit
(
&
db
,
song
)
{
db
.
ReturnSong
(
song
);
};
const
auto
value
=
sticker_song_get_value
(
*
song
,
args
[
3
]);
const
auto
value
=
sticker_song_get_value
(
sticker_database
,
*
song
,
args
[
3
]);
if
(
value
.
empty
())
{
r
.
Error
(
ACK_ERROR_NO_EXIST
,
"no such sticker"
);
return
CommandResult
::
ERROR
;
...
...
@@ -77,7 +81,7 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
assert
(
song
!=
nullptr
);
AtScopeExit
(
&
db
,
song
)
{
db
.
ReturnSong
(
song
);
};
const
auto
sticker
=
sticker_song_get
(
*
song
);
const
auto
sticker
=
sticker_song_get
(
sticker_database
,
*
song
);
sticker_print
(
r
,
sticker
);
return
CommandResult
::
OK
;
...
...
@@ -87,7 +91,8 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
assert
(
song
!=
nullptr
);
AtScopeExit
(
&
db
,
song
)
{
db
.
ReturnSong
(
song
);
};
sticker_song_set_value
(
*
song
,
args
[
3
],
args
[
4
]);
sticker_song_set_value
(
sticker_database
,
*
song
,
args
[
3
],
args
[
4
]);
return
CommandResult
::
OK
;
/* delete song song_id [key] */
}
else
if
((
args
.
size
==
3
||
args
.
size
==
4
)
&&
...
...
@@ -97,8 +102,9 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
AtScopeExit
(
&
db
,
song
)
{
db
.
ReturnSong
(
song
);
};
bool
ret
=
args
.
size
==
3
?
sticker_song_delete
(
*
song
)
:
sticker_song_delete_value
(
*
song
,
args
[
3
]);
?
sticker_song_delete
(
sticker_database
,
*
song
)
:
sticker_song_delete_value
(
sticker_database
,
*
song
,
args
[
3
]);
if
(
!
ret
)
{
r
.
Error
(
ACK_ERROR_NO_EXIST
,
"no such sticker"
);
return
CommandResult
::
ERROR
;
...
...
@@ -138,7 +144,7 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
args
[
3
],
};
sticker_song_find
(
db
,
base_uri
,
data
.
name
,
sticker_song_find
(
sticker_database
,
db
,
base_uri
,
data
.
name
,
op
,
value
,
sticker_song_find_print_cb
,
&
data
);
...
...
@@ -154,13 +160,18 @@ handle_sticker(Client &client, Request args, Response &r)
{
assert
(
args
.
size
>=
3
);
if
(
!
sticker_enabled
())
{
auto
&
instance
=
client
.
GetInstance
();
if
(
!
instance
.
HasStickerDatabase
())
{
r
.
Error
(
ACK_ERROR_UNKNOWN
,
"sticker database is disabled"
);
return
CommandResult
::
ERROR
;
}
auto
&
sticker_database
=
*
instance
.
sticker_database
;
if
(
StringIsEqual
(
args
[
1
],
"song"
))
return
handle_sticker_song
(
r
,
client
.
GetPartition
(),
args
);
return
handle_sticker_song
(
r
,
client
.
GetPartition
(),
sticker_database
,
args
);
else
{
r
.
Error
(
ACK_ERROR_ARG
,
"unknown sticker domain"
);
return
CommandResult
::
ERROR
;
...
...
src/sticker/Database.cxx
View file @
77c9081f
This diff is collapsed.
Click to expand it.
src/sticker/Database.hxx
View file @
77c9081f
...
...
@@ -45,70 +45,77 @@
#include "Match.hxx"
#include "util/Compiler.h"
#include <sqlite3.h>
#include <map>
#include <string>
class
Path
;
struct
Sticker
;
/**
* Opens the sticker database.
*
* Throws std::runtime_error on error.
*/
void
sticker_global_init
(
Path
path
);
class
StickerDatabase
{
enum
SQL
{
SQL_GET
,
SQL_LIST
,
SQL_UPDATE
,
SQL_INSERT
,
SQL_DELETE
,
SQL_DELETE_VALUE
,
SQL_FIND
,
SQL_FIND_VALUE
,
SQL_FIND_LT
,
SQL_FIND_GT
,
/**
* Close the sticker database.
*/
void
sticker_global_finish
()
noexcept
;
SQL_COUNT
};
sqlite3
*
db
;
sqlite3_stmt
*
stmt
[
SQL_COUNT
]
;
/**
* Returns true if the sticker database is configured and available.
public
:
/**
* Opens the sticker database.
*
* Throws on error.
*/
gcc_const
bool
sticker_enabled
()
noexcept
;
StickerDatabase
(
Path
path
);
~
StickerDatabase
()
noexcept
;
/**
/**
* Returns one value from an object's sticker record. Returns an
* empty string if the value doesn't exist.
*
* Throws #SqliteError on error.
*/
std
::
string
sticker_load_value
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
);
std
::
string
LoadValue
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
);
/**
/**
* Sets a sticker value in the specified object. Overwrites existing
* values.
*
* Throws #SqliteError on error.
*/
void
sticker_store_value
(
const
char
*
type
,
const
char
*
uri
,
void
StoreValue
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
,
const
char
*
value
);
/**
/**
* Deletes a sticker from the database. All sticker values of the
* specified object are deleted.
*
* Throws #SqliteError on error.
*/
bool
sticker_delete
(
const
char
*
type
,
const
char
*
uri
);
bool
Delete
(
const
char
*
type
,
const
char
*
uri
);
/**
/**
* Deletes a sticker value. Fails if no sticker with this name
* exists.
*
* Throws #SqliteError on error.
*/
bool
sticker_delete_value
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
);
bool
DeleteValue
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
);
/**
/**
* Loads the sticker for the specified resource.
*
* Throws #SqliteError on error.
...
...
@@ -117,10 +124,9 @@ sticker_delete_value(const char *type, const char *uri, const char *name);
* @param uri the URI of the resource, e.g. the song path
* @return a sticker object
*/
Sticker
sticker_load
(
const
char
*
type
,
const
char
*
uri
);
Sticker
Load
(
const
char
*
type
,
const
char
*
uri
);
/**
/**
* Finds stickers with the specified name below the specified URI.
*
* @param type the resource type, e.g. "song"
...
...
@@ -130,11 +136,25 @@ sticker_load(const char *type, const char *uri);
* @param op the comparison operator
* @param value the operand
*/
void
sticker_find
(
const
char
*
type
,
const
char
*
base_uri
,
const
char
*
name
,
void
Find
(
const
char
*
type
,
const
char
*
base_uri
,
const
char
*
name
,
StickerOperator
op
,
const
char
*
value
,
void
(
*
func
)(
const
char
*
uri
,
const
char
*
value
,
void
*
user_data
),
void
*
user_data
);
private
:
void
ListValues
(
std
::
map
<
std
::
string
,
std
::
string
>
&
table
,
const
char
*
type
,
const
char
*
uri
);
bool
UpdateValue
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
,
const
char
*
value
);
void
InsertValue
(
const
char
*
type
,
const
char
*
uri
,
const
char
*
name
,
const
char
*
value
);
sqlite3_stmt
*
BindFind
(
const
char
*
type
,
const
char
*
base_uri
,
const
char
*
name
,
StickerOperator
op
,
const
char
*
value
);
};
#endif
src/sticker/SongSticker.cxx
View file @
77c9081f
...
...
@@ -29,44 +29,47 @@
#include <stdlib.h>
std
::
string
sticker_song_get_value
(
const
LightSong
&
song
,
const
char
*
name
)
sticker_song_get_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
)
{
const
auto
uri
=
song
.
GetURI
();
return
sticker_load_v
alue
(
"song"
,
uri
.
c_str
(),
name
);
return
db
.
LoadV
alue
(
"song"
,
uri
.
c_str
(),
name
);
}
void
sticker_song_set_value
(
const
LightSong
&
song
,
sticker_song_set_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
,
const
char
*
value
)
{
const
auto
uri
=
song
.
GetURI
();
sticker_store_v
alue
(
"song"
,
uri
.
c_str
(),
name
,
value
);
db
.
StoreV
alue
(
"song"
,
uri
.
c_str
(),
name
,
value
);
}
bool
sticker_song_delete
(
const
char
*
uri
)
sticker_song_delete
(
StickerDatabase
&
db
,
const
char
*
uri
)
{
return
sticker_d
elete
(
"song"
,
uri
);
return
db
.
D
elete
(
"song"
,
uri
);
}
bool
sticker_song_delete
(
const
LightSong
&
song
)
sticker_song_delete
(
StickerDatabase
&
db
,
const
LightSong
&
song
)
{
return
sticker_song_delete
(
song
.
GetURI
().
c_str
());
return
sticker_song_delete
(
db
,
song
.
GetURI
().
c_str
());
}
bool
sticker_song_delete_value
(
const
LightSong
&
song
,
const
char
*
name
)
sticker_song_delete_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
)
{
const
auto
uri
=
song
.
GetURI
();
return
sticker_delete_v
alue
(
"song"
,
uri
.
c_str
(),
name
);
return
db
.
DeleteV
alue
(
"song"
,
uri
.
c_str
(),
name
);
}
Sticker
sticker_song_get
(
const
LightSong
&
song
)
sticker_song_get
(
StickerDatabase
&
db
,
const
LightSong
&
song
)
{
const
auto
uri
=
song
.
GetURI
();
return
sticker_l
oad
(
"song"
,
uri
.
c_str
());
return
db
.
L
oad
(
"song"
,
uri
.
c_str
());
}
namespace
{
...
...
@@ -101,7 +104,8 @@ sticker_song_find_cb(const char *uri, const char *value, void *user_data)
}
void
sticker_song_find
(
const
Database
&
db
,
const
char
*
base_uri
,
const
char
*
name
,
sticker_song_find
(
StickerDatabase
&
sticker_database
,
const
Database
&
db
,
const
char
*
base_uri
,
const
char
*
name
,
StickerOperator
op
,
const
char
*
value
,
void
(
*
func
)(
const
LightSong
&
song
,
const
char
*
value
,
void
*
user_data
),
...
...
@@ -126,6 +130,6 @@ sticker_song_find(const Database &db, const char *base_uri, const char *name,
data
.
base_uri_length
=
strlen
(
data
.
base_uri
);
sticker_
f
ind
(
"song"
,
data
.
base_uri
,
name
,
op
,
value
,
sticker_
database
.
F
ind
(
"song"
,
data
.
base_uri
,
name
,
op
,
value
,
sticker_song_find_cb
,
&
data
);
}
src/sticker/SongSticker.hxx
View file @
77c9081f
...
...
@@ -27,6 +27,7 @@
struct
LightSong
;
struct
Sticker
;
class
Database
;
class
StickerDatabase
;
/**
* Returns one value from a song's sticker record.
...
...
@@ -34,7 +35,8 @@ class Database;
* Throws #SqliteError on error.
*/
std
::
string
sticker_song_get_value
(
const
LightSong
&
song
,
const
char
*
name
);
sticker_song_get_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
);
/**
* Sets a sticker value in the specified song. Overwrites existing
...
...
@@ -43,7 +45,8 @@ sticker_song_get_value(const LightSong &song, const char *name);
* Throws #SqliteError on error.
*/
void
sticker_song_set_value
(
const
LightSong
&
song
,
sticker_song_set_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
,
const
char
*
value
);
/**
...
...
@@ -52,10 +55,10 @@ sticker_song_set_value(const LightSong &song,
* Throws #SqliteError on error.
*/
bool
sticker_song_delete
(
const
char
*
uri
);
sticker_song_delete
(
StickerDatabase
&
db
,
const
char
*
uri
);
bool
sticker_song_delete
(
const
LightSong
&
song
);
sticker_song_delete
(
StickerDatabase
&
db
,
const
LightSong
&
song
);
/**
* Deletes a sticker value. Does nothing if the sticker did not
...
...
@@ -64,7 +67,8 @@ sticker_song_delete(const LightSong &song);
* Throws #SqliteError on error.
*/
bool
sticker_song_delete_value
(
const
LightSong
&
song
,
const
char
*
name
);
sticker_song_delete_value
(
StickerDatabase
&
db
,
const
LightSong
&
song
,
const
char
*
name
);
/**
* Loads the sticker for the specified song.
...
...
@@ -75,7 +79,7 @@ sticker_song_delete_value(const LightSong &song, const char *name);
* @return a sticker object
*/
Sticker
sticker_song_get
(
const
LightSong
&
song
);
sticker_song_get
(
StickerDatabase
&
db
,
const
LightSong
&
song
);
/**
* Finds stickers with the specified name below the specified
...
...
@@ -89,7 +93,8 @@ sticker_song_get(const LightSong &song);
* @param name the name of the sticker
*/
void
sticker_song_find
(
const
Database
&
db
,
const
char
*
base_uri
,
const
char
*
name
,
sticker_song_find
(
StickerDatabase
&
sticker_database
,
const
Database
&
db
,
const
char
*
base_uri
,
const
char
*
name
,
StickerOperator
op
,
const
char
*
value
,
void
(
*
func
)(
const
LightSong
&
song
,
const
char
*
value
,
void
*
user_data
),
...
...
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