Skip to content

Commit

Permalink
Add sticker sub-commands inc and dec
Browse files Browse the repository at this point in the history
Let sqlite do the work for incrementing or decrementing a sticker value.
This sub-commands are usefull to track playcounts with sticker values and
saves us one roundtrip.
  • Loading branch information
jcorporation committed Dec 11, 2024
1 parent 78e6431 commit 1078c1c
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ver 0.24 (not yet released)
- volume command is no longer deprecated
- new "available" and "reset" subcommands for tagtypes
- searching stored playlists respond now with song position
- new sticker subcommand "inc" and "dec"
* database
- attribute "added" shows when each song was added to the database
- fix integer overflows with 64-bit inode numbers
Expand Down
14 changes: 14 additions & 0 deletions doc/protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,20 @@ the database for songs).
sticker item with that name already exists, it is
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 {TYPE} {URI} [NAME]`
Expand Down
26 changes: 26 additions & 0 deletions src/command/StickerCommands.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ class DomainHandler {
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) {
std::string validated_uri = ValidateUri(uri);
uri = validated_uri.c_str();
Expand Down Expand Up @@ -442,6 +460,14 @@ handle_sticker(Client &client, Request args, Response &r)
/* set */
if (args.size() == 5 && StringIsEqual(cmd, "set"))
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 */
if ((args.size() == 3 || args.size() == 4) && StringIsEqual(cmd, "delete"))
Expand Down
58 changes: 58 additions & 0 deletions src/sticker/Database.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ enum sticker_sql {
STICKER_SQL_NAMES,
STICKER_SQL_NAMES_TYPES,
STICKER_SQL_NAMES_TYPES_BY_TYPE,
STICKER_SQL_INC,
STICKER_SQL_DEC,

STICKER_SQL_COUNT
};
Expand Down Expand Up @@ -115,6 +117,16 @@ static constexpr auto sticker_sql = std::array {

//[STICKER_SQL_NAMES_TYPES_BY_TYPE]
"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[] =
Expand Down Expand Up @@ -280,6 +292,52 @@ StickerDatabase::StoreValue(const char *type, const char *uri,
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
StickerDatabase::Delete(const char *type, const char *uri)
{
Expand Down
20 changes: 20 additions & 0 deletions src/sticker/Database.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class StickerDatabase {
SQL_NAMES,
SQL_NAMES_TYPES,
SQL_NAMES_TYPES_BY_TYPE,
STICKER_SQL_INC,
STICKER_SQL_DEC,

SQL_COUNT
};
Expand Down Expand Up @@ -118,6 +120,24 @@ public:
*/
void StoreValue(const char *type, const char *uri,
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
Expand Down
18 changes: 18 additions & 0 deletions src/sticker/SongSticker.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ sticker_song_set_value(StickerDatabase &db,
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
sticker_song_delete(StickerDatabase &db, const char *uri)
{
Expand Down
22 changes: 22 additions & 0 deletions src/sticker/SongSticker.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ sticker_song_set_value(StickerDatabase &db,
const LightSong &song,
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.
*
Expand Down

0 comments on commit 1078c1c

Please sign in to comment.