GSoC:2008 Collections 2.0 Querying concept - nesciens/xmms2-wiki GitHub Wiki

A. Query_medialist

The client developer provides a collection structure resulting in a medialist to the daemon. The daemon then queries the metadata from the sqlite-database, so that there is one row for every entry of the medialist and the rows are in the same order as the medialist.

Informal signature:

query_medialist (coll, fetch)

B. Query_clustered

The client developer provides a collection structure to the daemon, then metadata is queried for groups of ids aka clusters.

The developer also specifies a list of things the ids in a cluster should have in common, for instance genre, artist or album. The daemon then queries the metadata from the sqlite-database, so that there is one row per cluster. If no things to have in common are specified all ids in the collection will be in one cluster.

Informal signature:

query_clustered (coll, cluster, fetch, order, start, length)

Examples

Get a simple representation of the playlist

As this is gets you a value-key dict you can use this for entry_format.

query_medialist (     reference ( reference = "_active", "namespace" = "Playlists" ), // coll: the active playlist     dict (                                                          // fetch-argument         "artist" = "artist",         "album" = "album",         "tracknr" = "tracknr",         "title" = "title"         "duration" = "duration"     )

list (     dict (         "artist" = "Something Corporate",         "album" = "Leaving through the window",         "tracknr" = "10",         "title" = "Good News",         "duration" = "232280"     ),     ...,     dict (         "artist" = "Something Corporate",         "album" = "Leaving through the window",         "tracknr" = "16",         "title" = "Globes and Maps",         "duration" = "287933"     ) )

Get a simple representation of the playlist II

As this is gets you a value-key dict you can use this for entry_format.

query_medialist (     reference ( reference = "_active", "namespace" = "Playlists" ), // coll: the active playlist     dict (         "id" = "id"         "data" = dict ( "field" = list ( "artist", "album", "tracknr", "title", "duration" ) )     ) )

list (     dict (         "id" = 767         "data" = dict (             "artist" = "Something Corporate",             "album" = "Leaving through the window",             "tracknr" = "10",             "title" = "Good News",             "duration" = "232280"         )     ),     ...,     dict (         "id" = 766         "data" = dict (             "artist" = "Something Corporate",             "album" = "Leaving through the window",             "tracknr" = "16",             "title" = "Globes and Maps",             "duration" = "287933"         )     ) )

Get a full propdict for every entry in the playlist

query_medialist (     reference ( reference = "_active", "namespace" = "Playlists" ), // coll: the active playlist     dict (         "data" = dict ( "get" = list ( "key", "source", "value" ), "source-preference" = "All" )     ) )

list (     dict (         "data" => dict (             "artist" = dict (                 "plugin/id3v2" = "Something Corporate"             ),             ...,             "size" = dict (                 "plugin/file" = "6126427"                 "plugin/id3v2" = "6125413"             ),             ...,             "url" = dict (                 "server" = "file:///home/erik/muziek/Something+Corporate+-+Leaving+Through+the+Window+-+Good+News.mp3"             )         )     ),     ... )

Get a dict according to server-side source-preference

query_medialist (     reference ( reference = "_active", "namespace" = "Playlists" ), // coll: the active playlist     dict (         "data" = dict ( "get" = list ( "key", "value" ) )     ) )

list (     dict (         "data" => dict (             "artist" = "Something Corporate",             ...,             "size" = "6126427",             ...,             "url" = "file:///home/erik/muziek/Something+Corporate+-+Leaving+Through+the+Window+-+Good+News.mp3"         )     ),     ... )

Get all fields the songs have

query_clustered (     coll,                    // coll argument: the collection     NULL,                    // cluster argument: all songs go into 1 cluster     dict (         "fields" = "field",         "aggregate" = "list"     ),                       // fetch argument: get the fields     NULL, 0, 0               // order, start, length arguments: who cares?     )

list (     dict ("fields" = list ( "added", "album", "artist", ...) ) )

Get the number of songs in the collection

query_clustered (     coll,                      // coll argument: the collection     NULL,                      // cluster argument: all songs go into 1 cluster     dict ("count" = "count"),  // fetch argument: get the number of songs in this cluster     NULL, 0, 0                 // order, start, length arguments: who cares? )

list (     dict = ("count" = 10) )

For each artist, what albums are in the collection

query_clustered (     coll,     dict ("artist", "artist"),     dict (         "artist" = "cluster",         "albums" = dict ("field" = "album", "aggregate" = "list")     ),     NULL, 0, 0 )

list (     dict (         "artist" = "The Clash",         "albums" = list (             "London Calling"         )     ),     ...,     dict (         "artist" = "Sonata Arctica",         "albums" = list (             "Broken",             "Ecliptica",             "For The Sake Of Revenge"         )     ) )

Albums, their number of songs, and total duration

query_clustered (     coll,     dict ("album" = "album"),     dict (         "album" = "cluster",         "number" = "count",         "duration" = dict ("field" = "duration", "aggregate" = "sum"),     )     NULL, 0, 0 )

list (     dict = (         "album" = "The Devil And God Are Raging Inside Me",         "number" = 12,         "duration" = 3541123     ),     ...,     dict (         "album" = "MTV Unplugged in New York",         "number" = 1,         "duration" = 175943     ) )

For every album get the ids + for every song a dict with tracknumber and title

query_clustered (     coll,                      // coll argument: the collection     dict ("album" = "album"), // cluster argument: 1 cluster for every album     dict (         "album" = "cluster",         "ids" = "ids",         "metadata" = dict (             "field" = list ("tracknr", "title"),             "get" = list ("id", "field", "value")         )     ),     NULL, 0, 0                // order, start, length arguments: who cares? )

list (     dict (         "album" = "The Devil And God Are Raging Inside Me",         "ids" = list (59, ..., 70),         "metadata" = dict (             "59" = dict (                 "tracknr" = "4",                 "title" = "Degausser"             ),             ...,             "70" = dict (                 "tracknr" = "6",                 "title" = "You won't know"             )         )     ),     ...,     dict (         "album" = "MTV Unplugged in New York",         "ids" = 630,         "metadata" = dict (             "tracknr" = "12",             "title" = "Lake of Fire"         )     ) )

Fetch/Cluster/Order Datatype

This is an informal description of the datatype used in the fetch, cluster, and order arguments below.

dict (     "type" = < "id" | "count" | "random" | "cluster" | "metadata" > )

Note: "type" = "cluster" is only allowed in order and fetch arguments.

Default values:

"type" = "metadata"

short-cuts

"id" => dict ( "type" = "id" ) "ids" => dict ( "type" = "id", "aggregate" = "list" ) "count" => dict ( "type" = "count" ) "random" => dict ( "type" = "random" ) "cluster" => dict ( "type" = "cluster", label = ) // (only in fetch argument) "fields" => dict ( "get" = list ("field"), "aggregate" = "list" ) "sources" => dict ( "get" = list ("source"), "aggregate" = "list")  => dict ( "field" =  )

Note: Everywhere where a list is used below a string can also be used, which is converted to a list of one element:

 => list (  )

=== "type" = "cluster" === Additional fields:

"label" = , "get" = list (     list of one or more of "field", "id", "value", "source". )

Default values:

"get" = list ( "value" )

=== "type" = "id" === Additional fields:

"aggregate" = < "first" | "sum" | "min" | "max" | "list" >

Default values:

"aggregate" = "first"

=== "type" = "metadata" === Additional fields:

"get" = list (     list of one or more of "field", "id", "value", "source". ) "aggregate" = < "first" | "sum" | "min" | "max" | "list" > "source-preference" = < "All" | "Default" >

Default values:

"get" = list ("value") "aggregate" = "first" "source-preference" = "Default"

Optional fields:

"id" = list (...) "field" = list (...) "value" = list (...) "source" = list (...)

Functions for convenience

These are yet to be updated.

C. Per id

The client developer provides a collection structure to the daemon. The daemon then queries the metadata from the sqlite-database, so that there is one row for every id of the resulting collection. The result is ordered ascending by id.

coll: reference[reference=Gothic Metal,namespace=Playlists] fetch: {{ spec={ type=id,                arguments={}             }, label=id       },         { spec={ type=value,             arguments={field=artist} }, label=artist   },         { spec={ type=value,             arguments={field=album}  }, label=album    },         { spec={ type=value,             arguments={field=title}  }, label=title    },         { spec={ type=source_value_dict, arguments={field=size}   }, label=datasize }} result: {{ id=113,  artist=Evanescence,       album=Anywhere But Home, title=Thoughtless,           datasize={plugin/id3v2=8286281, plugin/file=8314880} },          { id=141,  artist=Evanescence,       album=Not For Your Ears, title=Taking Over Me (Long), datasize={plugin/id3v2=5304040, plugin/file=5326558} },          { id=1092, artist=Within Temptation, album=Mother Earth,      title=Mother Earth,          datasize={plugin/id3v2=8947303, plugin/file=8947840} }}

D. Get all keys

E. The legacy way

The client developer provides a collection structure to the daemon and an optional list of things ids in a group should have in common, for instance genre, artist or album (the groupby-argument). The daemon then queries the metadata from the sqlite-database, so that there are zero or more rows per group, showing all permutations of the "free" (not used for grouping) properties. If no groupby-list is supplied all requested properties are used for grouping.

coll: reference[reference=Gothic Metal,namespace=Playlists] group-by: {artist} fetch: {id, artist, album, title, size} result: {{ id=113,  artist=Evanescence,       album=Anywhere But Home, title=Thoughtless,  size=8286281 },          { id=1092, artist=Within Temptation, album=Mother Earth,      title=Mother Earth, size=8947303 }}

coll: reference[reference=Gothic Metal,namespace=Playlists] group-by: {} fetch: {id, artist, album, title, size} result: {{ id=113,  artist=Evanescence,       album=Anywhere But Home, title=Thoughtless,           size=8286281 },          { id=113,  artist=Evanescence,       album=Anywhere But Home, title=Thoughtless,           size=8314880 },          { id=141,  artist=Evanescence,       album=Not For Your Ears, title=Taking Over Me (Long), size=5304040 },          { id=141,  artist=Evanescence,       album=Not For Your Ears, title=Taking Over Me (Long), size=5326558 },          { id=1092, artist=Within Temptation, album=Mother Earth,      title=Mother Earth,          size=8947303 },          { id=1092, artist=Within Temptation, album=Mother Earth,      title=Mother Earth,          size=8947840 }}

⚠️ **GitHub.com Fallback** ⚠️