Merge branch 'sticker_inc_dec' of https://github.com/jcorporation/MPD

This commit is contained in:
Max Kellermann
2024-12-12 08:38:58 +01:00
7 changed files with 159 additions and 0 deletions

1
NEWS
View File

@@ -18,6 +18,7 @@ ver 0.24 (not yet released)
- volume command is no longer deprecated - volume command is no longer deprecated
- new "available" and "reset" subcommands for tagtypes - new "available" and "reset" subcommands for tagtypes
- searching stored playlists respond now with song position - searching stored playlists respond now with song position
- new sticker subcommand "inc" and "dec"
* database * database
- attribute "added" shows when each song was added to the database - attribute "added" shows when each song was added to the database
- proxy: require MPD 0.21 or later - proxy: require MPD 0.21 or later

View File

@@ -1518,6 +1518,20 @@ the database for songs).
sticker item with that name already exists, it is sticker item with that name already exists, it is
replaced. replaced.
.. _command_sticker_inc:
:command:`sticker inc {TYPE} {URI} {NAME} {VALUE}`
Adds a sticker value to the specified object. If a
sticker item with that name already exists, it is
incremented by supplied value.
.. _command_sticker_dec:
:command:`sticker dec {TYPE} {URI} {NAME} {VALUE}`
Adds a sticker value to the specified object. If a
sticker item with that name already exists, it is
decremented by supplied value.
.. _command_sticker_delete: .. _command_sticker_delete:
:command:`sticker delete {TYPE} {URI} [NAME]` :command:`sticker delete {TYPE} {URI} [NAME]`

View File

@@ -58,6 +58,24 @@ public:
return CommandResult::OK; return CommandResult::OK;
} }
virtual CommandResult Inc(const char *uri, const char *name, const char *value) {
sticker_database.IncValue(sticker_type,
ValidateUri(uri).c_str(),
name,
value);
return CommandResult::OK;
}
virtual CommandResult Dec(const char *uri, const char *name, const char *value) {
sticker_database.DecValue(sticker_type,
ValidateUri(uri).c_str(),
name,
value);
return CommandResult::OK;
}
virtual CommandResult Delete(const char *uri, const char *name) { virtual CommandResult Delete(const char *uri, const char *name) {
std::string validated_uri = ValidateUri(uri); std::string validated_uri = ValidateUri(uri);
uri = validated_uri.c_str(); uri = validated_uri.c_str();
@@ -440,6 +458,14 @@ handle_sticker(Client &client, Request args, Response &r)
/* set */ /* set */
if (args.size() == 5 && StringIsEqual(cmd, "set")) if (args.size() == 5 && StringIsEqual(cmd, "set"))
return handler->Set(uri, sticker_name, args[4]); return handler->Set(uri, sticker_name, args[4]);
/* inc */
if (args.size() == 5 && StringIsEqual(cmd, "inc"))
return handler->Inc(uri, sticker_name, args[4]);
/* dec */
if (args.size() == 5 && StringIsEqual(cmd, "dec"))
return handler->Dec(uri, sticker_name, args[4]);
/* delete */ /* delete */
if ((args.size() == 3 || args.size() == 4) && StringIsEqual(cmd, "delete")) if ((args.size() == 3 || args.size() == 4) && StringIsEqual(cmd, "delete"))

View File

@@ -48,6 +48,8 @@ enum sticker_sql {
STICKER_SQL_NAMES, STICKER_SQL_NAMES,
STICKER_SQL_NAMES_TYPES, STICKER_SQL_NAMES_TYPES,
STICKER_SQL_NAMES_TYPES_BY_TYPE, STICKER_SQL_NAMES_TYPES_BY_TYPE,
STICKER_SQL_INC,
STICKER_SQL_DEC,
STICKER_SQL_COUNT STICKER_SQL_COUNT
}; };
@@ -115,6 +117,16 @@ static constexpr auto sticker_sql = std::array {
//[STICKER_SQL_NAMES_TYPES_BY_TYPE] //[STICKER_SQL_NAMES_TYPES_BY_TYPE]
"SELECT name,type FROM sticker WHERE type = ? GROUP BY name,type ORDER BY name", "SELECT name,type FROM sticker WHERE type = ? GROUP BY name,type ORDER BY name",
//[STICKER_SQL_INC] =
"INSERT INTO sticker (type, uri, name, value) VALUES (?, ?, ?, ?) "
"ON CONFLICT(type, uri, name) DO "
"UPDATE set value = value + ?",
//[STICKER_SQL_DEC] =
"INSERT INTO sticker (type, uri, name, value) VALUES (?, ?, ?, ?) "
"ON CONFLICT(type, uri, name) DO "
"UPDATE set value = value - ?",
}; };
static constexpr const char sticker_sql_create[] = static constexpr const char sticker_sql_create[] =
@@ -280,6 +292,52 @@ StickerDatabase::StoreValue(const char *type, const char *uri,
InsertValue(type, uri, name, value); InsertValue(type, uri, name, value);
} }
void
StickerDatabase::IncValue(const char *type, const char *uri,
const char *name, const char *value)
{
sqlite3_stmt *const s = stmt[STICKER_SQL_INC];
assert(type != nullptr);
assert(uri != nullptr);
assert(name != nullptr);
assert(*name != 0);
assert(value != nullptr);
BindAll(s, type, uri, name, value, value);
AtScopeExit(s) {
sqlite3_reset(s);
sqlite3_clear_bindings(s);
};
ExecuteCommand(s);
idle_add(IDLE_STICKER);
}
void
StickerDatabase::DecValue(const char *type, const char *uri,
const char *name, const char *value)
{
sqlite3_stmt *const s = stmt[STICKER_SQL_DEC];
assert(type != nullptr);
assert(uri != nullptr);
assert(name != nullptr);
assert(*name != 0);
assert(value != nullptr);
BindAll(s, type, uri, name, value, value);
AtScopeExit(s) {
sqlite3_reset(s);
sqlite3_clear_bindings(s);
};
ExecuteCommand(s);
idle_add(IDLE_STICKER);
}
bool bool
StickerDatabase::Delete(const char *type, const char *uri) StickerDatabase::Delete(const char *type, const char *uri)
{ {

View File

@@ -54,6 +54,8 @@ class StickerDatabase {
SQL_NAMES, SQL_NAMES,
SQL_NAMES_TYPES, SQL_NAMES_TYPES,
SQL_NAMES_TYPES_BY_TYPE, SQL_NAMES_TYPES_BY_TYPE,
STICKER_SQL_INC,
STICKER_SQL_DEC,
SQL_COUNT SQL_COUNT
}; };
@@ -118,6 +120,24 @@ public:
*/ */
void StoreValue(const char *type, const char *uri, void StoreValue(const char *type, const char *uri,
const char *name, const char *value); const char *name, const char *value);
/**
* Increments a sticker by value in the specified object. Inserts
* the value if object does not exist.
*
* Throws #SqliteError on error.
*/
void IncValue(const char *type, const char *uri,
const char *name, const char *value);
/**
* Decrements a sticker by value in the specified object. Inserts
* the value if object does not exist.
*
* Throws #SqliteError on error.
*/
void DecValue(const char *type, const char *uri,
const char *name, const char *value);
/** /**
* Deletes a sticker from the database. All sticker values of the * Deletes a sticker from the database. All sticker values of the

View File

@@ -30,6 +30,24 @@ sticker_song_set_value(StickerDatabase &db,
db.StoreValue("song", uri.c_str(), name, value); db.StoreValue("song", uri.c_str(), name, value);
} }
void
sticker_song_inc_value(StickerDatabase &db,
const LightSong &song,
const char *name, const char *value)
{
const auto uri = song.GetURI();
db.IncValue("song", uri.c_str(), name, value);
}
void
sticker_song_dec_value(StickerDatabase &db,
const LightSong &song,
const char *name, const char *value)
{
const auto uri = song.GetURI();
db.DecValue("song", uri.c_str(), name, value);
}
bool bool
sticker_song_delete(StickerDatabase &db, const char *uri) sticker_song_delete(StickerDatabase &db, const char *uri)
{ {

View File

@@ -34,6 +34,28 @@ sticker_song_set_value(StickerDatabase &db,
const LightSong &song, const LightSong &song,
const char *name, const char *value); const char *name, const char *value);
/**
* Increments a sticker by value in the specified object. Inserts
* the value if object does not exist.
*
* Throws #SqliteError on error.
*/
void
sticker_song_inc_value(StickerDatabase &db,
const LightSong &song,
const char *name, const char *value);
/**
* Decrements a sticker by value in the specified object. Inserts
* the value if object does not exist.
*
* Throws #SqliteError on error.
*/
void
sticker_song_dec_value(StickerDatabase &db,
const LightSong &song,
const char *name, const char *value);
/** /**
* Deletes a sticker from the database. All values are deleted. * Deletes a sticker from the database. All values are deleted.
* *