Meta API and collection architecture

Maximilian Kossick mkossick at htwg-konstanz.de
Thu May 3 22:03:24 CEST 2007


Hi all,
today Nikolaj asked me about the Meta API and the collection architecture, 
because he got the impression that he might be duplicating stuff for the 
service framework that already exists as part of the new collection 
architecture. Alexandre is familiar with it to some extent because he wrote 
the new collection browser, and Martin, Bart, Sven and I talked about the 
general architecture at FOSDEM, but I'm not sure how much the rest of you 
actually know about it. The umbrello diagramm in amarok/docs describes an 
architecture that is pretty close to the actual implementation, and might 
therefore be helpful.

Meta API
The Meta API in meta.h is a replacement for MetaBundle. As far as I know, it 
was already agreed at the k3m meeting last year that MetaBundle would have to 
be refactored for Amarok 2.

The main goal of the Meta API is to increase maintainability by being more 
object-oriented than MetaBundle in Amarok 1.x. It uses multiple classes to 
represent tracks, artists, albums, composers, genres or years. Additionally, 
the classes defined in meta.h are abstract and have to be implemented for 
each collection.

A lot of the tasks which are handled by CollectionDB at the moment are going 
to be moved to the classes of the Meta API. For example, instead of calling a 
method of CollectionDB to get the album image of a song, you can now call a 
method of Meta::Album (that particular method doesn't work yet because i 
don't know what the return type is supposed to be, a QImage or the 
EmbeddedImage thingy which is used currently, but I hope you get the idea)

Note: the Meta API isn't finished yet. I've been working on it and trying to 
improve it for a while now, but i'm sure that it will have changed because 
there are new requirements or the requirements are different from what i 
expected. The best way to improve it is to use the API in the code, and 
discuss possible changes on the ML or on IRC. There are two implementations 
in SVN at the moment, and i have at least one more (an implementaion which 
handles streams) on my harddisk, so changes to the API force us to change 
quite a few other files and should therefore be carefully thought through.

Collection architecture and QueryMaker
The idea behind the new collection architecture is that there are different 
types of collections ( for example music on an ipod, the files on your 
computer backed by a relational database, or a DAAP server), and Amarok 
should be able to handle all of them the same way. In particular should it be 
possible for smart or dynamic playlists to load songs on a daap server or on 
an ipod into the playlist ( that would allow Amarok to load the music on 
pwsp.net into the playlist automatically, or allow it to play the music on a 
friend's ipod at a party ).

To achieve the goal decribed above I created QueryMaker, which is the 
replacement of QueryBuilder. Unlike QueryBuilder, QueryMaker does not have 
any SQL-isms in its API. QueryMaker's API is still work in progress. The 
parts of the API which are needed for smart playlists or the filtering in the 
collection browser are not implemented yet. 

I've created a few support classes which should make it easier to implement a 
new collection. The classes are located in collection/support and are called 
MemoryCollection and MemoryQueryMaker. Check the DAAP collection 
implementation to see how they are used. They are probably not very fast, and 
the whole collection has to be loaded into memory, but they should make it 
easier to implement a new collection. 


How to use all this stuff
CollectionManager::trackForUrl( KUrl ) is a factory method which creates Track 
object for the given url (or it will do that as soon as it's more than the 
stub that it is now). So whenever you have an url and want a track object for 
it you can use that method, which will try to figure the correct Track 
implementation for the url.

You can get a list of all available collections by calling 
CollectionManager::collections(). You can query a specific collection by 
getting a QueryMaker object directly from the collection, or you can query 
all collections in parallel by using the QueryMaker object returned by 
CollectionManager::queryBuilder().

To use QueryMaker, you first have to select the type of query you want to 
execute by calling one of the start*Query() methods. Depending on the method 
you called, a different signal is emitted with the result of the query. ( 
newResultReady( QString, Meta::DataList ) is a special case and probably only 
necessary for the collection browser) After that, you can build the query by 
calling methods on the QueryMaker instance. The API isn't finished yet, but 
most of the available methods should be familiar to you from QueryBuilder.

Calling run() on the QueryMaker instance start the query, but also returns 
immediately. The query is processed asynchronously and the results are 
delivered by the QueryMaker object by emitting one of its signals. Please 
note that it's possible that the signal is emitted multiple times, with 
different results and a different collectionID each time. It is only safe to 
delete the QueryMaker object after queryDone() was emitted.

BlockingQuery allows you to avoid the asynchronous nature of QueryMaker. 
Configure the QueryMaker object, pass it to BlockingQuery's constructor, and 
call startQuery(), which will block until the query is done.

Creating a new collection
To create a new collection, you'll have to implement the following classes: 
CollectionFactory, Collection, QueryMaker, and all of the Meta classes.

If you use MemoryCollection and MemoryQueryMaker you won't have to implement 
QueryMaker. Implementing the classes mentioned above and creating a plugin 
makes it possible to show your collection in the collection browser. However 
this is optional, your CollectionFactory implementation is free not to emit 
the CollectionFactory::newCollection signal. Nikolay, this would allow you to 
make it possible for the user to decide if the stores are shown in the 
collection browser, if you want.

That's all which occurred to me right now, I'm sure I could write more about 
it. I might do that tomorrow/on the weekend, or just ask me:)

Cheers, Max
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/amarok-devel/attachments/20070503/52bc9dde/attachment.pgp 


More information about the Amarok-devel mailing list