]> git.sesse.net Git - vlc/commitdiff
media library: good riddance
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 24 Mar 2013 16:57:32 +0000 (18:57 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 24 Mar 2013 16:58:42 +0000 (18:58 +0200)
Big pile of non-sensical and unmaintained code.

16 files changed:
configure.ac
modules/LIST
modules/Makefile.am
modules/media_library/Modules.am [deleted file]
modules/media_library/item_list.c [deleted file]
modules/media_library/item_list.h [deleted file]
modules/media_library/media_pool.c [deleted file]
modules/media_library/ml_watch.c [deleted file]
modules/media_library/sql_add.c [deleted file]
modules/media_library/sql_delete.c [deleted file]
modules/media_library/sql_media_library.c [deleted file]
modules/media_library/sql_media_library.h [deleted file]
modules/media_library/sql_monitor.c [deleted file]
modules/media_library/sql_search.c [deleted file]
modules/media_library/sql_update.c [deleted file]
po/POTFILES.in

index 5c579e084d3d018e63638415be09dd66ec5293c4..24acad976abbd6591500c6895071fa20998a6f2b 100644 (file)
@@ -3967,7 +3967,6 @@ AC_ARG_ENABLE(media-library,
 AS_IF([test "${enable_media_library}" = "yes"], [
   AC_DEFINE([MEDIA_LIBRARY], 1, [Define if you want to use the VLC media library])
   VLC_ADD_CPPFLAGS([qt4],"-DMEDIA_LIBRARY")
-  VLC_ADD_PLUGIN([media_library])
 
 dnl
 dnl SQLite
@@ -4135,7 +4134,6 @@ AC_CONFIG_FILES([
   modules/lua/Makefile
   modules/meta_engine/Makefile
   modules/misc/Makefile
-  modules/media_library/Makefile
   modules/mux/Makefile
   modules/notify/Makefile
   modules/packetizer/Makefile
index 749a29b87199ec34d0bd86c436b8049777fecd0c..8e0e9ff6e7d4381128862ae72b7d5566c1c33817 100644 (file)
@@ -192,7 +192,6 @@ $Id$
  * magnify: zoom video filter
  * marq: Overlays a marquee on the video
  * mash: OpenMash based decoder
- * media_library: a sql based media library
  * mediacodec: Android Jelly Bean MediaCodec decoder module
  * mediadirs: Picture/Music/Video user directories as service discoveries
  * minimal_macosx: a minimal Mac OS X GUI, using the FrameWork
index 805232402d5e80402783a3380bc2fe06f5cca31f..31c6d837172e5689fed8a2397c02fa655fbdc0aa 100644 (file)
@@ -10,7 +10,6 @@ BASE_SUBDIRS = \
        gui \
        meta_engine \
        misc \
-       media_library \
        notify \
        packetizer \
        services_discovery \
diff --git a/modules/media_library/Modules.am b/modules/media_library/Modules.am
deleted file mode 100644 (file)
index e219161..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-SOURCES_media_library = sql_media_library.c \
-                        sql_media_library.h \
-                        sql_monitor.c \
-                        sql_search.c \
-                        sql_add.c \
-                        sql_update.c \
-                        sql_delete.c \
-                        item_list.c \
-                        item_list.h \
-                        ml_watch.c \
-                        media_pool.c
diff --git a/modules/media_library/item_list.c b/modules/media_library/item_list.c
deleted file mode 100644 (file)
index ad91ae0..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*****************************************************************************
- * item_list.c: An input_item_t+media_id couple list for the media library
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include "sql_media_library.h"
-#include "item_list.h"
-
-/**
- * @short item hash list for the media library monitoring system
- */
-
-/**
- * @brief Add an item to the head of the list
- * @param p_ml
- * @param p_media media object. ID must be non zero and valid
- * @param p_item input item to add, MUST NOT be NULL
- * @param locked flag set if the list is locked. do not use
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int __item_list_add( watch_thread_t *p_wt, ml_media_t* p_media, input_item_t *p_item,
-                     bool locked )
-{
-    if( !locked )
-        vlc_mutex_lock( &p_wt->list_mutex );
-    ml_LockMedia( p_media );
-    assert( p_media->i_id );
-    /* Ensure duplication does not occur */
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item->i_id == p_item->i_id )
-        {
-            ml_UnlockMedia( p_media );
-            if( !locked )
-                vlc_mutex_unlock( &p_wt->list_mutex );
-            return VLC_EGENERIC;
-        }
-    }
-
-    item_list_t *p_new = ( item_list_t* ) calloc( 1, sizeof( item_list_t ) );
-    if( !p_new )
-    {
-        ml_UnlockMedia( p_media );
-        if( !locked )
-            vlc_mutex_unlock( &p_wt->list_mutex );
-        return VLC_ENOMEM;
-    }
-    p_new->p_next = p_wt->p_hlist[ item_hash( p_item ) ];
-    p_new->i_refs = 1;
-    p_new->i_media_id = p_media->i_id;
-    p_new->p_media = p_media;
-    p_new->p_item = p_item;
-    p_wt->p_hlist[ item_hash( p_item ) ] = p_new;
-    ml_UnlockMedia( p_media );
-    if( !locked )
-        vlc_mutex_unlock( &p_wt->list_mutex );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Delete an item from the list
- * @param p_ml this media library
- * @param i_media_id media library's media ID
- */
-item_list_t* item_list_delMedia( watch_thread_t *p_wt, int i_media_id )
-{
-    vlc_mutex_lock( &p_wt->list_mutex );
-    item_list_t *p_prev = NULL;
-    il_foreachhashlist( p_wt->p_hlist, p_elt, ixx )
-    {
-        if( p_elt->i_media_id == i_media_id )
-        {
-            if( p_prev )
-                p_prev->p_next = p_elt->p_next;
-            else
-                p_wt->p_hlist[ixx] = p_elt->p_next;
-            p_elt->p_next = NULL;
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt;
-        }
-        else
-        {
-            p_prev = p_elt;
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-    return NULL;
-}
-
-/**
- * @brief Delete an item from the list and return the single element
- * @param p_ml this media library
- * @param p_item item to delete
- * @return The element from the list containing p_item
- */
-item_list_t* item_list_delItem( watch_thread_t *p_wt, input_item_t *p_item, bool locked )
-{
-    if( !locked )
-        vlc_mutex_lock( &p_wt->list_mutex );
-    item_list_t *p_prev = NULL;
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item == p_item )
-        {
-            if( p_prev )
-                p_prev->p_next = p_elt->p_next;
-            else
-                p_wt->p_hlist[ item_hash( p_item ) ] = p_elt->p_next;
-            p_elt->p_next = NULL;
-            if( !locked )
-                vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt;
-        }
-        else
-        {
-            p_prev = p_elt;
-        }
-    }
-    if( !locked )
-        vlc_mutex_unlock( &p_wt->list_mutex );
-    return NULL;
-}
-
-/**
- * @brief Find an input item
- * @param p_ml this media library
- * @param i_media_id item to find and gc_incref
- * @return input item if found, NULL if not found
- */
-input_item_t* item_list_itemOfMediaId( watch_thread_t *p_wt, int i_media_id )
-{
-    item_list_t* p_tmp = item_list_listitemOfMediaId( p_wt, i_media_id );
-    if( p_tmp )
-        return p_tmp->p_item;
-    else
-        return NULL;
-}
-
-/**
- * @brief Find an item list item
- * @param p_ml this media library
- * @param i_media_id item to find and gc_incref
- * @return input item if found, NULL if not found
- */
-item_list_t* item_list_listitemOfMediaId( watch_thread_t *p_wt, int i_media_id )
-{
-    vlc_mutex_lock( &p_wt->list_mutex );
-    il_foreachhashlist( p_wt->p_hlist, p_elt, ixx )
-    {
-        if( p_elt->i_media_id == i_media_id )
-        {
-            p_elt->i_age = 0;
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt;
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-    return NULL;
-}
-
-/**
- * @brief Find a media
- * @param p_ml this media library
- * @param i_media_id item to find and gc_incref
- * @return media if found. NULL otherwise
- */
-ml_media_t* item_list_mediaOfMediaId( watch_thread_t *p_wt, int i_media_id )
-{
-    item_list_t* p_tmp = item_list_listitemOfMediaId( p_wt, i_media_id );
-    if( p_tmp )
-        return p_tmp->p_media;
-    else
-        return NULL;
-}
-
-/**
- * @brief Find a media ID by its input_item
- * @param p_ml this media library
- * @param p_item item to find
- * @return media_id found, or VLC_EGENERIC
- */
-int item_list_mediaIdOfItem( watch_thread_t *p_wt, input_item_t *p_item )
-{
-    vlc_mutex_lock( &p_wt->list_mutex );
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item == p_item )
-        {
-            if( p_elt->i_media_id <= 0 )
-                /* TODO! */
-            p_elt->i_age = 0;
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt->i_media_id;
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-    return VLC_EGENERIC;
-}
-
-/**
- * @brief Find a media by its input_item
- * @param p_ml this media library
- * @param p_item item to find
- * @return media found, or VLC_EGENERIC
- */
-ml_media_t* item_list_mediaOfItem( watch_thread_t *p_wt, input_item_t* p_item,
-        bool locked )
-{
-    if( !locked )
-        vlc_mutex_lock( &p_wt->list_mutex );
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item == p_item )
-        {
-            p_wt->p_hlist[ item_hash( p_item ) ] = p_elt->p_next;
-            p_elt->p_next = NULL;
-            if( !locked )
-                vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt->p_media;
-        }
-    }
-    if( !locked )
-        vlc_mutex_unlock( &p_wt->list_mutex );
-    return NULL;
-}
-/**
- * @brief Flag an item as updated
- * @param p_ml this media library
- * @param p_item item to find and flag
- * @param b_played raise play count or not, update last play
- * @return media_id found, or VLC_EGENERIC
- */
-int item_list_updateInput( watch_thread_t *p_wt, input_item_t *p_item,
-                           bool b_played )
-{
-    vlc_mutex_lock( &p_wt->list_mutex );
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item == p_item )
-        {
-            /* Item found, flag and return */
-            p_elt->i_age = 0;
-            p_elt->i_update |= b_played ? 3 : 1;
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            return p_elt->i_media_id;
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-    return VLC_EGENERIC;
-}
-
-/**
- * @brief Free every item in the item list.
- * @param p_wt Watch thread
- * @note All decref of objects must be handled by watch system
- */
-void item_list_destroy( watch_thread_t* p_wt )
-{
-    vlc_mutex_lock( &p_wt->list_mutex );
-    for( int i = 0; i < ML_ITEMLIST_HASH_LENGTH ; i++ )
-    {
-        for( item_list_t* p_elt = p_wt->p_hlist[i] ; p_elt; p_elt = p_wt->p_hlist[i] )
-        {
-            p_wt->p_hlist[i] = p_elt->p_next;
-            free( p_elt );
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-}
diff --git a/modules/media_library/item_list.h b/modules/media_library/item_list.h
deleted file mode 100644 (file)
index 2d24686..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*****************************************************************************
- * item_list.h : Item list data structure for Watching system
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team  and AUTHORS
- * $Id$
- *
- * Authors: Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef ML_ITEM_LIST_H
-#define ML_ITEM_LIST_H
-
-#include <vlc_input.h>
-#include <vlc_arrays.h>
-
-struct watch_thread_t;
-typedef struct watch_thread_t watch_thread_t;
-typedef struct item_list_t item_list_t;
-
-/**
- * Definition of item_list_t
- */
-struct item_list_t {
-    input_item_t *p_item;     /**< Input item */
-    ml_media_t   *p_media;    /**< Media item */
-    item_list_t  *p_next;     /**< Next element in the list */
-    int           i_media_id; /**< Media id */
-    int           i_age;      /**< Time spent in this list without activity */
-    int           i_refs;     /**< Number of important refs */
-    int           i_update;   /**< Flag set when the input item is updated:
-                                    0: no update,
-                                    1: meta update,
-                                    2: increment play count,
-                                    3: both */
-};
-
-#define ML_ITEMLIST_HASH_LENGTH 40
-
-#define il_foreachhashlist( a, b, c )                                          \
-            for( int c = 0 ; c < ML_ITEMLIST_HASH_LENGTH ; c++ )         \
-                for( item_list_t* b = a[c]; b; b = b->p_next )
-
-#define il_foreachlist( a, b )  for( item_list_t* b = a ; b; b = b->p_next )
-
-#define item_list_add( a, b, c ) __item_list_add( a, b, c, false )
-
-int __item_list_add( watch_thread_t *p_wt, ml_media_t* p_media,
-                     input_item_t *p_item, bool );
-item_list_t* item_list_delMedia( watch_thread_t *p_wt, int i_media_id );
-item_list_t* item_list_delItem( watch_thread_t *p_wt, input_item_t *p_item, bool );
-item_list_t* item_list_listitemOfMediaId( watch_thread_t *p_wt, int i_media_id );
-input_item_t* item_list_itemOfMediaId( watch_thread_t *p_wt, int i_media_id );
-ml_media_t* item_list_mediaOfMediaId( watch_thread_t *p_wt, int i_media_id );
-ml_media_t* item_list_mediaOfItem( watch_thread_t *p_wt, input_item_t* p_item, bool );
-int item_list_mediaIdOfItem( watch_thread_t *p_wt, input_item_t *p_item );
-int item_list_updateInput( watch_thread_t *p_wt, input_item_t *p_item,
-                           bool b_play_count );
-void item_list_destroy( watch_thread_t* p_wt );
-
-/**
- * @brief Simple hash function
- * @param item_id Hash Key
- * @return Hash index
- */
-static inline int item_hash( input_item_t* p_item )
-{
-    return DictHash( p_item->psz_uri, ML_ITEMLIST_HASH_LENGTH );
-}
-
-#endif /* ML_ITEM_LIST_H */
diff --git a/modules/media_library/media_pool.c b/modules/media_library/media_pool.c
deleted file mode 100644 (file)
index b868d4d..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*****************************************************************************
- * media_pool.c : Media pool for watching system
- *****************************************************************************
- * Copyright (C) 2009-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include "sql_media_library.h"
-
-#define mp_foreachlist( a, b ) for( ml_poolobject_t* b = a; b; b = b->p_next )
-
-static inline int mediapool_hash( int media_id )
-{
-    return media_id % ML_MEDIAPOOL_HASH_LENGTH;
-}
-
-/**
- * @brief Get a media from the pool
- * @param p_ml ML object
- * @param media_id The media id of the object to get
- * @return the found media or NULL if not found
- */
-ml_media_t* pool_GetMedia( media_library_t* p_ml, int media_id )
-{
-    vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
-    ml_media_t* p_media = NULL;
-    mp_foreachlist( p_ml->p_sys->p_mediapool[ mediapool_hash( media_id ) ], p_item )
-    {
-        if( p_item->p_media->i_id == media_id )
-        {
-            p_media = p_item->p_media;
-            break;
-        }
-    }
-    if( p_media )
-        ml_gc_incref( p_media );
-    vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
-    return p_media;
-}
-
-/**
- * @brief Insert a media into the media pool
- * @param p_ml ML object
- * @param p_media Media object to insert
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int pool_InsertMedia( media_library_t* p_ml, ml_media_t* p_media, bool locked )
-{
-    if( !locked )
-        ml_LockMedia( p_media );
-    assert( p_media );
-    assert( p_media->i_id > 0 );
-    if( p_media->ml_gc_data.pool )
-    {
-        msg_Dbg( p_ml, "Already in pool! %s %d", p_media->psz_uri, p_media->i_id );
-        ml_UnlockMedia( p_media );
-        return VLC_EGENERIC;
-    }
-    p_media->ml_gc_data.pool = true;
-    int i_ret = VLC_SUCCESS;
-    vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
-    mp_foreachlist( p_ml->p_sys->p_mediapool[ (mediapool_hash(p_media->i_id)) ], p_item )
-    {
-        if( p_media == p_item->p_media )
-        {
-            i_ret = VLC_EGENERIC;
-            break;
-        }
-        else if( p_media->i_id == p_item->p_media->i_id )
-        {
-            i_ret = VLC_EGENERIC;
-            msg_Warn( p_ml, "A media of the same id was found, but in different objects!" );
-            break;
-        }
-    }
-    if( i_ret == VLC_SUCCESS )
-    {
-        ml_poolobject_t* p_new = ( ml_poolobject_t * ) calloc( 1, sizeof( ml_poolobject_t* ) );
-        if( !p_new )
-            i_ret = VLC_EGENERIC;
-        else
-        {
-            ml_gc_incref( p_media );
-            p_new->p_media = p_media;
-            p_new->p_next = p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ];
-            p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ] = p_new;
-        }
-    }
-    vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
-    if( !locked )
-        ml_UnlockMedia( p_media );
-    return i_ret;
-}
-
-/**
- * @brief Perform a single garbage collection scan on the media pool
- * @param p_ml The ML object
- * @note Scans all media and removes any medias not held by any other objects.
- */
-void pool_GC( media_library_t* p_ml )
-{
-    vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
-    ml_poolobject_t* p_prev = NULL;
-    ml_media_t* p_media = NULL;
-    for( int i_idx = 0; i_idx < ML_MEDIAPOOL_HASH_LENGTH; i_idx++ )
-    {
-        p_prev = NULL;
-        for( ml_poolobject_t* p_item = p_ml->p_sys->p_mediapool[ i_idx ];
-                p_item != NULL; p_item = p_item->p_next )
-        {
-            p_media = p_item->p_media;
-            int refs;
-            refs = p_media->ml_gc_data.refs;
-            if( refs == 1 )
-            {
-                if( p_prev == NULL )
-                    p_ml->p_sys->p_mediapool[i_idx] = p_item->p_next;
-                else
-                    p_prev->p_next = p_item->p_next;
-                p_media->ml_gc_data.pool = false;
-                ml_gc_decref( p_item->p_media );//This should destroy the object
-                free( p_item );
-            }
-            p_prev = p_item;
-        }
-    }
-    vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
-}
diff --git a/modules/media_library/ml_watch.c b/modules/media_library/ml_watch.c
deleted file mode 100644 (file)
index 51ed194..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-/*****************************************************************************
- * ml_watch.c: SQL-based media library: Medias watching system
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include "sql_media_library.h"
-#include "item_list.h"
-#include <vlc_events.h>
-
-static void watch_ItemChange( const vlc_event_t *, void * );
-static int watch_PlaylistItemCurrent( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data );
-static int watch_PlaylistItemAppend( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data );
-static int watch_PlaylistItemDeleted( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data );
-static void watch_loop( media_library_t *p_ml, bool b_force );
-static void watch_Thread_Cleanup( void* p_object );
-static int watch_update_Item( media_library_t *p_ml, int i_media_id,
-                       input_item_t *p_item, bool b_raise_count, bool locked );
-static void watch_ProcessAppendQueue( media_library_t* p_ml );
-
-/**
- * @brief Watching thread
- */
-static void* watch_Thread( void *obj )
-{
-    watch_thread_t *p_watch = ( watch_thread_t* )obj;
-    media_library_t *p_ml = p_watch->p_ml;
-    int i_ret = 0;
-
-    vlc_mutex_lock( &p_watch->lock );
-    vlc_cleanup_push( watch_Thread_Cleanup, p_ml );
-    for( ;; )
-    {
-        watch_loop( p_ml, !i_ret );
-        i_ret = vlc_cond_timedwait( &p_watch->cond, &p_watch->lock,
-                                mdate() + 1000000 * THREAD_SLEEP_DELAY );
-    }
-    vlc_cleanup_run();
-    return NULL;
-}
-
-/**
- * @brief Callback for thread exit
- */
-static void watch_Thread_Cleanup( void* p_object )
-{
-    media_library_t* p_ml = ( media_library_t* )p_object;
-    watch_loop( p_ml, true );
-    vlc_mutex_unlock( &p_ml->p_sys->p_watch->lock );
-}
-/**
- * @brief Init watching system
- * @return Error if the object or the thread could not be created
- */
-int watch_Init( media_library_t *p_ml )
-{
-    /* init and launch watching thread */
-    p_ml->p_sys->p_watch = calloc( 1, sizeof(*p_ml->p_sys->p_watch) );
-    if( !p_ml->p_sys->p_watch )
-        return VLC_ENOMEM;
-
-    watch_thread_t* p_wt = p_ml->p_sys->p_watch;
-    vlc_mutex_init( &p_wt->list_mutex );
-    p_wt->p_ml = p_ml;
-
-    vlc_cond_init( &p_wt->cond );
-    vlc_mutex_init( &p_wt->lock );
-
-    /* Initialise item append queue */
-    vlc_mutex_init( &p_wt->item_append_queue_lock );
-    p_wt->item_append_queue = NULL;
-    p_wt->item_append_queue_count = 0;
-
-    if( vlc_clone( &p_wt->thread, watch_Thread, p_wt, VLC_THREAD_PRIORITY_LOW ) )
-    {
-        msg_Dbg( p_ml, "unable to launch the auto-updating thread" );
-        free( p_wt );
-        return VLC_EGENERIC;
-    }
-
-    /* Wait on playlist events
-     * playlist-item-append -> entry to playlist
-     * activity -> to ensure that we catch played item only!
-     * playlist-item-deleted -> exit from playlist
-     * item-change -> Currently not required, as we monitor input_item events
-     */
-    playlist_t *p_pl = pl_Get( p_ml );
-    var_AddCallback( p_pl, "activity", watch_PlaylistItemCurrent, p_ml );
-    var_AddCallback( p_pl, "playlist-item-append", watch_PlaylistItemAppend, p_ml );
-    var_AddCallback( p_pl, "playlist-item-deleted", watch_PlaylistItemDeleted, p_ml );
-
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Add the input to the watch system
- * @param p_ml The Media Library Object
- * @param p_item Item to be watched
- * @param p_media Corresponding media item to sync with
- * @param locked Status of item list lock
- * @return VLC_SUCCESS or error code
- */
-int __watch_add_Item( media_library_t *p_ml, input_item_t *p_item,
-                        ml_media_t* p_media, bool locked )
-{
-    vlc_gc_incref( p_item );
-    ml_gc_incref( p_media );
-    int i_ret = __item_list_add( p_ml->p_sys->p_watch, p_media, p_item, locked );
-    if( i_ret != VLC_SUCCESS )
-        return i_ret;
-    vlc_event_manager_t *p_em = &p_item->event_manager;
-    vlc_event_attach( p_em, vlc_InputItemMetaChanged, watch_ItemChange, p_ml );
-    vlc_event_attach( p_em, vlc_InputItemNameChanged, watch_ItemChange, p_ml );
-    vlc_event_attach( p_em, vlc_InputItemInfoChanged, watch_ItemChange, p_ml );
-    /*
-    Note: vlc_InputItemDurationChanged is disabled because
-          it is triggered too often, even without consequent changes
-    */
-    return VLC_SUCCESS;
-}
-
-
-/**
- * @brief Detach event manager
- * @param p_ml The Media Library Object
- */
-static void detachItemEvents( media_library_t *p_ml, input_item_t *p_item )
-{
-    vlc_event_manager_t *p_em = &p_item->event_manager;
-    vlc_event_detach( p_em, vlc_InputItemMetaChanged, watch_ItemChange, p_ml );
-    vlc_event_detach( p_em, vlc_InputItemNameChanged, watch_ItemChange, p_ml );
-    vlc_event_detach( p_em, vlc_InputItemInfoChanged, watch_ItemChange, p_ml );
-}
-
-
-/**
- * @brief Close the watching system
- * @param p_ml The Media Library Object
- */
-void watch_Close( media_library_t *p_ml )
-{
-    playlist_t *p_pl = pl_Get( p_ml );
-    var_DelCallback( p_pl, "playlist-item-deleted", watch_PlaylistItemDeleted, p_ml );
-    var_DelCallback( p_pl, "playlist-item-append", watch_PlaylistItemAppend, p_ml );
-    var_DelCallback( p_pl, "activity", watch_PlaylistItemCurrent, p_ml );
-
-    /* Flush item list */
-    il_foreachhashlist( p_ml->p_sys->p_watch->p_hlist, p_elt, ixx )
-    {
-        detachItemEvents( p_ml, p_elt->p_item );
-        ml_gc_decref( p_elt->p_media );
-        vlc_gc_decref( p_elt->p_item );
-    }
-    item_list_destroy( p_ml->p_sys->p_watch );
-
-    /* Stop the watch thread and join in */
-    vlc_cancel( p_ml->p_sys->p_watch->thread );
-    vlc_join( p_ml->p_sys->p_watch->thread, NULL );
-
-    /* Clear up other stuff */
-    vlc_mutex_destroy( &p_ml->p_sys->p_watch->lock );
-    vlc_cond_destroy( &p_ml->p_sys->p_watch->cond );
-    vlc_mutex_destroy( &p_ml->p_sys->p_watch->list_mutex );
-    free( p_ml->p_sys->p_watch );
-
-    free( p_ml->p_sys->p_watch->item_append_queue );
-    vlc_mutex_destroy( &p_ml->p_sys->p_watch->item_append_queue_lock );
-    p_ml->p_sys->p_watch = NULL;
-}
-
-/**
- * @brief Del item that is currently being watched
- * @param p_ml The Media Library Object
- * @param p_item Item to stop watching
- * @param locked Lock state of item list
- */
-int __watch_del_Item( media_library_t* p_ml, input_item_t* p_item, bool locked )
-{
-    assert( p_item );
-    item_list_t* p_tmp = item_list_delItem( p_ml->p_sys->p_watch, p_item, locked );
-    if( p_tmp == NULL )
-        return VLC_EGENERIC;
-    detachItemEvents( p_ml, p_tmp->p_item );
-    vlc_gc_decref( p_tmp->p_item );
-    ml_gc_decref( p_tmp->p_media );
-    free( p_tmp );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Del media from watching by ID
- * @param p_ml The Media Library Object
- * @param i_media_id Media ID
- */
-int watch_del_MediaById( media_library_t* p_ml, int i_media_id )
-{
-    assert( i_media_id > 0 );
-    item_list_t* p_elt = item_list_delMedia( p_ml->p_sys->p_watch, i_media_id );
-    if( p_elt == NULL )
-        return VLC_EGENERIC;
-    detachItemEvents( p_ml, p_elt->p_item );
-    vlc_gc_decref( p_elt->p_item );
-    ml_gc_decref( p_elt->p_media );
-    free( p_elt );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Get item using media id, if exists in item list
- * @param p_ml The Media Library Object
- * @param i_media_id Media ID
- */
-input_item_t* watch_get_itemOfMediaId( media_library_t *p_ml, int i_media_id )
-{
-    input_item_t* p_tmp = item_list_itemOfMediaId( p_ml->p_sys->p_watch, i_media_id );
-    if( p_tmp == NULL )
-        return NULL;
-    vlc_gc_incref( p_tmp );
-    return p_tmp;
-}
-
-/**
- * @brief Get media using media id, if exists in item list
- * @param p_ml The Media Library Object
- * @param i_media_id Media ID
- */
-ml_media_t* watch_get_mediaOfMediaId( media_library_t* p_ml, int i_media_id )
-{
-    ml_media_t* p_tmp = item_list_mediaOfMediaId( p_ml->p_sys->p_watch, i_media_id );
-    if( p_tmp == NULL )
-        return NULL;
-    ml_gc_incref( p_tmp );
-    return p_tmp;
-}
-
-/**
- * @brief Get mediaid of existing item
- * @param p_ml The Media Library Object
- * @param p_item Pointer to input item
- */
-int watch_get_mediaIdOfItem( media_library_t *p_ml, input_item_t *p_item )
-{
-    return item_list_mediaIdOfItem( p_ml->p_sys->p_watch, p_item );
-}
-
-/**
- * @brief Updates a media each time it is changed (name, info or meta)
- */
-static void watch_ItemChange( const vlc_event_t *event, void *data )
-{
-    input_item_t *p_item = ( input_item_t* ) event->p_obj;
-    media_library_t *p_ml = ( media_library_t* ) data;
-    /* Note: we don't add items to the item_list, but normally there should
-       not be any item at this point that is not in the list. */
-    if( item_list_updateInput( p_ml->p_sys->p_watch, p_item, false ) <= 0 )
-    {
-#ifndef NDEBUG
-        msg_Dbg( p_ml, "Couldn't update in watch_ItemChange(): (%s:%d)",
-                 __FILE__, __LINE__ );
-#endif
-    }
-
-    /*
-    if( event->type == vlc_InputItemMetaChanged )
-    {
-        int id = item_list_mediaIdOfItem( p_ml->p_sys->p_watch, p_item );
-        if( !id ) return;
-
-        * Tell the world what happened *
-        var_SetInteger( p_ml, "media-meta-change", id );
-    }
-    */
-}
-
-/**
- * @brief Callback when item is added to playlist
- */
-static int watch_PlaylistItemAppend( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data )
-{
-    VLC_UNUSED( oldval );
-    VLC_UNUSED( p_this );
-    VLC_UNUSED( psz_var );
-    media_library_t* p_ml = ( media_library_t* ) data;
-    playlist_t* p_playlist = pl_Get( p_ml );
-    playlist_add_t* p_add;
-    p_add = ( playlist_add_t* ) newval.p_address;
-    playlist_item_t* p_pitem = playlist_ItemGetById( p_playlist, p_add->i_item );
-    input_item_t* p_item = p_pitem->p_input;
-    watch_thread_t* p_wt = p_ml->p_sys->p_watch;
-
-    vlc_mutex_lock( &p_wt->list_mutex );
-    /* Check if we are already watching this item */
-    il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item->i_id == p_item->i_id )
-        {
-            p_elt->i_refs++;
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            goto quit_playlistitemappend;
-        }
-    }
-    vlc_mutex_unlock( &p_wt->list_mutex );
-
-    /* Add the the append queue */
-    vlc_mutex_lock( &p_wt->item_append_queue_lock );
-    p_wt->item_append_queue_count++;
-    p_wt->item_append_queue = realloc( p_wt->item_append_queue,
-            sizeof( input_item_t* ) * p_wt->item_append_queue_count );
-    vlc_gc_incref( p_item );
-    p_wt->item_append_queue[ p_wt->item_append_queue_count - 1 ] = p_item;
-    vlc_mutex_unlock( &p_wt->item_append_queue_lock );
-quit_playlistitemappend:
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Callback when item is deleted from playlist
- */
-static int watch_PlaylistItemDeleted( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data )
-{
-    VLC_UNUSED( oldval );
-    VLC_UNUSED( p_this );
-    VLC_UNUSED( psz_var );
-    media_library_t* p_ml = ( media_library_t* ) data;
-    playlist_t* p_playlist = pl_Get( p_ml );
-
-    /* Luckily this works, because the item isn't deleted from PL, yet */
-    playlist_item_t* p_pitem = playlist_ItemGetById( p_playlist, newval.i_int );
-    input_item_t* p_item = p_pitem->p_input;
-
-    /* Find the new item and decrement its ref */
-    il_foreachlist( p_ml->p_sys->p_watch->p_hlist[ item_hash( p_item ) ], p_elt )
-    {
-        if( p_elt->p_item->i_id == p_item->i_id )
-        {
-            p_elt->i_refs--;
-            break;
-        }
-    }
-
-    return VLC_SUCCESS;
-}
-/**
- * @brief Callback when watched input item starts playing
- * @note This will update playcount mainly
- * TODO: Increment playcount on playing 50%(configurable)
- */
-static int watch_PlaylistItemCurrent( vlc_object_t *p_this, char const *psz_var,
-                                  vlc_value_t oldval, vlc_value_t newval,
-                                  void *data )
-{
-    (void)p_this;
-    (void)oldval;
-    (void)newval;
-    media_library_t *p_ml = ( media_library_t* ) data;
-    input_item_t *p_item = NULL;
-
-    /* Get current input */
-    input_thread_t *p_input = pl_CurrentInput( p_ml );
-    p_item = p_input ? input_GetItem( p_input ) : NULL;
-
-    if( p_input )
-        vlc_object_release( p_input );
-
-    if( !p_item )
-        return VLC_EGENERIC;
-
-    if( item_list_updateInput( p_ml->p_sys->p_watch, p_item, true ) == 0 )
-    {
-#ifndef NDEBUG
-        msg_Dbg( p_ml, "couldn't in watch_PlaylistItemCurrent(): (%s:%d)",
-                 __FILE__, __LINE__ );
-#endif
-    }
-
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Update information in the DB for an input item
- *
- * @param p_ml this media library instance
- * @param i_media_id may be 0 (but not recommended)
- * @param p_item input item that was updated
- * @param b_raise_count increment the played count
- * @return result of UpdateMedia()
- */
-static int watch_update_Item( media_library_t *p_ml,
-                       int i_media_id, input_item_t *p_item,
-                       bool b_raise_count, bool locked )
-{
-#ifndef NDEBUG
-    msg_Dbg( p_ml, "automatically updating media %d", i_media_id );
-#endif
-    ml_media_t* p_media = item_list_mediaOfItem( p_ml->p_sys->p_watch, p_item, locked );
-    CopyInputItemToMedia( p_media, p_item );
-    ml_LockMedia( p_media );
-    p_media->i_played_count += b_raise_count ? 1 : 0;
-    ml_UnlockMedia( p_media );
-    int i_ret = UpdateMedia( p_ml, p_media );
-
-    /* Add the poster to the album */
-    ml_LockMedia( p_media );
-    if( p_media->i_album_id && p_media->psz_cover )
-    {
-        SetArtCover( p_ml, p_media->i_album_id, p_media->psz_cover );
-    }
-    ml_UnlockMedia( p_media );
-
-    return i_ret;
-}
-
-/**
- * @brief Signals the watch system to update all medias
- */
-void watch_Force_Update( media_library_t* p_ml )
-{
-    vlc_mutex_lock( &p_ml->p_sys->p_watch->lock );
-    vlc_cond_signal( &p_ml->p_sys->p_watch->cond );
-    vlc_mutex_unlock( &p_ml->p_sys->p_watch->lock );
-}
-
-/**
- * @brief Loop on the item_list: old objects collector and automatic updater
- *
- * This function is *not* a garbage collector. It actually decrefs items
- * when they are too old. ITEM_GC_MAX_AGE is the maximum 'time' an item
- * can stay in the list. After that, it is gc_decref'ed but not removed
- * from this list. If you try to get it after that, either the input item
- * is still alive, then you get it, or you'll have
- *
- * The update of an item is done when its age is >= ITEM_LOOP_UPDATE
- * (0 could lead to a too early update)
- *
- * A thread should call this function every N seconds
- *
- * @param p_ml the media library instance
- */
-static void watch_loop( media_library_t *p_ml, bool b_force )
-{
-    /* Do the garbage collection */
-    pool_GC( p_ml );
-
-    /* Process the append queue */
-    watch_ProcessAppendQueue( p_ml );
-
-    /* Do the item update if necessary */
-    vlc_mutex_lock( &p_ml->p_sys->p_watch->list_mutex );
-    item_list_t *p_prev = NULL;
-    il_foreachhashlist( p_ml->p_sys->p_watch->p_hlist, p_elt, ixx )
-    {
-        if( ( p_elt->i_update && p_elt->i_age >= ITEM_LOOP_UPDATE )
-                || b_force )
-        {
-            /* This is the automatic delayed update */
-            watch_update_Item( p_ml, p_elt->i_media_id, p_elt->p_item,
-                               ( p_elt->i_update & 2 ) ? true : false, true );
-            /* The item gets older */
-            p_prev = p_elt;
-            p_elt->i_age++;
-            p_elt->i_update = false;
-        }
-        else if( p_elt->i_refs == 0 )
-        {
-            if( p_elt->i_update )
-            watch_update_Item( p_ml, p_elt->i_media_id, p_elt->p_item,
-                               ( p_elt->i_update & 2 ) ? true : false, true );
-            __watch_del_Item( p_ml, p_elt->p_item, true );
-            /* TODO: Do something about below crazy hack */
-            if( p_prev != NULL )
-                p_elt = p_prev;
-            else
-            {
-                ixx--;
-                break;
-            }
-        }
-        else
-        {
-            p_prev = p_elt;
-            p_elt->i_age++;
-        }
-    }
-    vlc_mutex_unlock( &p_ml->p_sys->p_watch->list_mutex );
-}
-
-/**
- * This function goes through a queue of input_items and checks
- * if they are present in ML. All the items we wish to add in the
- * watch Queue
- */
-static void watch_ProcessAppendQueue( media_library_t* p_ml )
-{
-    watch_thread_t* p_wt = p_ml->p_sys->p_watch;
-    vlc_mutex_lock( &p_wt->item_append_queue_lock );
-    bool b_add = var_CreateGetBool( p_ml, "ml-auto-add" );
-    for( int i = 0; i < p_wt->item_append_queue_count; i++ )
-    {
-        input_item_t* p_item = p_wt->item_append_queue[i];
-        ml_media_t* p_media = NULL;
-        /* Is this item in ML? */
-        int i_media_id = GetMediaIdOfURI( p_ml, p_item->psz_uri );
-        int i_ret = 0;
-        if( i_media_id <= 0 )
-        {
-            if( b_add )
-            {
-                i_ret = AddInputItem( p_ml, p_item );
-                /* FIXME: Need to skip? */
-                if( i_ret != VLC_SUCCESS )
-                    continue;
-                i_media_id = GetMediaIdOfURI( p_ml, p_item->psz_uri );
-            }
-            else
-                continue;
-        }
-        vlc_mutex_lock( &p_wt->list_mutex );
-        p_media = media_New( p_ml, i_media_id, ML_MEDIA, true );
-        if( p_media == NULL )
-        {
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            continue;
-        }
-        /* If duplicate, then it just continues */
-        i_ret = __watch_add_Item( p_ml, p_item, p_media, true );
-        if( i_ret != VLC_SUCCESS )
-        {
-            ml_gc_decref( p_media );
-            vlc_mutex_unlock( &p_wt->list_mutex );
-            continue;
-        }
-
-        /* Find the new item and increment its ref */
-        il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
-        {
-            if( p_elt->p_item->i_id == p_item->i_id )
-            {
-                p_elt->i_refs++;
-                break;
-            }
-        }
-        vlc_mutex_unlock( &p_wt->list_mutex );
-        ml_gc_decref( p_media );
-    }
-    p_wt->item_append_queue_count = 0;
-    FREENULL( p_wt->item_append_queue );
-    vlc_mutex_unlock( &p_wt->item_append_queue_lock );
-}
diff --git a/modules/media_library/sql_add.c b/modules/media_library/sql_add.c
deleted file mode 100644 (file)
index 380eb65..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*****************************************************************************
- * sql_add.c: SQL-based media library
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include "sql_media_library.h"
-
-/*****************************************************************************
- * ADD FUNCTIONS
- *****************************************************************************/
-
-/**
- * @brief Add element to ML based on a ml_media_t (media ID ignored)
- * @param p_ml This media_library_t object
- * @param p_media media item to add in the DB. The media_id is ignored
- * @return VLC_SUCCESS or VLC_EGENERIC
- * @note This function is threadsafe
- */
-int AddMedia( media_library_t *p_ml, ml_media_t *p_media )
-{
-    int i_ret = VLC_SUCCESS;
-    int i_album_artist = 0;
-
-    Begin( p_ml );
-    ml_LockMedia( p_media );
-    assert( p_media->i_id == 0 );
-    /* Add any people */
-    ml_person_t* person = p_media->p_people;
-    while( person )
-    {
-        if( person->i_id <= 0 )
-        {
-            if( person->psz_name )
-            {
-                person->i_id = ml_GetInt( p_ml, ML_PEOPLE_ID, person->psz_role,
-                                            ML_PEOPLE, person->psz_role,
-                                            person->psz_name );
-                if( person->i_id <= 0 )
-                {
-                    /* Create person */
-                    AddPeople( p_ml, person->psz_name, person->psz_role );
-                    person->i_id = ml_GetInt( p_ml, ML_PEOPLE_ID, person->psz_role,
-                                            ML_PEOPLE, person->psz_role,
-                                            person->psz_name );
-                }
-
-            }
-        }
-        if( strcmp( person->psz_role, ML_PERSON_ALBUM_ARTIST ) == 0 )
-            i_album_artist = person->i_id;
-        person = person->p_next;
-    }
-
-    /* Album id */
-    if( p_media->i_album_id <= 0 )
-    {
-        if( p_media->psz_album )
-        {
-            /* TODO:Solidly incorporate Album artist */
-            int i_album_id = ml_GetAlbumId( p_ml, p_media->psz_album );
-            if( i_album_id <= 0 )
-            {
-                /* Create album */
-                i_ret = AddAlbum( p_ml, p_media->psz_album, p_media->psz_cover,
-                                    i_album_artist );
-                if( i_ret != VLC_SUCCESS )
-                    return i_ret;
-                i_album_id = ml_GetAlbumId( p_ml, p_media->psz_album );
-                if( i_album_id <= 0 )
-                    return i_ret;
-            }
-            p_media->i_album_id = i_album_id;
-        }
-    }
-
-
-    if( !p_media->psz_uri || !*p_media->psz_uri )
-    {
-        msg_Dbg( p_ml, "cannot add a media without uri (%s)", __func__ );
-        return VLC_EGENERIC;
-    }
-
-    i_ret = QuerySimple( p_ml,
-            "INSERT INTO media ( uri, title, original_title, genre, type, "
-            "comment, cover, preview, year, track, disc, album_id, vote, score, "
-            "duration, first_played, played_count, last_played, "
-            "skipped_count, last_skipped, import_time, filesize ) "
-            "VALUES ( %Q, %Q, %Q, %Q, '%d',%Q, %Q, %Q, '%d', '%d', '%d', '%d',"
-            "'%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d' )",
-                p_media->psz_uri,
-                p_media->psz_title,
-                p_media->psz_orig_title,
-                p_media->psz_genre,
-                (int)p_media->i_type,
-                p_media->psz_comment,
-                p_media->psz_cover,
-                p_media->psz_preview,
-                (int)p_media->i_year,
-                (int)p_media->i_track_number,
-                (int)p_media->i_disc_number,
-                (int)p_media->i_album_id,
-                (int)p_media->i_vote,
-                (int)p_media->i_score,
-                (int)p_media->i_duration,
-                (int)p_media->i_first_played,
-                (int)p_media->i_played_count,
-                (int)p_media->i_last_played,
-                (int)p_media->i_skipped_count,
-                (int)p_media->i_last_skipped,
-                (int)p_media->i_import_time,
-                (int)p_media->i_filesize );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_addmedia;
-
-    int id = GetMediaIdOfURI( p_ml, p_media->psz_uri );
-    if( id <= 0 )
-    {
-        i_ret = VLC_EGENERIC;
-        goto quit_addmedia;
-    }
-
-    p_media->i_id = id;
-    person = p_media->p_people;
-    if( !person )
-    {
-        /* If there is no person, set it to "Unknown", ie. people_id=0 */
-        i_ret = QuerySimple( p_ml, "INSERT into media_to_people ( media_id, "
-                                     "people_id ) VALUES ( %d, %d )",
-                                     id, 0 );
-        if( i_ret != VLC_SUCCESS )
-            goto quit_addmedia;
-    } else {
-        while( person )
-        {
-            i_ret = QuerySimple( p_ml, "INSERT into media_to_people ( media_id, "
-                                         "people_id ) VALUES ( %d, %d )",
-                                         id, person->i_id );
-            if( i_ret != VLC_SUCCESS )
-                goto quit_addmedia;
-            person = person->p_next;
-        }
-    }
-
-    i_ret = QuerySimple( p_ml, "INSERT into extra ( id, extra, language, bitrate, "
-            "samplerate, bpm ) VALUES ( '%d', %Q, %Q, '%d', '%d', '%d' )",
-            id, p_media->psz_extra, p_media->psz_language,
-            p_media->i_bitrate, p_media->i_samplerate, p_media->i_bpm );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_addmedia;
-    i_ret = pool_InsertMedia( p_ml, p_media, true );
-
-quit_addmedia:
-    if( i_ret == VLC_SUCCESS )
-    {
-        Commit( p_ml );
-    }
-    else
-        Rollback( p_ml );
-    ml_UnlockMedia( p_media );
-    if( i_ret == VLC_SUCCESS )
-        var_SetInteger( p_ml, "media-added", id );
-    return i_ret;
-}
-
-
-/**
- * @brief Add generic album to ML
- *
- * @param p_ml this Media Library
- * @param psz_title album title, cannot be null
- * @param psz_cover album cover, can be null
- * @return VLC_SUCCESS or a VLC error code
- *
- * This will add a new in the album table, without checking if album is
- * already present (or another album with same title)
- */
-int AddAlbum( media_library_t *p_ml, const char *psz_title,
-        const char *psz_cover, const int i_album_artist )
-{
-    assert( p_ml );
-
-    if( !psz_title || !*psz_title )
-    {
-        msg_Warn( p_ml, "tried to add an album without title" );
-        return VLC_EGENERIC;
-    }
-    msg_Dbg( p_ml, "New album: '%s'", psz_title );
-
-    int i_ret = QuerySimple( p_ml,
-                        "INSERT INTO album ( title, cover, album_artist_id ) "
-                        "VALUES ( %Q, %Q, '%d' )",
-                        psz_title , psz_cover, i_album_artist );
-
-    return i_ret;
-}
-
-
-/**
- * @brief Add generic people to ML
- *
- * @param p_ml this Media Library
- * @param psz_title name
- * @param i_role role: 1 for artist, 2 for publisher
- * @return VLC_SUCCESS or a VLC error code
- *
- * This will add a new in the album table, without checking if album is
- * already present (or another album with same title)
- */
-int AddPeople( media_library_t *p_ml, const char *psz_name,
-        const char* psz_role )
-{
-    assert( p_ml );
-    assert( psz_role && *psz_role );
-
-    if( !psz_name || !*psz_name )
-    {
-        msg_Warn( p_ml, "tried to add an artist without name" );
-        return VLC_EGENERIC;
-    }
-    msg_Dbg( p_ml, "New people: (%s) '%s'", psz_role, psz_name );
-
-    int i_ret = QuerySimple( p_ml,
-                             "INSERT INTO people ( name, role ) "
-                             "VALUES ( %Q, %Q )",
-                             psz_name, psz_role );
-
-    return i_ret;
-}
-
-/**
- * @brief Add element to ML based on an Input Item
- * @param p_ml This media_library_t object
- * @param p_input input item to add
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int AddInputItem( media_library_t *p_ml, input_item_t *p_input )
-{
-    assert( p_ml );
-    if( !p_input || !p_input->psz_uri )
-        return VLC_EGENERIC;
-    int i_ret = VLC_SUCCESS;
-
-    vlc_gc_incref( p_input );
-
-    /* Check input item is not already in the ML */
-    i_ret = GetMediaIdOfInputItem( p_ml, p_input );
-    if( i_ret > 0 )
-    {
-        msg_Dbg( p_ml, "Item already in Media Library (id: %d)", i_ret );
-        vlc_gc_decref( p_input );
-        return VLC_SUCCESS;
-    }
-
-    ml_media_t* p_media = media_New( p_ml, 0, ML_MEDIA, false );
-
-    /* Add media to the database */
-    CopyInputItemToMedia( p_media, p_input );
-    i_ret = AddMedia( p_ml, p_media );
-    if( i_ret == VLC_SUCCESS )
-        watch_add_Item( p_ml, p_input, p_media );
-    ml_gc_decref( p_media );
-    vlc_gc_decref( p_input );
-    return i_ret;
-}
-
-
-/**
- * @brief Add element to ML based on a Playlist Item
- *
- * @param p_ml the media library object
- * @param p_playlist_item playlist_item to add
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int AddPlaylistItem( media_library_t *p_ml, playlist_item_t *p_playlist_item )
-{
-    if( !p_playlist_item )
-        return VLC_EGENERIC;
-
-    return AddInputItem( p_ml, p_playlist_item->p_input );
-}
-
diff --git a/modules/media_library/sql_delete.c b/modules/media_library/sql_delete.c
deleted file mode 100644 (file)
index 10d4bf8..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*****************************************************************************
- * sql_delete.c: SQL-based media library: all database delete functions
- *****************************************************************************
- * Copyright (C) 2008-2010 The VideoLAN Team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "sql_media_library.h"
-
-
-/**
- * @brief Generic DELETE function for many medias
- * Delete a media and all its referencies which don't point
- * an anything else.
- *
- * @param p_ml This media_library_t object
- * @param p_array list of ids to delete
- * @return VLC_SUCCESS or VLC_EGENERIC
- * TODO: Expand to delete media/artist/album given any params
- */
-int Delete( media_library_t *p_ml, vlc_array_t *p_array )
-{
-    char *psz_idlist = NULL, *psz_tmp = NULL;
-    int i_return = VLC_ENOMEM;
-
-    int i_rows = 0, i_cols = 0;
-    char **pp_results = NULL;
-
-    if( vlc_array_count( p_array ) <= 0 )
-    {
-        i_return = VLC_SUCCESS;
-        goto quit_delete_final;
-    }
-    for( int i = 0; i < vlc_array_count( p_array ); i++ )
-    {
-        ml_element_t* find = ( ml_element_t * )
-            vlc_array_item_at_index( p_array, i );
-        assert( find->criteria == ML_ID );
-        if( !psz_idlist )
-        {
-            if( asprintf( &psz_tmp, "( %d", find->value.i ) == -1)
-            {
-                goto quit_delete_final;
-            }
-        }
-        else
-        {
-            if( asprintf( &psz_tmp, "%s, %d", psz_idlist,
-                    find->value.i ) == -1)
-            {
-                goto quit_delete_final;
-            }
-        }
-        free( psz_idlist );
-        psz_idlist = psz_tmp;
-        psz_tmp = NULL;
-    }
-    free( psz_tmp );
-    if( asprintf( &psz_tmp, "%s )", psz_idlist ? psz_idlist : "(" ) == -1 )
-    {
-        goto quit_delete_final;
-    }
-    psz_idlist = psz_tmp;
-    psz_tmp = NULL;
-
-    msg_Dbg( p_ml, "Multi Delete id list: %s", psz_idlist );
-
-    /**
-     * Below ensures you are emitting media-deleted only
-     * for existant media
-     */
-    Begin( p_ml );
-    i_return = Query( p_ml, &pp_results, &i_rows, &i_cols,
-            "SELECT id FROM media WHERE id IN %s", psz_idlist );
-    if( i_return != VLC_SUCCESS )
-        goto quit;
-
-    i_return = QuerySimple( p_ml,
-            "DELETE FROM media WHERE media.id IN %s", psz_idlist );
-    if( i_return != VLC_SUCCESS )
-        goto quit;
-
-    i_return = QuerySimple( p_ml,
-            "DELETE FROM extra WHERE extra.id IN %s", psz_idlist );
-    if( i_return != VLC_SUCCESS )
-        goto quit;
-
-quit:
-    if( i_return == VLC_SUCCESS )
-    {
-        Commit( p_ml );
-        /* Emit delete on var media-deleted */
-        for( int i = 1; i <= i_rows; i++ )
-        {
-            var_SetInteger( p_ml, "media-deleted", atoi( pp_results[i*i_cols] ) );
-        }
-    }
-    else
-        Rollback( p_ml );
-quit_delete_final:
-    FreeSQLResult( p_ml, pp_results );
-    free( psz_tmp );
-    free( psz_idlist );
-    return i_return;
-}
diff --git a/modules/media_library/sql_media_library.c b/modules/media_library/sql_media_library.c
deleted file mode 100644 (file)
index 6a5788d..0000000
+++ /dev/null
@@ -1,1428 +0,0 @@
-/*****************************************************************************
- * sql_media_library.c: SQL-based media library
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "sql_media_library.h"
-
-static const char* ppsz_AudioExtensions[] = { EXTENSIONS_AUDIO_CSV, NULL };
-static const char* ppsz_VideoExtensions[] = { EXTENSIONS_VIDEO_CSV, NULL };
-
-#define MEDIA_LIBRARY_PATH_TEXT N_( "Filename of the SQLite database" )
-#define MEDIA_LIBRARY_PATH_LONGTEXT N_( "Path to the file containing " \
-                                        "the SQLite database" )
-
-#define IGNORE_TEXT N_( "Ignored extensions in the media library" )
-#define IGNORE_LONGTEXT N_( "Files with these extensions will not be added to"\
-                            " the media library when scanning directories." )
-
-#define RECURSIVE_TEXT N_( "Subdirectory recursive scanning" )
-#define RECURSIVE_LONGTEXT N_( "When scanning a directory, scan also all its"\
-        " subdirectories." )
-
-
-
-/*****************************************************************************
- * Static functions
- *****************************************************************************/
-
-/* Module entry point and exit point */
-static int load( vlc_object_t* );
-static void unload( vlc_object_t* );
-
-static int CreateInputItemFromMedia( input_item_t **pp_item,
-                                     ml_media_t *p_media );
-
-
-struct ml_table_elt
-{
-    int column_id;
-    const char* column_name;
-};
-
-static int compare_ml_elts( const void *a, const void *b )
-{
-    return strcmp( ( (struct ml_table_elt* )a )->column_name,
-            ( ( struct ml_table_elt* )b )->column_name );
-}
-
-static const struct ml_table_elt ml_table_map[]=
-{
-    { ML_ALBUM_COVER,    "album_cover" },
-    { ML_ALBUM_ID,       "album_id" },
-    { ML_ALBUM,          "album_title" },
-    { ML_COMMENT,        "comment" },
-    { ML_COVER,          "cover" },
-    { ML_DIRECTORY,      "directory_id" },
-    { ML_DISC_NUMBER,    "disc" },
-    { ML_DURATION,       "duration" },
-    { ML_EXTRA,          "extra" },
-    { ML_FILESIZE,       "filesize" },
-    { ML_FIRST_PLAYED,   "first_played" },
-    { ML_GENRE,          "genre" },
-    { ML_ID,             "id" },
-    { ML_IMPORT_TIME,    "import_time" },
-    { ML_LANGUAGE,       "language" },
-    { ML_LAST_PLAYED,    "last_played" },
-    { ML_LAST_SKIPPED,   "last_skipped" },
-    { ML_ORIGINAL_TITLE, "original_title" },
-    { ML_PEOPLE_ID,      "people_id" },
-    { ML_PEOPLE,         "people_name" },
-    { ML_PEOPLE_ROLE,    "people_role" },
-    { ML_PLAYED_COUNT,   "played_count" },
-    { ML_PREVIEW,        "preview" },
-    { ML_SCORE,          "score" },
-    { ML_SKIPPED_COUNT,  "skipped_count" },
-    { ML_TITLE,          "title" },
-    { ML_TRACK_NUMBER,   "track" },
-    { ML_TYPE,           "type" },
-    { ML_URI,            "uri" },
-    { ML_VOTE,           "vote" },
-    { ML_YEAR,           "year" }
-};
-
-/*****************************************************************************
- * Module description
- *****************************************************************************/
-vlc_module_begin()
-    set_shortname( "Media Library" )
-    set_description( _( "Media Library based on a SQL based database" ) )
-    set_capability( "media-library", 1 )
-    set_callbacks( load, unload )
-    set_category( CAT_ADVANCED )
-    set_subcategory( SUBCAT_ADVANCED_MISC )
-    add_string( "ml-filename", "vlc-media-library.db",
-            MEDIA_LIBRARY_PATH_TEXT, MEDIA_LIBRARY_PATH_LONGTEXT, false )
-    add_string( "ml-username", "",  N_( "Username for the database" ),
-            N_( "Username for the database" ), false )
-    add_string( "ml-password", "",  N_( "Password for the database" ),
-            N_( "Password for the database" ), false )
-    add_integer( "ml-port", 0,
-            N_( "Port for the database" ), N_("Port for the database"), false )
-    add_bool( "ml-recursive-scan", true, RECURSIVE_TEXT,
-            RECURSIVE_LONGTEXT, false )
-    add_bool( "ml-auto-add", true,  N_("Auto add new medias"),
-            N_( "Automatically add new medias to ML" ), false )
-    add_bool( "ml-synchronous", true,  N_("Use transactions"),
-            N_( "Disabling transactions saves I/O but can corrupt database in case of crash" ), false )
-vlc_module_end()
-
-
-/**
- * @brief Load module
- * @param obj Parent object
- */
-static int load( vlc_object_t *obj )
-{
-    msg_Dbg( obj, "loading media library module" );
-
-    media_library_t *p_ml = ( media_library_t * ) obj;
-    p_ml->p_sys = ( media_library_sys_t* )
-                        calloc( 1, sizeof( media_library_sys_t ) );
-    if( !p_ml->p_sys )
-        return VLC_ENOMEM;
-
-    p_ml->functions.pf_Find               = FindVa;
-    p_ml->functions.pf_FindAdv            = FindAdv;
-    p_ml->functions.pf_Control            = Control;
-    p_ml->functions.pf_InputItemFromMedia = GetInputItemFromMedia;
-    p_ml->functions.pf_Update             = Update;
-    p_ml->functions.pf_Delete             = Delete;
-    p_ml->functions.pf_GetMedia           = GetMedia;
-
-    vlc_mutex_init( &p_ml->p_sys->lock );
-
-    /* Initialise Sql module */
-    if ( InitDatabase( p_ml ) != VLC_SUCCESS )
-    {
-        vlc_mutex_destroy( &p_ml->p_sys->lock );
-        free( p_ml->p_sys );
-        return VLC_EGENERIC;
-    }
-
-    /* Initialise the media pool */
-    ARRAY_INIT( p_ml->p_sys->mediapool );
-    vlc_mutex_init( &p_ml->p_sys->pool_mutex );
-
-    /* Create variables system */
-    var_Create( p_ml, "media-added", VLC_VAR_INTEGER );
-    var_Create( p_ml, "media-deleted", VLC_VAR_INTEGER );
-    var_Create( p_ml, "media-meta-change", VLC_VAR_INTEGER );
-
-    /* Launching the directory monitoring thread */
-    monitoring_thread_t *p_mon =
-            vlc_object_create( p_ml, sizeof( monitoring_thread_t ) );
-    if( !p_mon )
-    {
-        vlc_mutex_destroy( &p_ml->p_sys->lock );
-        sql_Destroy( p_ml->p_sys->p_sql );
-        free( p_ml->p_sys );
-        return VLC_ENOMEM;
-    }
-    p_ml->p_sys->p_mon = p_mon;
-
-    p_mon->p_ml = p_ml;
-
-    if( vlc_clone( &p_mon->thread, RunMonitoringThread, p_mon,
-                VLC_THREAD_PRIORITY_LOW ) )
-    {
-        msg_Err( p_ml, "cannot spawn the media library monitoring thread" );
-        vlc_mutex_destroy( &p_ml->p_sys->lock );
-        sql_Destroy( p_ml->p_sys->p_sql );
-        free( p_ml->p_sys );
-        vlc_object_release( p_mon );
-        return VLC_EGENERIC;
-    }
-    /* Starting the watching system (starts a thread) */
-    watch_Init( p_ml );
-
-    msg_Dbg( p_ml, "Media library module loaded successfully" );
-
-    return VLC_SUCCESS;
-}
-
-
-/**
- * @brief Unload module
- *
- * @param obj the media library object
- * @return Nothing
- */
-static void unload( vlc_object_t *obj )
-{
-    media_library_t *p_ml = ( media_library_t* ) obj;
-
-    /* Stopping the watching system */
-    watch_Close( p_ml );
-
-    /* Stop the monitoring thread */
-    vlc_cancel( p_ml->p_sys->p_mon->thread );
-    vlc_join( p_ml->p_sys->p_mon->thread, NULL );
-    vlc_object_release( p_ml->p_sys->p_mon );
-
-    /* Destroy the variable */
-    var_Destroy( p_ml, "media-meta-change" );
-    var_Destroy( p_ml, "media-deleted" );
-    var_Destroy( p_ml, "media-added" );
-
-    /* Empty the media pool */
-    ml_media_t* item;
-    FOREACH_ARRAY( item, p_ml->p_sys->mediapool )
-        ml_gc_decref( item );
-    FOREACH_END()
-    vlc_mutex_destroy( &p_ml->p_sys->pool_mutex );
-
-    sql_Destroy( p_ml->p_sys->p_sql );
-
-    vlc_mutex_destroy( &p_ml->p_sys->lock );
-
-    free( p_ml->p_sys );
-}
-
-/**
- * @brief Get results of an SQL-Query on the database (please : free the result)
- *
- * @param p_ml the media library object
- * @param ppp_res char *** in which to store the table of results (allocated)
- * @param pi_rows resulting row number in table
- * @param pi_cols resulting column number in table
- * @param psz_fmt query command with printf-like format enabled
- * @param va_args format the command
- * @return VLC_SUCCESS or a VLC error code
- */
-int Query( media_library_t *p_ml,
-              char ***ppp_res, int *pi_rows, int *pi_cols,
-              const char *psz_fmt, ... )
-{
-    va_list argp;
-    va_start( argp, psz_fmt );
-
-    int i_ret = QueryVa( p_ml, ppp_res, pi_rows, pi_cols, psz_fmt, argp );
-
-    va_end( argp );
-    return i_ret;
-}
-
-/**
- * @brief Get results of an SQL-Query on the database (please : free the result)
- *
- * @param p_ml the media library object
- * @param ppp_res char *** in which to store the table of results (allocated)
- * @param pi_rows resulting row number in table
- * @param pi_cols resulting column number in table
- * @param psz_fmt query command with printf-like format enabled
- * @param va_args format the command
- * @return VLC_SUCCESS or a VLC error code
- */
-int QueryVa( media_library_t *p_ml, char ***ppp_res,
-                      int *pi_rows, int *pi_cols, const char *psz_fmt,
-                      va_list argp )
-{
-    assert( p_ml );
-    if( !ppp_res || !psz_fmt ) return VLC_EGENERIC;
-
-    char *psz_query = sql_VPrintf( p_ml->p_sys->p_sql, psz_fmt, argp );
-    if( !psz_query )
-        return VLC_ENOMEM;
-
-    int i_ret = sql_Query( p_ml->p_sys->p_sql, psz_query,
-                           ppp_res, pi_rows, pi_cols );
-
-    free( psz_query );
-    return i_ret;
-}
-
-/**
- * @brief Do a SQL-query without any data coming back
- *
- * @param p_ml the media library object
- * @param psz_fmt query command with printf-like format enabled
- * @param va_args format the command
- * @return VLC_SUCCESS or a VLC error code
- */
-int QuerySimple( media_library_t *p_ml,
-                    const char *psz_fmt, ... )
-{
-    va_list argp;
-    va_start( argp, psz_fmt );
-
-    int i_ret = QuerySimpleVa( p_ml, psz_fmt, argp );
-
-    va_end( argp );
-    return i_ret;
-}
-
-/**
- * @brief Do a SQL-query without any data coming back
- *
- * @param p_ml the media library object
- * @param psz_fmt query command with printf-like format enabled
- * @param argp format the command
- * @return VLC_SUCCESS or a VLC error code
- */
-int QuerySimpleVa( media_library_t *p_ml,
-                      const char *psz_fmt, va_list argp )
-{
-    assert( p_ml );
-
-    int i_ret = VLC_SUCCESS;
-    int i_rows, i_cols;
-    char **pp_results = NULL;
-
-    i_ret = QueryVa( p_ml, &pp_results, &i_rows, &i_cols, psz_fmt, argp );
-
-    FreeSQLResult( p_ml, pp_results );
-    va_end( argp );
-
-    return i_ret;
-}
-
-/**
- * @brief Transforms a string to a ml_result_t, with given type and id (as psz)
- *
- * @param res the result of the function
- * @param psz string to transform into a result
- * @param psz_id id as a string
- * @param result_type type of the result
- * @return ID or a VLC error code
- */
-int StringToResult( ml_result_t *p_result, const char *psz,
-                    const char *psz_id, ml_result_type_e result_type )
-{
-    memset( &p_result->value, 0, sizeof( p_result->value ) );
-
-    p_result->id = psz_id ? atoi( psz_id ) : 0;
-    p_result->type = result_type;
-
-    switch( result_type )
-    {
-        case ML_TYPE_INT:
-            p_result->value.i = psz ? atoi( psz ) : 0;
-            break;
-
-        case ML_TYPE_TIME:
-            p_result->value.time = psz ? ( mtime_t ) atoi( psz )
-                                       : ( mtime_t ) 0LL;
-            break;
-
-        case ML_TYPE_PSZ:
-            p_result->value.psz = psz ? strdup( psz ) : NULL;
-            break;
-
-        case ML_TYPE_MEDIA:
-        default:
-            /* This is an error */
-            return VLC_EGENERIC;
-    }
-
-    return p_result->id;
-}
-
-
-/**
- * @brief fills an ml_result_array_t with result of an SQL query
- *
- * @param p_ml the media library object
- * @param p_media ml_result_array_t object to fill
- * @param pp_results result of sql query
- * @param i_rows row number
- * @param i_cols column number
- * @param result_type type of the result
- * @return VLC_SUCCESS or a VLC error code
- **/
-int SQLToResultArray( media_library_t *p_ml, vlc_array_t *p_result_array,
-                      char **pp_results, int i_rows, int i_cols,
-                      ml_result_type_e result_type )
-{
-    assert( p_ml );
-    if( !p_result_array )
-        return VLC_EGENERIC;
-    if( i_cols == 0 )   /* No result */
-        return VLC_SUCCESS;
-    if( i_cols < 0 )
-    {
-        msg_Err( p_ml, "negative number of columns in result ?" );
-        return VLC_EGENERIC;
-    }
-
-    if( i_cols == 1 )
-    {
-        for( int i = 1; i <= i_rows; i++ )
-        {
-            ml_result_t *res = ( ml_result_t* )
-                                    calloc( 1, sizeof( ml_result_t ) );
-            if( !res )
-                return VLC_ENOMEM;
-            StringToResult( res, pp_results[ i ], NULL, result_type );
-            vlc_array_append( p_result_array, res );
-        }
-    }
-    /* FIXME?: Assuming all double column results are id - result pairs */
-    else if( ( i_cols == 2 ) )
-    {
-        for( int i = 1; i <= i_rows; i++ )
-        {
-            ml_result_t *res = ( ml_result_t* )
-                                    calloc( 1, sizeof( ml_result_t ) );
-            if( !res )
-                return VLC_ENOMEM;
-            StringToResult( res, pp_results[ i * 2 + 1], pp_results[ i * 2 ],
-                            result_type );
-            vlc_array_append( p_result_array, res );
-        }
-    }
-    else if( result_type == ML_TYPE_MEDIA )
-    {
-        return SQLToMediaArray( p_ml, p_result_array,
-                                pp_results, i_rows, i_cols );
-    }
-    else
-    {
-        msg_Err( p_ml, "unable to convert SQL result to a ml_result_t array" );
-        return VLC_EGENERIC;
-    }
-    return VLC_SUCCESS;
-}
-
-
-/**
- * @brief fills a vlc_array_t with results of an SQL query
- *        medias in ml_result_t
- *
- * @param p_ml the media library object
- * @param p_array array to fill with ml_media_t elements (might be initialized)
- * @param pp_results result of sql query
- * @param i_rows row number
- * @param i_cols column number
- * @return VLC_SUCCESS or a VLC error code
- * Warning: this returns VLC_EGENERIC if i_rows == 0 (empty result)
- **/
-int SQLToMediaArray( media_library_t *p_ml, vlc_array_t *p_result_array,
-                     char **pp_results, int i_rows, int i_cols )
-{
-    int i_ret = VLC_SUCCESS;
-    assert( p_ml );
-
-    #define res( i, j ) ( pp_results[ i * i_cols + j ] )
-    #define atoinull( a ) ( (a) ? atoi( a ) : 0 )
-    #define strdupnull( a ) ( (a) ? strdup( a ) : NULL )
-
-    if( i_rows == 0 )
-        return VLC_EGENERIC;
-
-    if( !p_result_array || !pp_results || i_rows < 0 || i_cols <= 0 )
-    {
-        msg_Warn( p_ml, "bad arguments (%s:%d)", __FILE__, __LINE__ );
-        return VLC_EGENERIC;
-    }
-
-    vlc_array_t* p_intermediate_array = vlc_array_new();
-
-    /* Analyze first row */
-    int *indexes = ( int* ) calloc( i_cols + 1, sizeof( int ) );
-    if( !indexes )
-    {
-        vlc_array_destroy( p_intermediate_array );
-        return VLC_ENOMEM;
-    }
-
-    const int count = sizeof( ml_table_map )/ sizeof( struct ml_table_elt );
-    for( int col = 0; col < i_cols; col++ )
-    {
-        struct ml_table_elt key, *result = NULL;
-        key.column_name = res( 0, col );
-        result = bsearch( &key, ml_table_map, count,
-                sizeof( struct ml_table_elt ), compare_ml_elts );
-
-        if( !result )
-            msg_Warn( p_ml, "unknown column: %s", res( 0, col ) );
-        else
-            indexes[col] = result->column_id;
-    }
-
-    /* Read rows 1 to i_rows */
-    ml_media_t  *p_media  = NULL;
-    ml_result_t *p_result = NULL;
-
-    for( int row = 1; ( row <= i_rows ) && ( i_ret == VLC_SUCCESS ); row++ )
-    {
-        p_media = media_New( p_ml, 0, ML_MEDIA, false );
-        if( !p_media )
-        {
-            free( indexes );
-            i_ret = VLC_ENOMEM;
-            goto quit_sqlmediaarray;
-        }
-        p_result = ( ml_result_t * ) calloc( 1, sizeof( ml_result_t ) );
-        if( !p_result )
-        {
-            ml_gc_decref( p_media );
-            free( indexes );
-            i_ret = VLC_ENOMEM;
-            goto quit_sqlmediaarray;
-        }
-
-        char* psz_append_pname = NULL;
-        char* psz_append_prole = NULL;
-        int i_append_pid = 0;
-
-#define SWITCH_INT( key, value ) case key: \
-        p_media-> value = atoinull( res( row, col ) );
-#define SWITCH_PSZ( key, value ) case key: \
-        p_media-> value = strdupnull( res( row, col ) );
-
-        ml_LockMedia( p_media );
-        for( int col = 0; ( col < i_cols ) && ( i_ret == VLC_SUCCESS ); col++ )
-        {
-            switch( indexes[ col ] )
-            {
-                SWITCH_INT( ML_ALBUM_ID, i_album_id );
-                SWITCH_PSZ( ML_ALBUM, psz_album );
-                SWITCH_PSZ( ML_COMMENT, psz_comment );
-                SWITCH_INT( ML_DISC_NUMBER, i_disc_number );
-                SWITCH_INT( ML_DURATION, i_duration );
-                SWITCH_PSZ( ML_EXTRA, psz_extra );
-                SWITCH_INT( ML_FILESIZE, i_filesize );
-                SWITCH_INT( ML_FIRST_PLAYED, i_first_played );
-                SWITCH_PSZ( ML_GENRE, psz_genre);
-                SWITCH_INT( ML_IMPORT_TIME, i_import_time );
-                SWITCH_PSZ( ML_LANGUAGE, psz_language );
-                SWITCH_INT( ML_LAST_PLAYED, i_last_played );
-                SWITCH_INT( ML_LAST_SKIPPED, i_last_skipped );
-                SWITCH_PSZ( ML_ORIGINAL_TITLE, psz_orig_title );
-                SWITCH_INT( ML_PLAYED_COUNT, i_played_count );
-                SWITCH_PSZ( ML_PREVIEW, psz_preview );
-                SWITCH_INT( ML_SCORE, i_score );
-                SWITCH_INT( ML_SKIPPED_COUNT, i_skipped_count );
-                SWITCH_PSZ( ML_TITLE, psz_title );
-                SWITCH_INT( ML_TRACK_NUMBER, i_track_number );
-                SWITCH_INT( ML_TYPE, i_type );
-                SWITCH_INT( ML_VOTE, i_vote);
-                SWITCH_INT( ML_YEAR, i_year );
-            case ML_ALBUM_COVER:
-                /* See ML_COVER */
-                // Discard attachment://
-                if( !p_media->psz_cover || !*p_media->psz_cover
-                 || !strncmp( p_media->psz_cover, "attachment://", 13 ) )
-                {
-                    free( p_media->psz_cover );
-                    p_media->psz_cover = strdupnull( res( row, col ) );
-                }
-                break;
-            case ML_PEOPLE:
-                psz_append_pname = strdupnull( res( row, col ) );
-                break;
-            case ML_PEOPLE_ID:
-                i_append_pid = atoinull( res( row, col ) );
-                break;
-            case ML_PEOPLE_ROLE:
-                psz_append_prole = strdupnull( res( row, col ) );
-                break;
-            case ML_COVER:
-                /* See ML_ALBUM_COVER */
-                if( !p_media->psz_cover || !*p_media->psz_cover
-                     || !strncmp( p_media->psz_cover, "attachment://", 13 ) )
-                {
-                    free( p_media->psz_cover );
-                    p_media->psz_cover = strdupnull( res( row, col ) );
-                }
-                break;
-            case ML_ID:
-                p_media->i_id = atoinull( res( row, col ) );
-                if( p_media->i_id <= 0 )
-                    msg_Warn( p_ml, "entry with id null or inferior to zero" );
-                break;
-            case ML_URI:
-                p_media->psz_uri = strdupnull( res( row, col ) );
-                if( !p_media->psz_uri )
-                    msg_Warn( p_ml, "entry without uri" );
-                break;
-            case ML_DIRECTORY:
-                break; // The column directory_id is'nt part of the media model
-            default:
-                msg_Warn( p_ml, "unknown element, row %d column %d (of %d) - %s - %s",
-                        row, col, i_cols, res( 0 , col ), res( row, col ) );
-                break;
-            }
-        }
-
-#undef SWITCH_INT
-#undef SWITCH_PSZ
-        int i_appendrow;
-        ml_result_t* p_append = NULL;
-        for( i_appendrow = 0; i_appendrow < vlc_array_count( p_intermediate_array ); i_appendrow++ )
-        {
-            p_append = ( ml_result_t* )
-                vlc_array_item_at_index( p_intermediate_array, i_appendrow );
-            if( p_append->id == p_media->i_id )
-                break;
-        }
-        if( i_appendrow == vlc_array_count( p_intermediate_array ) )
-        {
-            p_result->id   = p_media->i_id;
-            p_result->type = ML_TYPE_MEDIA;
-            p_result->value.p_media = p_media;
-            if( psz_append_pname && i_append_pid && psz_append_prole )
-                ml_CreateAppendPersonAdv( &(p_result->value.p_media->p_people),
-                        psz_append_prole, psz_append_pname, i_append_pid );
-            vlc_array_append( p_intermediate_array, p_result );
-            ml_UnlockMedia( p_media );
-        }
-        else /* This is a repeat row and the people need to be put together */
-        {
-            free( p_result );
-            ml_LockMedia( p_append->value.p_media );
-            if( psz_append_pname && i_append_pid && psz_append_prole )
-                ml_CreateAppendPersonAdv( &(p_append->value.p_media->p_people),
-                        psz_append_prole, psz_append_pname, i_append_pid );
-            ml_UnlockMedia( p_append->value.p_media );
-            ml_UnlockMedia( p_media );
-            ml_gc_decref( p_media );
-        }
-        FREENULL( psz_append_prole );
-        FREENULL( psz_append_pname );
-        i_append_pid = 0;
-    }
-    p_media = NULL;
-    free( indexes );
-
-    /* Now check if these medias are already on the pool, and sync */
-    for( int i = 0; i < vlc_array_count( p_intermediate_array ); i++ )
-    {
-        p_result =
-            ( ml_result_t* )vlc_array_item_at_index( p_intermediate_array, i );
-        p_media = p_result->value.p_media;
-        ml_media_t* p_poolmedia = pool_GetMedia( p_ml, p_result->id );
-        /* TODO: Pool_syncMedia might be cleaner? */
-
-        p_result = ( ml_result_t* ) calloc( 1, sizeof( ml_result_t * ) );
-        if( !p_result )
-            goto quit_sqlmediaarray;
-        if( p_poolmedia )
-        {
-            /* TODO: This might cause some weird stuff to occur w/ GC? */
-            ml_CopyMedia( p_poolmedia, p_media );
-            p_result->id = p_poolmedia->i_id;
-            p_result->type = ML_TYPE_MEDIA;
-            p_result->value.p_media = p_poolmedia;
-            vlc_array_append( p_result_array, p_result );
-        }
-        else
-        {
-            i_ret = pool_InsertMedia( p_ml, p_media, false );
-            if( i_ret == VLC_SUCCESS )
-            {
-                ml_gc_incref( p_media );
-                p_result->id = p_media->i_id;
-                p_result->type = ML_TYPE_MEDIA;
-                p_result->value.p_media = p_media;
-                vlc_array_append( p_result_array, p_result );
-            }
-        }
-    }
-
-    #undef strdupnull
-    #undef atoinull
-    #undef res
-quit_sqlmediaarray:
-    for( int k = 0; k < vlc_array_count( p_intermediate_array ); k++ )
-    {
-        ml_result_t* temp = ((ml_result_t*)vlc_array_item_at_index( p_intermediate_array, k ));
-        ml_FreeResult( temp );
-    }
-    vlc_array_destroy( p_intermediate_array );
-    return i_ret;
-}
-
-
-/**
- * @brief Returns (unique) ID of media with specified URI
- *
- * @param p_ml the media library object
- * @param psz_uri URI to look for
- * @return i_id: (first) ID found, VLC_EGENERIC in case of error
- * NOTE: Normally, there should not be more than one ID with one URI
- */
-int GetMediaIdOfURI( media_library_t *p_ml, const char *psz_uri )
-{
-    int i_ret = VLC_EGENERIC;
-    vlc_array_t *p_array = vlc_array_new();
-    i_ret = Find( p_ml, p_array, ML_ID, ML_URI, psz_uri, ML_LIMIT, 1, ML_END );
-    if( ( i_ret == VLC_SUCCESS )
-        && ( vlc_array_count( p_array ) > 0 )
-        && vlc_array_item_at_index( p_array, 0 ) )
-    {
-        i_ret = ( (ml_result_t*)vlc_array_item_at_index( p_array, 0 ) )
-                        ->value.i;
-    }
-    else
-    {
-        i_ret = VLC_EGENERIC;
-    }
-    vlc_array_destroy( p_array );
-    return i_ret;
-}
-
-
-/**
- * @brief Control function for media library
- *
- * @param p_ml Media library handle
- * @param i_query query type
- * @param args query arguments
- * @return VLC_SUCCESS if ok
- */
-int Control( media_library_t *p_ml, int i_query, va_list args )
-{
-    switch( i_query )
-    {
-    case ML_ADD_INPUT_ITEM:
-    {
-        input_item_t *p_item = (input_item_t *)va_arg( args, input_item_t * );
-        return AddInputItem( p_ml, p_item );
-    }
-
-    case ML_ADD_PLAYLIST_ITEM:
-    {
-        playlist_item_t *p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
-        return AddPlaylistItem( p_ml, p_item );
-    }
-
-    case ML_ADD_MONITORED:
-    {
-        char *psz_dir = (char *)va_arg( args, char * );
-        return AddDirToMonitor( p_ml, psz_dir );
-    }
-
-    case ML_GET_MONITORED:
-    {
-        vlc_array_t *p_array = (vlc_array_t *)va_arg( args, vlc_array_t * );
-        return ListMonitoredDirs( p_ml, p_array );
-    }
-
-    case ML_DEL_MONITORED:
-    {
-        char *psz_dir = (char *)va_arg( args, char * );
-        return RemoveDirToMonitor( p_ml, psz_dir );
-    }
-
-    default:
-        return VLC_EGENERIC;
-    }
-}
-
-
-/**
- * @brief Create a new (empty) database. The database might be initialized
- *
- * @param p_ml This ML
- * @return VLC_SUCCESS or VLC_EGENERIC
- * @note This function is transactional
- */
-int CreateEmptyDatabase( media_library_t *p_ml )
-{
-    assert( p_ml );
-    int i_ret = VLC_SUCCESS;
-    msg_Dbg( p_ml, "creating a new (empty) database" );
-
-    Begin( p_ml );
-
-    /* Albums */
-    i_ret= QuerySimple( p_ml,
-                        "CREATE TABLE album ( "
-                        "id INTEGER PRIMARY KEY,"
-                        "album_artist_id INTEGER,"
-                        "title VARCHAR(1024),"
-                        "cover VARCHAR(1024) )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    i_ret = QuerySimple( p_ml, "CREATE INDEX album_title_index ON album (title);" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Add "unknown" entry to albums */
-    i_ret = QuerySimple( p_ml,
-                        "INSERT INTO album ( id, title, cover, album_artist_id ) "
-                        "VALUES ( 0, 'Unknown', '', 0 )" );
-
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Main media table */
-    i_ret= QuerySimple( p_ml,
-                        "CREATE TABLE media ( "
-                        "id INTEGER PRIMARY KEY,"
-                        "timestamp INTEGER,"            /* File timestamp */
-                        "uri VARCHAR(1024),"
-                        "type INTEGER,"
-                        "title VARCHAR(1024),"
-                        "original_title VARCHAR(1024),"
-                        "album_id INTEGER,"
-                        "cover VARCHAR(1024),"
-                        "preview VARCHAR(1024),"        /* Video preview */
-                        "track INTEGER,"                /* Track number */
-                        "disc INTEGER,"                 /* Disc number */
-                        "year INTEGER,"
-                        "genre VARCHAR(1024),"
-                        "vote INTEGER,"                 /* Rating/Stars */
-                        "score INTEGER,"                /* ML score/rating */
-                        "comment VARCHAR(1024),"        /* Comment */
-                        "filesize INTEGER,"
-                        /* Dates and times */
-                        "duration INTEGER,"             /* Length of media */
-                        "played_count INTEGER,"
-                        "last_played DATE,"
-                        "first_played DATE,"
-                        "import_time DATE,"
-                        "skipped_count INTEGER,"
-                        "last_skipped DATE,"
-                        "directory_id INTEGER,"
-                        "CONSTRAINT associated_album FOREIGN KEY(album_id) "
-            "REFERENCES album(id) ON DELETE SET DEFAULT ON UPDATE RESTRICT)" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    i_ret = QuerySimple( p_ml, "CREATE INDEX media_ui_index ON media (uri);" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* People */
-    i_ret = QuerySimple( p_ml,
-                        "CREATE TABLE people ( "
-                        "id INTEGER PRIMARY KEY,"
-                        "name VARCHAR(1024) ,"
-                        "role VARCHAR(1024) )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Media to people */
-    i_ret = QuerySimple( p_ml,
-                        "CREATE TABLE media_to_people ( "
-                        "media_id INTEGER, "
-                        "people_id INTEGER, "
-                        "PRIMARY KEY( media_id, people_id ), "
-                        "CONSTRAINT associated_people FOREIGN KEY(people_id) "
-            "REFERENCES people(id) ON DELETE SET DEFAULT ON UPDATE RESTRICT, "
-                        "CONSTRAINT associated_media FOREIGN KEY(media_id) "
-            "REFERENCES media(id) ON DELETE CASCADE ON UPDATE RESTRICT )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Add "unknown" entry to people */
-    i_ret = QuerySimple( p_ml,
-                        "INSERT INTO people ( id, name, role ) "
-                        "VALUES ( 0, 'Unknown', NULL )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* recursive is set to 1 if the directory is added to the database
-       by recursion and 0 if not */
-    i_ret = QuerySimple( p_ml,
-                        "CREATE TABLE directories ( "
-                        "id INTEGER PRIMARY KEY,"
-                        "uri VARCHAR(1024),"
-                        "timestamp INTEGER,"
-                        "recursive INTEGER )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Create information table
-     * This table should have one row and the version number is the version
-     * of the database
-     * Other information may be stored here at later stages */
-    i_ret = QuerySimple( p_ml,
-                        "CREATE TABLE information ( "
-                        "version INTEGER PRIMARY KEY )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Insert current DB version */
-    i_ret = QuerySimple( p_ml,
-                        "INSERT INTO information ( version ) "
-                        "VALUES ( %d )", ML_DBVERSION );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Text data: song lyrics or subtitles */
-    i_ret = QuerySimple( p_ml,
-                        "CREATE TABLE extra ( "
-                        "id INTEGER PRIMARY KEY,"
-                        "extra TEXT,"
-                        "language VARCHAR(256),"
-                        "bitrate INTEGER,"
-                        "samplerate INTEGER,"
-                        "bpm INTEGER )" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-
-    /* Emulating foreign keys with triggers */
-    /* Warning: Lots of SQL */
-    if( !strcmp( module_get_name( p_ml->p_sys->p_sql->p_module, false ),
-        "SQLite" ) )
-    {
-    i_ret = QuerySimple( p_ml,
-    "\nCREATE TRIGGER genfkey1_insert_referencing BEFORE INSERT ON \"media\" WHEN\n"
-    "    new.\"album_id\" IS NOT NULL AND NOT EXISTS (SELECT 1 FROM \"album\" WHERE new.\"album_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey1_insert_referencing failed. Cannot insert album_id into media. Album did not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey1_update_referencing BEFORE\n"
-    "    UPDATE OF album_id ON \"media\" WHEN \n"
-    "    new.\"album_id\" IS NOT NULL AND \n"
-    "    NOT EXISTS (SELECT 1 FROM \"album\" WHERE new.\"album_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey1_update_referencing failed. Cannot update album_id in media. Album did not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey1_delete_referenced BEFORE DELETE ON \"album\" WHEN\n"
-    "    EXISTS (SELECT 1 FROM \"media\" WHERE old.\"id\" == \"album_id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey1_delete_referenced failed. Cannot delete album, media still exist');\n"
-    "END;\n"
-    "\n"
-    "\n"
-    "CREATE TRIGGER genfkey1_update_referenced AFTER\n"
-    "    UPDATE OF id ON \"album\" WHEN \n"
-    "    EXISTS (SELECT 1 FROM \"media\" WHERE old.\"id\" == \"album_id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey1_update_referenced failed. Cannot change album id in album, media still exist');\n"
-    "END;\n"
-    "\n"
-    "\n"
-    "CREATE TRIGGER genfkey2_insert_referencing BEFORE INSERT ON \"media_to_people\" WHEN \n"
-    "    new.\"media_id\" IS NOT NULL AND NOT EXISTS (SELECT 1 FROM \"media\" WHERE new.\"media_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey2_insert_referencing failed. Cannot insert into media_to_people, that media does not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey2_update_referencing BEFORE\n"
-    "    UPDATE OF media_id ON \"media_to_people\" WHEN \n"
-    "    new.\"media_id\" IS NOT NULL AND \n"
-    "    NOT EXISTS (SELECT 1 FROM \"media\" WHERE new.\"media_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey2_update_referencing failed. Cannot update media_to_people, that media does not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey2_delete_referenced BEFORE DELETE ON \"media\" WHEN\n"
-    "    EXISTS (SELECT 1 FROM \"media_to_people\" WHERE old.\"id\" == \"media_id\")\n"
-    "BEGIN\n"
-    "  DELETE FROM \"media_to_people\" WHERE \"media_id\" = old.\"id\";\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey2_update_referenced AFTER\n"
-    "    UPDATE OF id ON \"media\" WHEN \n"
-    "    EXISTS (SELECT 1 FROM \"media_to_people\" WHERE old.\"id\" == \"media_id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey2_update_referenced failed. Cannot update media id, refs still exist in media_to_people');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey3_insert_referencing BEFORE INSERT ON \"media_to_people\" WHEN \n"
-    "    new.\"people_id\" IS NOT NULL AND NOT EXISTS (SELECT 1 FROM \"people\" WHERE new.\"people_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey3_insert_referencing failed. Cannot insert into media_to_people, people does not exist');\n"
-    "END;\n"
-    "CREATE TRIGGER genfkey3_update_referencing BEFORE\n"
-    "    UPDATE OF people_id ON \"media_to_people\" WHEN \n"
-    "    new.\"people_id\" IS NOT NULL AND \n"
-    "    NOT EXISTS (SELECT 1 FROM \"people\" WHERE new.\"people_id\" == \"id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey3_update_referencing failed. Cannot update media_to_people, people does not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey3_delete_referenced BEFORE DELETE ON \"people\" WHEN\n"
-    "    EXISTS (SELECT 1 FROM \"media_to_people\" WHERE old.\"id\" == \"people_id\")\n"
-    "BEGIN\n"
-    "  UPDATE media_to_people SET people_id = 0 WHERE people_id == old.\"id\";\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER genfkey3_update_referenced AFTER\n"
-    "    UPDATE OF id ON \"people\" WHEN \n"
-    "    EXISTS (SELECT 1 FROM \"media_to_people\" WHERE old.\"id\" == \"people_id\")\n"
-    "BEGIN\n"
-    "  SELECT RAISE(ABORT, 'constraint genfkey3_update_referenced failed. Cannot update people_id, people does not exist');\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER keep_people_clean AFTER \n"
-    "    DELETE ON \"media_to_people\"\n"
-    "    WHEN NOT EXISTS( SELECT 1 from \"media_to_people\" WHERE old.\"people_id\" == \"people_id\" )\n"
-    "BEGIN\n"
-    "    DELETE FROM people WHERE people.id = old.\"people_id\" AND people.id != 0;\n"
-    "END;\n"
-    "\n"
-    "CREATE TRIGGER keep_album_clean AFTER\n"
-    "    DELETE ON \"media\"\n"
-    "    WHEN NOT EXISTS( SELECT 1 FROM \"media\" WHERE old.\"album_id\" == \"album_id\" )\n"
-    "BEGIN\n"
-    "    DELETE FROM album WHERE album.id = old.\"album_id\" AND album.id != 0;\n"
-    "END;" );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_createemptydatabase;
-    }
-
-quit_createemptydatabase:
-    if( i_ret == VLC_SUCCESS )
-        Commit( p_ml );
-    else
-        Rollback( p_ml );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Journal and synchronous disc and writes
- *
- * @param p_ml media library object
- * @param b_sync boolean
- * @return <= 0 on error.
- */
-static int SetSynchronous( media_library_t *p_ml, bool b_sync )
-{
-    int i_rows, i_cols;
-    char **pp_results;
-    int i_return;
-    if ( b_sync )
-        i_return = Query( p_ml, &pp_results, &i_rows, &i_cols,
-            "PRAGMA synchronous = ON;PRAGMA journal_mode = TRUNCATE" );
-    else
-        i_return = Query( p_ml, &pp_results, &i_rows, &i_cols,
-            "PRAGMA synchronous = OFF;PRAGMA journal_mode = MEMORY" );
-    if( i_return != VLC_SUCCESS )
-        i_return = -1;
-    else
-        i_return = atoi( pp_results[ 1 ] );
-
-    FreeSQLResult( p_ml, pp_results );
-
-    return i_return;
-}
-
-/**
- * @brief Initiates database (create the database and the tables if needed)
- *
- * @param p_ml This ML
- * @return VLC_SUCCESS or an error code
- */
-int InitDatabase( media_library_t *p_ml )
-{
-    assert( p_ml );
-    msg_Dbg( p_ml, "initializing database" );
-
-    /* Select database name */
-    char *psz_dbhost = NULL, *psz_user = NULL, *psz_pass = NULL;
-    int i_port = 0;
-    bool b_sync = false;
-    psz_dbhost = config_GetPsz( p_ml, "ml-filename" );
-    psz_user = config_GetPsz( p_ml, "ml-username" );
-    psz_pass = config_GetPsz( p_ml, "ml-password" );
-    i_port = config_GetInt( p_ml, "ml-port" );
-    b_sync = config_GetInt( p_ml, "ml-synchronous" );
-
-    /* Let's consider that a filename with a DIR_SEP is a full URL */
-    if( strchr( psz_dbhost, DIR_SEP_CHAR ) == NULL )
-    {
-        char *psz_datadir = config_GetUserDir( VLC_DATA_DIR );
-        char *psz_tmp = psz_dbhost;
-        if( asprintf( &psz_dbhost, "%s" DIR_SEP "%s",
-                      psz_datadir, psz_tmp ) == -1 )
-        {
-            free( psz_datadir );
-            free( psz_tmp );
-            return VLC_ENOMEM;
-        }
-        free( psz_datadir );
-        free( psz_tmp );
-    }
-
-    p_ml->p_sys->p_sql = sql_Create( p_ml, NULL, psz_dbhost, i_port, psz_user,
-                                     psz_pass );
-    if( !p_ml->p_sys->p_sql )
-        return VLC_EGENERIC;
-
-    /* Let's check if tables exist */
-    int i_version = GetDatabaseVersion( p_ml );
-    if( i_version <= 0 )
-        CreateEmptyDatabase( p_ml );
-    else if( i_version != ML_DBVERSION )
-        return VLC_EGENERIC;
-
-    /**
-     * The below code ensures that correct code is written
-     * when database versions are changed
-     */
-
-#if ML_DBVERSION != 1
-#error "ML versioning code needs to be updated. Is this done correctly?"
-#endif
-
-    SetSynchronous( p_ml, b_sync );
-
-    msg_Dbg( p_ml, "ML initialized" );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Gets the current version number from the database
- *
- * @param p_ml media library object
- * @return version number of the current db. <= 0 on error.
- */
-int GetDatabaseVersion( media_library_t *p_ml )
-{
-    int i_rows, i_cols;
-    char **pp_results;
-    int i_return;
-    i_return = Query( p_ml, &pp_results, &i_rows, &i_cols,
-        "SELECT version FROM information ORDER BY version DESC LIMIT 1" );
-    if( i_return != VLC_SUCCESS )
-        i_return = -1;
-    else
-        i_return = atoi( pp_results[ 1 ] );
-
-    FreeSQLResult( p_ml, pp_results );
-
-    return i_return;
-}
-
- /**
- * @brief Object constructor for ml_media_t
- * @param p_ml The media library object
- * @param id If 0, this item isn't in database. If non zero, it is and
- * it will be a singleton
- * @param select Type of object
- * @param reload Whether to reload from database
- */
-ml_media_t* GetMedia( media_library_t* p_ml, int id,
-                        ml_select_e select, bool reload )
-{
-    assert( id > 0 );
-    assert( select == ML_MEDIA || select == ML_MEDIA_SPARSE );
-    int i_ret = VLC_SUCCESS;
-    ml_media_t* p_media = NULL;
-    if( !reload )
-    {
-        p_media = pool_GetMedia( p_ml, id );
-        if( !p_media )
-            reload = true;
-        else
-        {
-            ml_LockMedia( p_media );
-            if( p_media->b_sparse && select == ML_MEDIA )
-                reload = true;
-            /* Utilise ML_MEDIA_EXTRA load? TODO */
-            ml_UnlockMedia( p_media );
-            ml_gc_incref( p_media );
-        }
-    }
-    else
-    {
-        vlc_array_t *p_array = vlc_array_new();
-        i_ret = ml_Find( p_ml, p_array, select, ML_ID, id );
-        assert( vlc_array_count( p_array ) == 1 );
-        if( ( i_ret == VLC_SUCCESS )
-            && ( vlc_array_count( p_array ) > 0 )
-            && vlc_array_item_at_index( p_array, 0 ) )
-        {
-            p_media = ((ml_result_t*)vlc_array_item_at_index( p_array, 0 ))->value.p_media;
-            ml_gc_incref( p_media );
-            ml_FreeResult( vlc_array_item_at_index( p_array, 0 ) );
-        }
-        vlc_array_destroy( p_array );
-        if( select == ML_MEDIA )
-            p_media->b_sparse = false;
-        else
-            p_media->b_sparse = true;
-    }
-    return p_media;
-}
-/**
- * @brief Create an input item from media (given its ID)
- *
- * @param p_ml This media_library_t object
- * @param i_media Media ID
- * @return input_item_t* created
- *
- * @note This is a public function (pf_InputItemFromMedia)
- * The input_item will have a refcount at 2 (1 for the ML, 1 for you)
- */
-input_item_t* GetInputItemFromMedia( media_library_t *p_ml, int i_media )
-{
-    input_item_t *p_item = NULL;
-
-    p_item = watch_get_itemOfMediaId( p_ml, i_media );
-    if( !p_item )
-    {
-        ml_media_t* p_media = media_New( p_ml, i_media, ML_MEDIA, true );
-        if( p_media == NULL )
-            return NULL;
-        CreateInputItemFromMedia( &p_item, p_media );
-        watch_add_Item( p_ml, p_item, p_media );
-        ml_gc_decref( p_media );
-    }
-
-    return p_item;
-}
-
-/**
- * @brief Copy an input_item_t to a ml_media_t
- * @param p_media Destination
- * @param p_item Source
- * @note Media ID will not be set! This function is threadsafe. Leaves
- * unsyncable items alone
- */
-void CopyInputItemToMedia( ml_media_t *p_media, input_item_t *p_item )
-{
-    ml_LockMedia( p_media );
-#if 0
-    // unused meta :
-    input_item_GetCopyright( item )
-    input_item_GetRating( item ) /* TODO */
-    input_item_GetGetting( item )
-    input_item_GetNowPlaying( item )
-    input_item_GetTrackID( item )
-    input_item_GetSetting( item )
-#endif
-    p_media->psz_title      = input_item_GetTitle       ( p_item );
-    p_media->psz_uri        = input_item_GetURL         ( p_item );
-    if( !p_media->psz_uri )
-        p_media->psz_uri = input_item_GetURI( p_item );
-    p_media->psz_album      = input_item_GetAlbum       ( p_item );
-    p_media->psz_cover      = input_item_GetArtURL      ( p_item );
-    p_media->psz_genre      = input_item_GetGenre       ( p_item );
-    p_media->psz_language   = input_item_GetLanguage    ( p_item );
-    p_media->psz_comment    = input_item_GetDescription ( p_item );
-    char *psz_track         = input_item_GetTrackNum    ( p_item );
-    p_media->i_track_number = psz_track ? atoi( psz_track ) : 0;
-    free( psz_track );
-    char *psz_date          = input_item_GetDate( p_item );
-    p_media->i_year         = psz_date ? atoi( psz_date ) : 0;
-    free( psz_date );
-    p_media->i_duration     = p_item->i_duration;
-
-    /* People */
-    char *psz_tmp = input_item_GetArtist( p_item );
-    if( psz_tmp )
-        ml_CreateAppendPersonAdv( &p_media->p_people, ML_PERSON_ARTIST,
-                                     psz_tmp, 0 );
-    free( psz_tmp );
-    psz_tmp = input_item_GetPublisher( p_item );
-    if( psz_tmp )
-        ml_CreateAppendPersonAdv( &p_media->p_people, ML_PERSON_PUBLISHER,
-                                    psz_tmp, 0 );
-    free( psz_tmp );
-    psz_tmp = input_item_GetEncodedBy( p_item );
-    if( psz_tmp )
-        ml_CreateAppendPersonAdv( &p_media->p_people, ML_PERSON_ENCODER,
-                                    psz_tmp, 0 );
-    free( psz_tmp );
-
-    /* Determine input type: audio, video, stream */
-    /* First read input type */
-    switch( p_item->i_type )
-    {
-    case ITEM_TYPE_FILE:
-        p_media->i_type |= 0;
-        break;
-    case ITEM_TYPE_DISC:
-    case ITEM_TYPE_CARD:
-        p_media->i_type |= ML_REMOVABLE;
-        break;
-    case ITEM_TYPE_CDDA:
-    case ITEM_TYPE_NET:
-        p_media->i_type |= ML_STREAM;
-        break;
-    case ITEM_TYPE_PLAYLIST:
-    case ITEM_TYPE_NODE:
-    case ITEM_TYPE_DIRECTORY:
-        p_media->i_type |= ML_NODE;
-        break;
-    case ITEM_TYPE_NUMBER:
-    case ITEM_TYPE_UNKNOWN:
-    default:
-        p_media->i_type |= ML_UNKNOWN;
-        break;
-    }
-
-    /* Then try to guess if this is a video or not */
-    /* Check file extension, and guess if this is a video or an audio media
-       Note: this test is not very good, but it's OK for normal files */
-    char *psz_ext = strrchr( p_item->psz_uri, '.' );
-    if( psz_ext && strlen( psz_ext ) < 5 )
-    {
-        bool b_ok = false;
-        psz_ext++;
-        for( unsigned i = 0; ppsz_AudioExtensions[i]; i++ )
-        {
-            if( strcasecmp( psz_ext, ppsz_AudioExtensions[i] ) == 0 )
-            {
-                p_media->i_type |= ML_AUDIO;
-                b_ok = true;
-                break;
-            }
-        }
-        if( !b_ok )
-        {
-            for( unsigned i = 0; ppsz_VideoExtensions[i]; i++ )
-            {
-                if( strcasecmp( psz_ext, ppsz_VideoExtensions[i] ) == 0 )
-                {
-                    p_media->i_type |= ML_VIDEO;
-                    break;
-                }
-            }
-        }
-    }
-    ml_UnlockMedia( p_media );
-}
-
-/**
- * @brief Copy a ml_media_t to an input_item_t
- * @param p_item Destination
- * @param p_media Source
- */
-void CopyMediaToInputItem( input_item_t *p_item, ml_media_t *p_media )
-{
-    ml_LockMedia( p_media );
-    if( p_media->psz_title && *p_media->psz_title )
-        input_item_SetTitle( p_item, p_media->psz_title );
-    if( p_media->psz_uri && *p_media->psz_uri && !strncmp( p_media->psz_uri, "http", 4 ) )
-        input_item_SetURL( p_item, p_media->psz_uri );
-    if( p_media->psz_album && *p_media->psz_album )
-        input_item_SetAlbum( p_item, p_media->psz_album );
-    if( p_media->psz_cover && *p_media->psz_cover )
-        input_item_SetArtURL( p_item, p_media->psz_cover );
-    if( p_media->psz_genre && *p_media->psz_genre )
-        input_item_SetGenre( p_item, p_media->psz_genre );
-    if( p_media->psz_language && *p_media->psz_language )
-        input_item_SetLanguage( p_item, p_media->psz_language );
-    if( p_media->psz_comment && *p_media->psz_comment )
-        input_item_SetDescription( p_item, p_media->psz_comment );
-    if( p_media->i_track_number )
-    {
-        char *psz_track;
-        if( asprintf( &psz_track, "%d", p_media->i_track_number ) != -1 )
-            input_item_SetTrackNum( p_item, psz_track );
-        free( psz_track );
-    }
-    if( p_media->i_year )
-    {
-        char *psz_date;
-        if( asprintf( &psz_date, "%d", p_media->i_year ) != -1 )
-            input_item_SetDate( p_item, psz_date );
-        free( psz_date );
-    }
-    p_item->i_duration = p_media->i_duration;
-    ml_person_t *person = p_media->p_people;
-    while( person )
-    {
-        if( !strcmp( person->psz_role, ML_PERSON_ARTIST ) )
-            input_item_SetArtist( p_item, person->psz_name );
-        else if( !strcmp( person->psz_role, ML_PERSON_PUBLISHER ) )
-            input_item_SetPublisher( p_item, person->psz_name );
-        else if( !strcmp( person->psz_role, ML_PERSON_ENCODER ) )
-            input_item_SetEncodedBy( p_item, person->psz_name );
-        person = person->p_next;
-    }
-    ml_UnlockMedia( p_media );
-}
-
-/**
- * @brief Copy a ml_media_t to an input_item_t
- * @param pp_item A pointer to a new input_item (return value)
- * @param p_media The media to copy as an input item
- * @note This function is threadsafe
- */
-static int CreateInputItemFromMedia( input_item_t **pp_item,
-                                     ml_media_t *p_media )
-{
-    *pp_item = input_item_New( p_media->psz_uri, p_media->psz_title );
-                               /* ITEM_TYPE_FILE ); */
-    if( !*pp_item )
-        return VLC_EGENERIC;
-    CopyMediaToInputItem( *pp_item, p_media );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Find the media_id associated to an input item
- * @param p_ml This
- * @param p_item Input item to look for
- * @return Media ID or <= 0 if not found
- */
-int GetMediaIdOfInputItem( media_library_t *p_ml, input_item_t *p_item )
-{
-    int i_media_id = watch_get_mediaIdOfItem( p_ml, p_item );
-    if( i_media_id <= 0 )
-    {
-        i_media_id = GetMediaIdOfURI( p_ml, p_item->psz_uri );
-    }
-    return i_media_id;
-}
-
-
diff --git a/modules/media_library/sql_media_library.h b/modules/media_library/sql_media_library.h
deleted file mode 100644 (file)
index 705c0a0..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/*****************************************************************************
- * sql_media_library.h : Media Library Interface
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef SQL_MEDIA_LIBRARY_H
-#define SQL_MEDIA_LIBRARY_H
-
-#include <stdarg.h>
-#include <assert.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include <vlc_common.h>
-#include <vlc_sql.h>
-#include <vlc_media_library.h>
-#include <vlc_playlist.h>
-#include <vlc_input.h>
-#include <vlc_arrays.h>
-#include <vlc_charset.h>
-#include <vlc_plugin.h>
-#include <vlc_interface.h>
-#include <vlc_modules.h>
-
-#include "item_list.h"
-
-/*****************************************************************************
- * Static parameters
- *****************************************************************************/
-#define THREAD_SLEEP_DELAY   2  /* Time between two calls to item_list_loop */
-#define MONITORING_DELAY    30  /* Media library updates interval */
-#define ITEM_LOOP_UPDATE     1  /* An item is updated after 1 loop */
-#define ITEM_LOOP_MAX_AGE   10  /* An item is deleted after 10 loops */
-#define ML_DBVERSION         1  /* The current version of the database */
-#define ML_MEDIAPOOL_HASH_LENGTH 100 /* The length of the media pool hash */
-
-/*****************************************************************************
- * Structures and types definitions
- *****************************************************************************/
-typedef struct monitoring_thread_t monitoring_thread_t;
-typedef struct ml_poolobject_t     ml_poolobject_t;
-
-struct ml_poolobject_t
-{
-    ml_media_t* p_media;
-    ml_poolobject_t* p_next;
-};
-
-struct media_library_sys_t
-{
-    /* Lock on the ML object */
-    vlc_mutex_t lock;
-
-    /* SQL object */
-    sql_t *p_sql;
-
-    /* Monitoring thread */
-    monitoring_thread_t *p_mon;
-
-    /* Watch thread */
-    watch_thread_t *p_watch;
-
-    /* Holds all medias */
-    DECL_ARRAY( ml_media_t* ) mediapool;
-    ml_poolobject_t* p_mediapool[ ML_MEDIAPOOL_HASH_LENGTH ];
-    vlc_mutex_t pool_mutex;
-
-    /* Info on update/collection rebuilding */
-    bool b_updating;
-    bool b_rebuilding;
-};
-
-/* Directory Monitoring thread */
-struct monitoring_thread_t
-{
-    VLC_COMMON_MEMBERS;
-
-    vlc_cond_t wait;
-    vlc_mutex_t lock;
-    vlc_thread_t thread;
-    media_library_t *p_ml;
-};
-
-/* Media status Watching thread */
-struct watch_thread_t
-{
-    media_library_t *p_ml;
-    vlc_thread_t thread;
-    vlc_cond_t cond;
-    vlc_mutex_t lock;
-
-    /* Input items watched */
-    struct item_list_t* p_hlist[ ML_ITEMLIST_HASH_LENGTH ];
-    vlc_mutex_t list_mutex;
-
-    /* List of items to check */
-    input_item_t** item_append_queue;
-    vlc_mutex_t item_append_queue_lock;
-    int item_append_queue_count;
-};
-
-
-
-/*****************************************************************************
- * Function headers
- *****************************************************************************/
-/* General functions */
-int CreateEmptyDatabase( media_library_t *p_ml );
-int InitDatabase( media_library_t *p_ml );
-
-/* Module Control */
-int Control( media_library_t *p_ml,
-             int i_query,
-             va_list args );
-
-/* Add functions */
-int AddMedia( media_library_t *p_ml,
-              ml_media_t *p_media );
-int AddAlbum( media_library_t *p_ml, const char *psz_title,
-              const char *psz_cover, const int i_album_artist );
-int AddPeople( media_library_t *p_ml,
-               const char *psz_name,
-               const char *psz_role );
-int AddPlaylistItem( media_library_t *p_ml,
-                     playlist_item_t *p_playlist_item );
-int AddInputItem( media_library_t *p_ml,
-                  input_item_t *p_input );
-
-/* Create and Copy functions */
-ml_media_t* GetMedia( media_library_t* p_ml, int id,
-                        ml_select_e select, bool reload );
-input_item_t* GetInputItemFromMedia( media_library_t *p_ml,
-                                     int i_media );
-void CopyInputItemToMedia( ml_media_t *p_media,
-                           input_item_t *p_item );
-void CopyMediaToInputItem( input_item_t *p_item,
-                           ml_media_t *p_media );
-
-/* Get functions */
-int GetDatabaseVersion( media_library_t *p_ml );
-int GetMediaIdOfInputItem( media_library_t *p_ml,
-                           input_item_t *p_item );
-int GetMediaIdOfURI( media_library_t *p_ml,
-                     const char *psz_uri );
-
-/* Search in the database */
-int BuildSelectVa( media_library_t *p_ml,
-                   char **ppsz_query,
-                   ml_result_type_e *p_result_type,
-                   va_list criterias );
-int BuildSelect( media_library_t *p_ml,
-                 char **ppsz_query,
-                 ml_result_type_e *p_result_type,
-                 const char *psz_selected_type_lvalue,
-                 ml_select_e selected_type,
-                 ml_ftree_t *tree );
-int Find( media_library_t *p_ml,
-          vlc_array_t *results,
-          ... );
-int FindVa( media_library_t *p_ml,
-            vlc_array_t *results,
-            va_list criterias );
-int FindAdv( media_library_t *p_ml,
-             vlc_array_t *results,
-             ml_select_e selected_type,
-             const char* psz_lvalue,
-             ml_ftree_t *tree );
-
-/* Update the database */
-int Update( media_library_t *p_ml,
-            ml_select_e selected_type,
-            const char* psz_lvalue,
-            ml_ftree_t *where,
-            vlc_array_t *changes );
-int BuildUpdate( media_library_t *p_ml,
-                 char **ppsz_query,
-                 char **ppsz_id_query,
-                 const char *psz_lvalue,
-                 ml_select_e selected_type,
-                 ml_ftree_t* where,
-                 vlc_array_t *changes );
-int UpdateMedia( media_library_t *p_ml,
-                 ml_media_t *p_media );
-int SetArtCover( media_library_t *p_ml,
-                 int i_album_id,
-                 const char *psz_cover );
-
-/* Delete medias in the database */
-int Delete( media_library_t *p_ml, vlc_array_t *p_array );
-
-/* Do some query on the database */
-int QuerySimple( media_library_t *p_ml,
-                 const char *psz_fmt, ... );
-int Query( media_library_t *p_ml,
-           char ***ppp_res,
-           int *pi_rows,
-           int *pi_cols,
-           const char *psz_fmt,
-           ... );
-int QueryVa( media_library_t *p_ml,
-             char ***ppp_res,
-             int *pi_rows,
-             int *pi_cols,
-             const char *psz_fmt,
-             va_list args );
-int QuerySimpleVa( media_library_t *p_ml,
-                   const char *psz_fmt,
-                   va_list argp );
-
-/* Convert SQL results to ML results */
-int StringToResult( ml_result_t *res,
-                    const char *psz,
-                    const char *psz_id,
-                    ml_result_type_e result_type );
-int SQLToMediaArray( media_library_t *p_ml,
-                     vlc_array_t *p_result_array,
-                     char **pp_results,
-                     int i_rows,
-                     int i_cols );
-int SQLToResultArray( media_library_t *p_ml,
-                      vlc_array_t *p_result_array,
-                      char **pp_results,
-                      int i_rows,
-                      int i_cols,
-                      ml_result_type_e result_type );
-
-/* Database locking functions */
-
-/**
- * @brief Begin a transaction
- * @param p_ml The Media Library object
- * @return VLC_SUCCESS and VLC_EGENERIC
- * @note This creates a SHARED lock in SQLITE. All queries made between
- * a Begin and Commit/Rollback will be transactional.
- */
-static inline int Begin( media_library_t* p_ml )
-{
-    return sql_BeginTransaction( p_ml->p_sys->p_sql );
-}
-
-/**
- * @brief Commits the transaction
- * @param p_ml The Media Library object
- */
-static inline void Commit( media_library_t* p_ml )
-{
-    sql_CommitTransaction( p_ml->p_sys->p_sql );
-}
-
-/**
- * @brief Rollback the transaction
- * @param p_ml The Media Library Object
- */
-static inline void Rollback( media_library_t* p_ml )
-{
-    sql_RollbackTransaction( p_ml->p_sys->p_sql );
-}
-
-/****************************************************************************
- * Scanning/monitoring functions
- *****************************************************************************/
-void *RunMonitoringThread( void *p_mon );
-int AddDirToMonitor( media_library_t *p_ml,
-                     const char *psz_dir );
-int ListMonitoredDirs( media_library_t *p_ml,
-                       vlc_array_t *p_array );
-int RemoveDirToMonitor( media_library_t *p_ml,
-                        const char *psz_dir );
-
-
-/*****************************************************************************
- * Media pool functions
- *****************************************************************************/
-ml_media_t* pool_GetMedia( media_library_t* p_ml, int media_id );
-int pool_InsertMedia( media_library_t* p_ml, ml_media_t* media, bool locked );
-void pool_GC( media_library_t* p_ml );
-
-/*****************************************************************************
- * Items watching system
- *****************************************************************************/
-/* Watching thread */
-#define watch_add_Item( a, b, c ) __watch_add_Item( a, b, c, false )
-
-int watch_Init( media_library_t *p_ml );
-void watch_Close( media_library_t *p_ml );
-int __watch_add_Item( media_library_t *p_ml, input_item_t *p_item,
-                            ml_media_t* p_media, bool locked );
-
-#define watch_del_Item( a, b ) __watch_del_Item( a, b, false )
-int __watch_del_Item( media_library_t *p_ml, input_item_t *p_item, bool locked );
-int watch_del_MediaById( media_library_t* p_ml, int i_media_id );
-input_item_t* watch_get_itemOfMediaId( media_library_t *p_ml, int i_media_id );
-ml_media_t* watch_get_mediaOfMediaId( media_library_t* p_ml, int i_media_id );
-int watch_get_mediaIdOfItem( media_library_t *p_ml, input_item_t *p_item );
-void watch_Force_Update( media_library_t* p_ml );
-
-/*****************************************************************************
- * Free result of ml_Query
- *****************************************************************************/
-static inline void FreeSQLResult( media_library_t *p_ml, char **ppsz_result )
-{
-    if( ppsz_result )
-    {
-        sql_Free( p_ml->p_sys->p_sql, ppsz_result );
-    }
-}
-
-#endif /* SQL_MEDIA_LIBRARY_H */
diff --git a/modules/media_library/sql_monitor.c b/modules/media_library/sql_monitor.c
deleted file mode 100644 (file)
index 47d56b4..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-/*****************************************************************************
- * sql_monitor.c: SQL-based media library: directory scanning and monitoring
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/** **************************************************************************
- * MONITORING AND DIRECTORY SCANNING FUNCTIONS
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-#   include "config.h"
-#endif
-
-#include "sql_media_library.h"
-#include "vlc_playlist.h"
-#include "vlc_url.h"
-#include "vlc_fs.h"
-
-static const char* ppsz_MediaExtensions[] =
-                        { EXTENSIONS_AUDIO_CSV, EXTENSIONS_VIDEO_CSV, NULL };
-
-
-/* Monitoring and directory scanning private functions */
-typedef struct stat_list_t stat_list_t;
-typedef struct preparsed_item_t preparsed_item_t;
-static void UpdateLibrary( monitoring_thread_t *p_mon );
-static void ScanFiles( monitoring_thread_t *, int, bool, stat_list_t *stparent );
-static int Sort( const char **, const char ** );
-
-/* Struct used to verify there are no recursive directory */
-struct stat_list_t
-{
-    stat_list_t *parent;
-    struct stat st;
-};
-
-struct preparsed_item_t
-{
-    monitoring_thread_t *p_mon;
-    char* psz_uri;
-    int i_dir_id;
-    int i_mtime;
-    int i_update_id;
-    bool b_update;
-};
-
-/**
- * @brief Remove a directory to monitor
- * @param p_ml A media library object
- * @param psz_dir the directory to remove
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int RemoveDirToMonitor( media_library_t *p_ml, const char *psz_dir )
-{
-    assert( p_ml );
-
-    char **pp_results = NULL;
-    int i_cols = 0, i_rows = 0, i_ret = VLC_SUCCESS;
-    int i;
-
-    bool b_recursive = var_CreateGetBool( p_ml, "ml-recursive-scan" );
-
-    if( b_recursive )
-    {
-        i_ret = Query( p_ml, &pp_results, &i_rows, &i_cols,
-                          "SELECT media.id FROM media JOIN directories ON "
-                          "(media.directory_id = directories.id) WHERE "
-                          "directories.uri LIKE '%q%%'",
-                          psz_dir );
-        if( i_ret != VLC_SUCCESS )
-        {
-            msg_Err( p_ml, "Error occurred while making a query to the database" );
-            return i_ret;
-        }
-        QuerySimple( p_ml, "DELETE FROM directories WHERE uri LIKE '%q%%'",
-                        psz_dir );
-    }
-    else
-    {
-        i_ret = Query( p_ml, &pp_results, &i_rows, &i_cols,
-                          "SELECT media.id FROM media JOIN directories ON "
-                          "(media.directory_id = directories.id) WHERE "
-                          "directories.uri = %Q",
-                          psz_dir );
-        if( i_ret != VLC_SUCCESS )
-        {
-            msg_Err( p_ml, "Error occurred while making a query to the database" );
-            return i_ret;
-        }
-        QuerySimple( p_ml, "DELETE FROM directories WHERE uri = %Q",
-                        psz_dir );
-    }
-
-    vlc_array_t *p_where = vlc_array_new();
-    for( i = 1; i <= i_rows; i++ )
-    {
-        int id = atoi( pp_results[i*i_cols] );
-        ml_element_t* p_find = ( ml_element_t * ) calloc( 1, sizeof( ml_element_t ) );
-        p_find->criteria = ML_ID;
-        p_find->value.i = id;
-        vlc_array_append( p_where, p_find );
-    }
-    Delete( p_ml, p_where );
-
-    FreeSQLResult( p_ml, pp_results );
-    for( i = 0; i < vlc_array_count( p_where ); i++ )
-    {
-        free( vlc_array_item_at_index( p_where, i ) );
-    }
-    vlc_array_destroy( p_where );
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Get the list of the monitored directories
- * @param p_ml A media library object
- * @param p_array An initialized array where the list will be put in
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int ListMonitoredDirs( media_library_t *p_ml, vlc_array_t *p_array )
-{
-    char **pp_results;
-    int i_cols, i_rows;
-    int i;
-
-    if( Query( p_ml, &pp_results, &i_rows, &i_cols,
-            "SELECT uri AS directory_uri FROM directories WHERE recursive=0" )
-        != VLC_SUCCESS )
-        return VLC_EGENERIC;
-
-    for( i = 1; i <= i_rows; i++ )
-    {
-        vlc_array_append( p_array, strdup( pp_results[i] ) );
-    }
-    FreeSQLResult( p_ml, pp_results );
-
-    return VLC_SUCCESS;
-}
-
-/**
- * @brief Add a directory to monitor
- * @param p_ml This media_library_t object
- * @param psz_dir the directory to add
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int AddDirToMonitor( media_library_t *p_ml, const char *psz_dir )
-{
-    assert( p_ml );
-
-    /* Verify if we can open the directory */
-    DIR *dir = vlc_opendir( psz_dir );
-    if( !dir )
-    {
-        int err = errno;
-        if( err != ENOTDIR )
-            msg_Err( p_ml, "%s: %m", psz_dir );
-        else
-            msg_Dbg( p_ml, "`%s' is not a directory", psz_dir );
-        errno = err;
-        return VLC_EGENERIC;
-    }
-
-    closedir( dir );
-
-    msg_Dbg( p_ml, "Adding directory `%s' to be monitored", psz_dir );
-    QuerySimple( p_ml, "INSERT INTO directories ( uri, timestamp, "
-                          "recursive ) VALUES( %Q, 0, 0 )", psz_dir );
-    vlc_cond_signal( &p_ml->p_sys->p_mon->wait );
-    return VLC_SUCCESS;
-}
-
-
-static int Sort( const char **a, const char **b )
-{
-#ifdef HAVE_STRCOLL
-    return strcoll( *a, *b );
-#else
-    return strcmp( *a, *b );
-#endif
-}
-
-/**
- * @brief Directory Monitoring thread loop
- */
-void *RunMonitoringThread( void *p_this )
-{
-    monitoring_thread_t *p_mon = (monitoring_thread_t*) p_this;
-    vlc_cond_init( &p_mon->wait );
-    vlc_mutex_init( &p_mon->lock );
-
-    var_Create( p_mon, "ml-recursive-scan", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
-    while( vlc_object_alive( p_mon ) )
-    {
-        vlc_mutex_lock( &p_mon->lock );
-
-        /* Update */
-        UpdateLibrary( p_mon );
-
-        /* We wait MONITORING_DELAY seconds or wait that the media library
-           signals us to do something */
-        vlc_cond_timedwait( &p_mon->wait, &p_mon->lock,
-                            mdate() + 1000000*MONITORING_DELAY );
-
-        vlc_mutex_unlock( &p_mon->lock );
-    }
-    vlc_cond_destroy( &p_mon->wait );
-    vlc_mutex_destroy( &p_mon->lock );
-    return NULL;
-}
-
-/**
- * @brief Update library if new files found or updated
- */
-static void UpdateLibrary( monitoring_thread_t *p_mon )
-{
-    int i_rows, i_cols, i;
-    char **pp_results;
-    media_library_t *p_ml = p_mon->p_ml;
-
-    struct stat s_stat;
-
-    bool b_recursive = var_GetBool( p_mon, "ml-recursive-scan" );
-
-    msg_Dbg( p_mon, "Scanning directories" );
-
-    Query( p_ml, &pp_results, &i_rows, &i_cols,
-              "SELECT id AS directory_id, uri AS directory_uri, "
-              "timestamp AS directory_ts FROM directories" );
-    msg_Dbg( p_mon, "%d directories to scan", i_rows );
-
-    for( i = 1; i <= i_rows; i++ )
-    {
-        int id = atoi( pp_results[i*i_cols] );
-        char *psz_dir = pp_results[i*i_cols+1];
-        int timestamp = atoi( pp_results[i*i_cols+2] );
-
-        if( vlc_stat( psz_dir, &s_stat ) == -1 )
-        {
-            int err = errno;
-            if( err == ENOTDIR || err == ENOENT )
-            {
-                msg_Dbg( p_mon, "Removing `%s'", psz_dir );
-                RemoveDirToMonitor( p_ml, psz_dir );
-            }
-            else
-            {
-                msg_Err( p_mon, "%s: %m", psz_dir );
-                FreeSQLResult( p_ml, pp_results );
-                return;
-            }
-            errno = err;
-        }
-
-        if( !S_ISDIR( s_stat.st_mode ) )
-        {
-            msg_Dbg( p_mon, "Removing `%s'", psz_dir );
-            RemoveDirToMonitor( p_ml, psz_dir );
-        }
-
-        if( timestamp < s_stat.st_mtime )
-        {
-            msg_Dbg( p_mon, "Adding `%s'", psz_dir );
-            ScanFiles( p_mon, id, b_recursive, NULL );
-        }
-    }
-    FreeSQLResult( p_ml, pp_results );
-}
-
-/**
- * @brief Callback for input item preparser to directory monitor
- */
-static void PreparseComplete( const vlc_event_t * p_event, void *p_data )
-{
-    int i_ret = VLC_SUCCESS;
-    preparsed_item_t* p_itemobject = (preparsed_item_t*) p_data;
-    monitoring_thread_t *p_mon = p_itemobject->p_mon;
-    media_library_t *p_ml = (media_library_t *)p_mon->p_ml;
-    input_item_t *p_input = (input_item_t*) p_event->p_obj;
-
-    if( input_item_IsPreparsed( p_input ) )
-    {
-        if( p_itemobject->b_update )
-        {
-            //TODO: Perhaps we don't have to load everything?
-            ml_media_t* p_media = GetMedia( p_ml, p_itemobject->i_update_id,
-                    ML_MEDIA_SPARSE, true );
-            CopyInputItemToMedia( p_media, p_input );
-            i_ret = UpdateMedia( p_ml, p_media );
-            ml_gc_decref( p_media );
-        }
-        else
-            i_ret = AddInputItem( p_ml, p_input );
-    }
-
-    if( i_ret != VLC_SUCCESS )
-        msg_Dbg( p_mon, "Item could not be correctly added"
-                " or updated during scan: %s", p_input->psz_uri );
-    QuerySimple( p_ml, "UPDATE media SET directory_id=%d, timestamp=%d "
-                          "WHERE id=%d",
-                    p_itemobject->i_dir_id, p_itemobject->i_mtime,
-                    GetMediaIdOfURI( p_ml, p_input->psz_uri ) );
-    vlc_event_detach( &p_input->event_manager, vlc_InputItemPreparsedChanged,
-                  PreparseComplete, p_itemobject );
-    vlc_gc_decref( p_input );
-    free( p_itemobject->psz_uri );
-}
-
-/**
- * @brief Scan files in a particular directory
- */
-static void ScanFiles( monitoring_thread_t *p_mon, int i_dir_id,
-                       bool b_recursive, stat_list_t *stparent )
-{
-    int i_rows, i_cols, i_dir_content, i, i_mon_rows, i_mon_cols;
-    char **ppsz_monitored_files;
-    char **pp_results, *psz_dir;
-    char **pp_dir_content;
-    bool *pb_processed;
-    input_item_t *p_input;
-    struct stat s_stat;
-    media_library_t *p_ml = (media_library_t *)p_mon->p_ml;
-
-    Query( p_ml, &pp_results, &i_rows, &i_cols,
-              "SELECT uri AS directory_uri FROM directories WHERE id = '%d'",
-              i_dir_id );
-    if( i_rows < 1 )
-    {
-        msg_Dbg( p_mon, "query returned no directory for dir_id: %d (%s:%d)",
-                 i_dir_id, __FILE__, __LINE__ );
-        return;
-    }
-    psz_dir = strdup( pp_results[1] );
-    FreeSQLResult( p_ml, pp_results );
-
-    struct stat_list_t stself;
-
-    if( vlc_stat( psz_dir, &stself.st ) == -1 )
-    {
-        msg_Err( p_ml, "Cannot stat `%s': %m", psz_dir );
-        free( psz_dir );
-        return;
-    }
-#ifndef WIN32
-    for( stat_list_t *stats = stparent; stats != NULL; stats = stats->parent )
-    {
-        if( ( stself.st.st_ino == stats->st.st_ino ) &&
-            ( stself.st.st_dev == stats->st.st_dev ) )
-        {
-            msg_Warn( p_ml, "Ignoring infinitely recursive directory `%s'",
-                      psz_dir );
-            free( psz_dir );
-            return;
-        }
-    }
-#else
-    /* Windows has st_dev (driver letter - 'A'), but it zeroes st_ino,
-     * so that the test above will always incorrectly succeed.
-     * Besides, Windows does not have dirfd(). */
-#endif
-    stself.parent = stparent;
-
-    QuerySimple( p_ml, "UPDATE directories SET timestamp=%d WHERE id = %d",
-                    stself.st.st_mtime, i_dir_id );
-    Query( p_ml, &ppsz_monitored_files, &i_mon_rows, &i_mon_cols,
-              "SELECT id AS media_id, timestamp AS media_ts, uri AS media_uri "
-              "FROM media WHERE directory_id = %d",
-              i_dir_id );
-    pb_processed = malloc(sizeof(bool) * i_mon_rows);
-    for( i = 0; i < i_mon_rows ; i++)
-        pb_processed[i] = false;
-
-    i_dir_content = vlc_scandir( psz_dir, &pp_dir_content, NULL, Sort );
-    if( i_dir_content == -1 )
-    {
-        msg_Err( p_mon, "Cannot read `%s': %m", psz_dir );
-        free( pb_processed );
-        free( psz_dir );
-        return;
-    }
-    else if( i_dir_content == 0 )
-    {
-        msg_Dbg( p_mon, "Nothing in directory `%s'", psz_dir );
-        free( pb_processed );
-        free( psz_dir );
-        return;
-    }
-
-    for( i = 0; i < i_dir_content; i++ )
-    {
-        const char *psz_entry = pp_dir_content[i];
-
-        if( psz_entry[0] != '.' )
-        {
-            /* 7 is the size of "file://" */
-            char psz_uri[strlen(psz_dir) + strlen(psz_entry) + 2 + 7];
-            sprintf( psz_uri, "%s/%s", psz_dir, psz_entry );
-
-            if( vlc_stat( psz_uri, &s_stat ) == -1 )
-            {
-                msg_Err( p_mon, "%s: %m", psz_uri );
-                free( pb_processed );
-                free( psz_dir );
-                return;
-            }
-
-            if( S_ISREG( s_stat.st_mode ) )
-            {
-                const char *psz_dot = strrchr( psz_uri, '.' );
-                if( psz_dot++ && *psz_dot )
-                {
-                    int i_is_media = 0;
-                    for( int a = 0; ppsz_MediaExtensions[a]; a++ )
-                    {
-                        if( !strcasecmp( psz_dot, ppsz_MediaExtensions[a] ) )
-                        {
-                            i_is_media = 1;
-                            break;
-                        }
-                    }
-                    if( !i_is_media )
-                    {
-                        msg_Dbg( p_mon, "ignoring file %s", psz_uri );
-                        continue;
-                    }
-                }
-
-                char * psz_tmp = encode_URI_component( psz_uri );
-                char * psz_encoded_uri = ( char * )calloc( strlen( psz_tmp ) + 9, 1 );
-                strcpy( psz_encoded_uri, "file:///" );
-                strcat( psz_encoded_uri, psz_tmp );
-                free( psz_tmp );
-
-                /* Check if given media is already in DB and it has been updated */
-                bool b_skip = false;
-                bool b_update = false;
-                int j = 1;
-                for( j = 1; j <= i_mon_rows; j++ )
-                {
-                    if( strcasecmp( ppsz_monitored_files[ j * i_mon_cols + 2 ],
-                                    psz_encoded_uri ) != 0 )
-                        continue;
-                    b_update = true;
-                    pb_processed[ j - 1 ] = true;
-                    if( atoi( ppsz_monitored_files[ j * i_mon_cols + 1 ] )
-                        < s_stat.st_mtime )
-                    {
-                        b_skip = false;
-                        break;
-                    }
-                    else
-                    {
-                        b_skip = true;
-                        break;
-                    }
-                }
-                msg_Dbg( p_ml , "Checking if %s is in DB. Found: %d", psz_encoded_uri,
-                         b_skip? 1 : 0 );
-                if( b_skip )
-                    continue;
-
-                p_input = input_item_New( psz_encoded_uri, psz_entry );
-
-                playlist_t* p_pl = pl_Get( p_mon );
-                preparsed_item_t* p_itemobject;
-                p_itemobject = malloc( sizeof( preparsed_item_t ) );
-                p_itemobject->i_dir_id = i_dir_id;
-                p_itemobject->psz_uri = psz_encoded_uri;
-                p_itemobject->i_mtime = s_stat.st_mtime;
-                p_itemobject->p_mon = p_mon;
-                p_itemobject->b_update = b_update;
-                p_itemobject->i_update_id = b_update ?
-                    atoi( ppsz_monitored_files[ j * i_mon_cols + 0 ] ) : 0 ;
-
-                vlc_event_manager_t *p_em = &p_input->event_manager;
-                vlc_event_attach( p_em, vlc_InputItemPreparsedChanged,
-                      PreparseComplete, p_itemobject );
-                playlist_PreparseEnqueue( p_pl, p_input );
-            }
-            else if( S_ISDIR( s_stat.st_mode ) && b_recursive )
-            {
-                Query( p_ml, &pp_results, &i_rows, &i_cols,
-                        "SELECT id AS directory_id FROM directories "
-                        "WHERE uri=%Q", psz_uri );
-                FreeSQLResult( p_ml, pp_results );
-
-                if( i_rows <= 0 )
-                {
-                    msg_Dbg( p_mon, "New directory `%s' in dir of id %d",
-                             psz_uri, i_dir_id );
-                    QuerySimple( p_ml,
-                                    "INSERT INTO directories (uri, timestamp, "
-                                    "recursive) VALUES(%Q, 0, 1)", psz_uri );
-
-                    // We get the id of the directory we've just added
-                    Query( p_ml, &pp_results, &i_rows, &i_cols,
-                    "SELECT id AS directory_id FROM directories WHERE uri=%Q",
-                              psz_uri );
-                    if( i_rows <= 0 )
-                    {
-                        msg_Err( p_mon, "Directory `%s' was not sucessfully"
-                                " added to the database", psz_uri );
-                        FreeSQLResult( p_ml, pp_results );
-                        continue;
-                    }
-
-                    ScanFiles( p_mon, atoi( pp_results[1] ), b_recursive,
-                               &stself );
-                    FreeSQLResult( p_ml, pp_results );
-                }
-            }
-        }
-    }
-
-    vlc_array_t* delete_ids = vlc_array_new();
-    for( i = 0; i < i_mon_rows; i++ )
-    {
-       if( !pb_processed[i] )
-        {
-            /* This file doesn't exist anymore. Let's...urm...delete it. */
-            ml_element_t* find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) );
-            find->criteria = ML_ID;
-            find->value.i = atoi( ppsz_monitored_files[ (i + 1) * i_mon_cols ] );
-            vlc_array_append( delete_ids, find );
-       }
-    }
-
-    /* Delete the unfound media */
-    if( Delete( p_ml, delete_ids ) != VLC_SUCCESS )
-        msg_Dbg( p_ml, "Something went wrong in multi delete" );
-
-    for( i = 0; i < vlc_array_count( delete_ids ); i++ )
-    {
-       free( vlc_array_item_at_index( delete_ids, i ) );
-    }
-    vlc_array_destroy( delete_ids );
-
-    FreeSQLResult( p_ml, ppsz_monitored_files );
-    for( i = 0; i < i_dir_content; i++ )
-        free( pp_dir_content[i] );
-    free( pp_dir_content );
-    free( psz_dir );
-    free( pb_processed );
-}
diff --git a/modules/media_library/sql_search.c b/modules/media_library/sql_search.c
deleted file mode 100644 (file)
index 5a0848b..0000000
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*****************************************************************************
- * sql_search.c: SQL-based media library: all find/get functions
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "sql_media_library.h"
-
-int Find( media_library_t *p_ml, vlc_array_t *p_result_array, ... )
-{
-    va_list args;
-    int returned;
-
-    va_start( args, p_result_array );
-    returned = FindVa( p_ml, p_result_array, args );
-    va_end( args );
-
-    return returned;
-}
-
-/**
- * @brief Generic find in Media Library, returns arrays of psz or int
- *
- * @param p_ml the media library object
- * @param result A pointer to a result array
- * @param criterias list of criterias used in SELECT
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int FindVa( media_library_t *p_ml,
-            vlc_array_t *p_result_array, va_list criterias )
-{
-    int i_ret = VLC_SUCCESS;
-    char *psz_query;
-    ml_result_type_e result_type;
-    char **pp_results = NULL;
-    int i_cols, i_rows;
-
-    if( !p_result_array )
-        return VLC_EGENERIC;
-
-    i_ret = BuildSelectVa( p_ml, &psz_query, &result_type, criterias );
-    if( i_ret != VLC_SUCCESS )
-        return i_ret;
-
-    if( Query( p_ml, &pp_results, &i_rows, &i_cols, "%s", psz_query )
-        != VLC_SUCCESS )
-    {
-        msg_Err( p_ml, "Error occurred while making the query to the database" );
-        return VLC_EGENERIC;
-    }
-
-    i_ret = SQLToResultArray( p_ml, p_result_array, pp_results, i_rows, i_cols,
-                              result_type );
-
-    free( psz_query);
-    FreeSQLResult( p_ml, pp_results );
-
-    return i_ret;
-}
-
-/**
- * @brief Generic find in Media Library, returns arrays of psz or int
- *
- * @param p_ml the media library object
- * @param result a pointer to a result array
- * @param selected_type the type of the element we're selecting
- * @param criterias list of criterias used in SELECT
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-
-int FindAdv( media_library_t *p_ml, vlc_array_t *p_result_array,
-             ml_select_e selected_type, const char* psz_lvalue, ml_ftree_t *tree )
-{
-    int i_ret = VLC_SUCCESS;
-    char *psz_query;
-    ml_result_type_e result_type;
-    char **pp_results = NULL;
-    int i_cols, i_rows;
-
-    if( !p_result_array )
-        return VLC_EGENERIC;
-
-    i_ret = BuildSelect( p_ml, &psz_query, &result_type, psz_lvalue,
-                         selected_type, tree );
-
-    if( i_ret != VLC_SUCCESS )
-        return i_ret;
-
-    if( Query( p_ml, &pp_results, &i_rows, &i_cols, "%s", psz_query )
-        != VLC_SUCCESS )
-    {
-        msg_Err( p_ml, "Error occurred while making the query to the database" );
-        return VLC_EGENERIC;
-    }
-
-    i_ret = SQLToResultArray( p_ml, p_result_array, pp_results, i_rows, i_cols,
-                              result_type );
-
-    free( psz_query);
-    FreeSQLResult( p_ml, pp_results );
-
-    return i_ret;
-}
-
-/**
- * @brief Generic SELECT query builder with va_list parameter
- *
- * @param p_ml This media_library_t object
- * @param ppsz_query *ppsz_query will contain query
- * @param p_result_type see enum ml_result_type_e
- * @param criterias list of criterias used in SELECT
- * @return VLC_SUCCESS or a VLC error code
- * NOTE va_list criterias must end with ML_END or this will fail (segfault)
- *
- * This function handles results of only one column (or two if ID is included),
- * of 'normal' types: int and strings
- */
-int BuildSelectVa( media_library_t *p_ml, char **ppsz_query,
-                   ml_result_type_e *p_result_type, va_list criterias )
-{
-    int i_continue = 1;
-    ml_ftree_t* p_ftree = NULL;
-    char* psz_lvalue = NULL;
-
-    /* Get the name of the data we want */
-    ml_select_e selected_type = va_arg( criterias, int );
-    if( selected_type == ML_PEOPLE || selected_type == ML_PEOPLE_ID ||
-            selected_type == ML_PEOPLE_ROLE )
-        psz_lvalue = va_arg( criterias, char * );
-
-    /* Loop on every arguments */
-    while( i_continue )
-    {
-        ml_ftree_t *p_find = ( ml_ftree_t* ) calloc( 1, sizeof( ml_ftree_t ) );
-        if( !p_find )
-            return VLC_ENOMEM;
-        p_find->criteria = va_arg( criterias, int );
-        p_find->comp = ML_COMP_EQUAL;
-        switch( p_find->criteria )
-        {
-            case ML_SORT_ASC:
-                p_ftree = ml_FtreeSpecAsc( p_ftree, va_arg( criterias, char* ) ); break;
-            case ML_SORT_DESC:
-                p_ftree = ml_FtreeSpecDesc( p_ftree, va_arg( criterias, char* ) ); break;
-            case ML_DISTINCT:
-                p_ftree = ml_FtreeSpecDistinct( p_ftree ); break;
-            case ML_LIMIT:
-                p_ftree = ml_FtreeSpecLimit( p_ftree, va_arg( criterias, int ) );
-                break;
-            case ML_ARTIST:
-                /* This is OK because of a shallow free find */
-                p_find->lvalue.str = (char *)ML_PERSON_ARTIST;
-                p_find->value.str = va_arg( criterias, char* );
-                p_ftree = ml_FtreeFastAnd( p_ftree, p_find );
-                break;
-            case ML_PEOPLE:
-                p_find->lvalue.str = va_arg( criterias, char* );
-                p_find->value.str = va_arg( criterias, char* );
-                p_ftree = ml_FtreeFastAnd( p_ftree, p_find );
-                break;
-            case ML_PEOPLE_ID:
-                p_find->lvalue.str = va_arg( criterias, char* );
-                p_find->value.i = va_arg( criterias, int );
-                p_ftree = ml_FtreeFastAnd( p_ftree, p_find );
-                break;
-            case ML_END:
-                i_continue = 0;
-                break;
-            default:
-                switch( ml_AttributeIsString( p_find->criteria ) )
-                {
-                    case 0:
-                        p_find->value.i = va_arg( criterias, int );
-                        break;
-                    case 1:
-                        p_find->value.str = va_arg( criterias, char* );
-                        break;
-                }
-                p_ftree = ml_FtreeFastAnd( p_ftree, p_find );
-                break;
-        }
-    }
-
-    int i_ret = BuildSelect( p_ml, ppsz_query, p_result_type, psz_lvalue,
-                             selected_type, p_ftree );
-
-    ml_ShallowFreeFindTree( p_ftree );
-    return i_ret;
-}
-
-/**
- * @brief Append a string and format it using SQL vmprintf
- **/
-static int AppendStringFmtVa( media_library_t *p_ml,
-                              char **ppsz_dst, const char *psz_fmt,
-                              va_list args )
-{
-    char *psz_tmp = NULL, *psz_fullexp = NULL;
-
-    assert( ppsz_dst != NULL );
-
-    if( !( *ppsz_dst ) )
-    {
-        /* New expression */
-        *ppsz_dst = sql_VPrintf( p_ml->p_sys->p_sql, psz_fmt, args );
-        if( !( *ppsz_dst ) )
-            return VLC_ENOMEM;
-    }
-    else
-    {
-        /* Create new expression B */
-        psz_tmp = sql_VPrintf( p_ml->p_sys->p_sql, psz_fmt, args );
-        if( !psz_tmp )
-            return VLC_ENOMEM;
-
-        if( asprintf( &psz_fullexp, "%s%s", *ppsz_dst, psz_tmp ) == -1 )
-        {
-            free( psz_tmp );
-            return VLC_ENOMEM;
-        }
-
-        free( *ppsz_dst );
-        *ppsz_dst = psz_fullexp;
-    }
-
-    return VLC_SUCCESS;
-}
-
-static int AppendStringFmt( media_library_t *p_ml,
-                            char **ppsz_dst, const char *psz_fmt, ... )
-{
-    va_list args;
-    va_start( args, psz_fmt );
-    int i_ret = AppendStringFmtVa( p_ml, ppsz_dst, psz_fmt, args );
-    va_end( args );
-    return i_ret;
-}
-
-/* Early Declaration of Where String Generator */
-static int BuildWhere( media_library_t* p_ml, char **ppsz_where, ml_ftree_t* tree,
-       char** sort, int* limit, const char** distinct, char*** pppsz_frompersons,
-       int* i_frompersons, int* join );
-
-#   define table_media             (1 << 0)
-#   define table_album             (1 << 1)
-#   define table_people            (1 << 2)
-#   define table_extra             (1 << 3)
-
-static void PackFromPersons( char*** pppsz_frompersons, int i_num_frompersons )
-{
-    for( int i = 0; i < i_num_frompersons; i++ )
-    {
-        if( *pppsz_frompersons[i] == NULL )
-            continue;
-        for( int j = i+1; j < i_num_frompersons; j++ )
-        {
-            if( strcmp( *pppsz_frompersons[i], *pppsz_frompersons[j] ) == 0 )
-            {
-                *pppsz_frompersons[j] = NULL;
-            }
-        }
-    }
-}
-/**
- * @brief Generic SELECT query builder
- *
- * @param p_ml This media_library_t object
- * @param ppsz_query *ppsz_query will contain query
- * @param p_result_type see enum ml_result_type_e
- * @param selected_type the type of the element we're selecting
- * @param tree the find tree
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int BuildSelect( media_library_t *p_ml,
-                 char **ppsz_query, ml_result_type_e *p_result_type,
-                 const char *psz_selected_type_lvalue, ml_select_e selected_type,
-                 ml_ftree_t *tree )
-{
-    /* Basic verification */
-    if( !ppsz_query )
-        return VLC_EGENERIC;
-
-    int i_ret = VLC_SUCCESS;
-    char *psz_query = NULL;
-
-    /* Building psz_query :
-    psz_query = "SELECT psz_distinct psz_select
-                 FROM psz_from [JOIN psz_join ON psz_on]
-                 [JOIN psz_join2 ON psz_on2]
-                 [WHERE psz_where[i] [AND psz_where[j] ...]]
-                 [LIMIT psz_limit] [ORDER BY psz_select psz_sort] ;"
-    */
-    char *psz_select             = NULL;
-    const char *psz_distinct     = ""; /* "DISTINCT" or "" */
-
-    /* FROM */
-    char *psz_from               = NULL;
-    int i_from                   = 0; /* Main select table */
-
-    char **ppsz_frompersons      = NULL;
-    int  i_num_frompersons       = 0;
-    char *psz_peoplerole         = NULL; /* Person to get selected */
-
-    /* JOIN ... ON ... */
-    char *psz_join               = NULL;
-    char *psz_join2              = NULL;
-    char *psz_on                 = NULL;
-    char *psz_on2                = NULL;
-    int i_join                   = 0;    /* Tables that need to be joined */
-
-    /* String buffers */
-    char *psz_where              = NULL;
-    char *psz_sort               = NULL; /* ASC or DESC or NULL */
-    char *psz_tmp                = NULL;
-
-    int i_limit                  = 0;
-
-    /* Build the WHERE condition */
-    BuildWhere( p_ml, &psz_where, tree, &psz_sort, &i_limit,
-            &psz_distinct, &ppsz_frompersons, &i_num_frompersons, &i_join );
-
-    PackFromPersons( &ppsz_frompersons, i_num_frompersons );
-
-    /* What is the result type? */
-    ml_result_type_e res_type   = ML_TYPE_PSZ;
-
-    /* SELECT, FROM */
-    /* Note that a DISTINCT select makes id of result non sense */
-    switch( selected_type )
-    {
-    case ML_ALBUM:
-        psz_select   = ( !*psz_distinct ) ?
-                        strdup( "album.id, album.title AS album_title" )
-                        : strdup( "album.title AS album_title" );
-        i_from       = table_album;
-        break;
-    case ML_ALBUM_COVER:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "album.id, album.cover" ) : strdup( "album.cover" );
-        i_from       = table_album;
-        break;
-    case ML_ALBUM_ID:
-        psz_select   = strdup( "album.id" );
-        psz_distinct = "DISTINCT";
-        i_from       = table_album;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_ARTIST:
-        psz_select   = ( !*psz_distinct ) ?
-                        strdup( "people_Artist.id, people_Artist.name" )
-                        : strdup( "people_Artist.name" );
-        i_from       = table_people;
-        psz_peoplerole = strdup( ML_PERSON_ARTIST );
-        break;
-    case ML_ARTIST_ID:
-        psz_select   = strdup( "people_Artist.id" );
-        psz_distinct = "DISTINCT";
-        i_from       = table_people;
-        res_type     = ML_TYPE_INT;
-        psz_peoplerole = strdup( ML_PERSON_ARTIST );
-        break;
-    case ML_COVER:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, media.cover" ) : strdup( "media.cover" );
-        i_from       = table_media;
-        break;
-    case ML_COMMENT:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, extra.comment" ) : strdup( "extra.comment" );
-        i_from       = table_extra;
-        break;
-    case ML_GENRE:
-        psz_select   = ( !*psz_distinct ) ?
-               strdup( "media.id, media.genre" ) : strdup( "media.genre" );
-        i_from       = table_media;
-        break;
-    case ML_COUNT_MEDIA:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "COUNT()" ) : strdup( "COUNT( DISTINCT media.id )" );
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_COUNT_ALBUM:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "COUNT()" ) : strdup( "COUNT( DISTINCT album.id )" );
-        i_from       = table_album;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_COUNT_PEOPLE:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "COUNT()" ) : strdup( "COUNT( DISTINCT people.id )" );
-        i_from       = table_people;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_FILESIZE:
-        psz_select   = strdup( "media.filesize" );
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_ID:
-        psz_select   = strdup( "media.id" ); /* ID: must be distinct */
-        psz_distinct = "DISTINCT";
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_LANGUAGE:
-        psz_select   = strdup( "extra.language" );
-        psz_distinct = "DISTINCT";
-        i_from       = table_extra;
-        break;
-    case ML_MEDIA_SPARSE:
-        i_ret = AppendStringFmt( p_ml, &psz_select, "media.id AS id,"
-                "media.uri AS uri,"
-                "media.type AS type,"
-                "media.title AS title,"
-                "media.duration AS duration,"
-                "media.original_title AS original_title,"
-                "media.album_id AS album_id,"
-                "media.cover AS cover,"
-                "media.preview AS preview,"
-                "media.disc AS disc,"
-                "media.track AS track,"
-                "media.year AS year,"
-                "media.genre AS genre,"
-                "media.played_count AS played_count,"
-                "media.last_played AS last_played,"
-                "media.first_played AS first_played,"
-                "media.import_time AS import_time,"
-                "media.skipped_count AS skipped_count,"
-                "media.last_skipped AS last_skipped,"
-                "media.vote AS vote,"
-                "media.score AS score,"
-                "media.comment AS comment,"
-                "media.filesize AS filesize,"
-                "album.title AS album_title,"
-                "album.cover AS album_cover,"
-        "(SELECT name FROM media_to_people JOIN people "
-        "ON (people_id = id) WHERE media_id = media.id AND role = %Q LIMIT 1) AS people_%s",
-        ML_PERSON_ARTIST, ML_PERSON_ARTIST );
-        if( i_ret != VLC_SUCCESS )
-            goto exit;
-        i_from       = table_media;
-        i_join      |= ( table_album | table_people );
-        psz_distinct = "DISTINCT";
-        res_type     = ML_TYPE_MEDIA;
-        break;
-    case ML_MEDIA:
-        /* Who said this was over-complicated ?? */
-        /* Yea right. */
-        psz_select   = strdup( "media.id AS id,"
-                "media.uri AS uri,"
-                "media.type AS type,"
-                "media.title AS title,"
-                "media.duration AS duration,"
-                "media.original_title AS original_title,"
-                "media.album_id AS album_id,"
-                "media.cover AS cover,"
-                "media.preview AS preview,"
-                "media.disc as disc,"
-                "media.track AS track,"
-                "media.year AS year,"
-                "media.genre AS genre,"
-                "media.played_count AS played_count,"
-                "media.last_played AS last_played,"
-                "media.first_played AS first_played,"
-                "media.import_time AS import_time,"
-                "media.last_skipped AS last_skipped,"
-                "media.skipped_count AS skipped_count,"
-                "media.vote AS vote,"
-                "media.score AS score,"
-                "media.comment AS comment,"
-                "media.filesize AS filesize,"
-                "album.title AS album_title,"
-                "album.cover AS album_cover,"
-                "people.id AS people_id,"
-                "people.name AS people_name,"
-                "people.role AS people_role,"
-                "extra.language AS language,"
-                "extra.extra AS extra" );
-        i_from       = table_media;
-        i_join      |= ( table_album | table_people | table_extra );
-        psz_distinct = "DISTINCT";
-        res_type     = ML_TYPE_MEDIA;
-        break;
-    case ML_MEDIA_EXTRA:
-        psz_select = strdup( "media.id AS id,"
-                "people.id AS people_id,"
-                "people.name AS people_name,"
-                "people.role AS people_role,"
-                "extra.extra AS extra,"
-                "extra.language AS language" );
-        i_from       = table_media;
-        i_join      |= ( table_album | table_people | table_extra );
-        psz_distinct = "DISTINCT";
-        res_type     = ML_TYPE_MEDIA;
-        break;
-    case ML_ORIGINAL_TITLE:
-        psz_select   = ( !*psz_distinct ) ?
-               strdup( "media.id, media.original_title" ) : strdup( "media.original_title" );
-        i_from       = table_media;
-        break;
-    /* For people, if lvalue = "", then we want ANY people. */
-    case ML_PEOPLE:
-        assert( psz_selected_type_lvalue );
-        i_ret = AppendStringFmt( p_ml, &psz_select, "people%s%s.name",
-           *psz_selected_type_lvalue ? "_" : "",
-           *psz_selected_type_lvalue ? psz_selected_type_lvalue : "" );
-        if( i_ret != VLC_SUCCESS )
-            goto exit;
-        if( *psz_distinct )
-        {
-            i_ret = AppendStringFmt( p_ml, &psz_select, ", people%s%s.name",
-               *psz_selected_type_lvalue ? "_" : "",
-               *psz_selected_type_lvalue ? psz_selected_type_lvalue : "" );
-            if( i_ret != VLC_SUCCESS )
-                goto exit;
-        }
-        i_from         = table_people;
-        psz_peoplerole = strdup( psz_selected_type_lvalue );
-        break;
-    case ML_PEOPLE_ID:
-        assert( psz_selected_type_lvalue );
-        i_ret = AppendStringFmt( p_ml, &psz_select, "people%s%s.id",
-           *psz_selected_type_lvalue ? "_" : "",
-           *psz_selected_type_lvalue ? psz_selected_type_lvalue : "" );
-        if( i_ret != VLC_SUCCESS )
-            goto exit;
-        if( *psz_distinct )
-        {
-            i_ret = AppendStringFmt( p_ml, &psz_select, ", people%s%s.id",
-               *psz_selected_type_lvalue ? "_" : "",
-               *psz_selected_type_lvalue ? psz_selected_type_lvalue : "" );
-            if( i_ret != VLC_SUCCESS )
-                goto exit;
-        }
-        psz_distinct   = "DISTINCT";
-        i_from         = table_people;
-        psz_peoplerole = strdup( psz_selected_type_lvalue );
-        res_type       = ML_TYPE_INT;
-        break;
-    case ML_PEOPLE_ROLE:
-        psz_select   = strdup( "people.role" );
-        psz_distinct = "DISTINCT";
-        i_from       = table_people;
-        break;
-    case ML_TITLE:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, media.title" ) : strdup( "media.title" );
-        i_from       = table_media;
-        break;
-    case ML_TYPE:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, media.type" ): strdup( "media.type" );
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_URI:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, media.uri" ) : strdup( "media.uri" );
-        i_from       = table_media;
-        break;
-    case ML_VOTE:
-        psz_select   = ( !*psz_distinct ) ?
-                strdup( "media.id, media.vote" ) : strdup( "media.vote" );
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_YEAR:
-        psz_select   = ( !*psz_distinct ) ?
-               strdup( "media.id, media.year" ) : strdup( "media.year" );
-        i_from       = table_media;
-        res_type     = ML_TYPE_INT;
-        break;
-    case ML_LIMIT:
-    case ML_SORT_DESC:
-    case ML_SORT_ASC:
-    case ML_END:
-    default:
-        msg_Dbg( p_ml, "unknown select (%d) in BuildSelect", selected_type );
-        return VLC_EGENERIC;
-    }
-
-    /* Let's build full psz_query ! */
-    i_ret = VLC_SUCCESS;
-
-    /* Figure out select and join tables */
-    switch( i_from )
-    {
-        case table_media:
-            break;
-        case table_album:
-            switch( i_join )
-            {
-                case 0: break;
-                case 2: i_join = 0; break;
-                case 1:
-                case 3: i_from = table_media; i_join = table_album; break;
-                case 4:
-                case 5:
-                case 6:
-                case 7: i_from = table_media; i_join = table_album | table_people; break;
-                case 8:
-                case 9:
-                case 10:
-                case 11: i_from = table_media; i_join = table_extra | table_album; break;
-                case 12:
-                case 13:
-                case 14:
-                case 15: i_from = table_media; i_join = table_extra | table_album | table_people; break;
-                default: break;
-            }
-            break;
-        case table_people:
-            switch( i_join )
-            {
-                case 0: break;
-                case 1: i_from = table_media; i_join = table_people; break;
-                case 2:
-                case 3: i_from = table_media; i_join = table_album | table_people; break;
-                case 4:
-                    /* Determine if a join from media is required */
-                    if( i_num_frompersons > 1 )
-                        i_from = table_media;
-                    else
-                        i_join = 0;
-                    break;
-                case 5: i_from = table_media; i_join = table_people; break;
-                case 6:
-                case 7: i_from = table_media; i_join = table_album | table_people; break;
-                case 8:
-                case 9: i_from = table_media; i_join = table_people | table_extra; break;
-                case 10:
-                case 11: i_from = table_media; i_join = table_people | table_album | table_extra; break;
-                case 12:
-                case 13: i_from = table_media; i_join = table_people | table_extra; break;
-                case 14:
-                case 15: i_from = table_media; i_join = table_people | table_album | table_extra; break;
-                default: break;
-            }
-            break;
-        case table_extra:
-            switch( i_join )
-            {
-                case 0: break;
-                case 1: i_from = table_media; i_join = table_extra; break;
-                case 2:
-                case 3: i_from = table_media; i_join = table_extra | table_album; break;
-                case 4:
-                case 5: i_from = table_media; i_join = table_extra | table_people; break;
-                case 6:
-                case 7: i_from = table_media; i_join = table_extra | table_people | table_album; break;
-                case 8: i_from = table_extra; i_join = 0; break;
-                case 9: i_from = table_media; i_join = table_extra; break;
-                case 10:
-                case 11: i_from = table_media; i_join = table_extra | table_album; break;
-                case 12:
-                case 13: i_from = table_media; i_join = table_extra | table_people; break;
-                case 14:
-                case 15: i_from = table_media; i_join = table_extra | table_people | table_album; break;
-                default: break;
-            }
-            break;
-        default: msg_Warn( p_ml, "You can't be selecting from this table!!" );
-                 i_ret = VLC_EGENERIC;
-                 goto exit;
-    }
-
-    assert( !( i_from & table_album && i_join & table_album ) );
-    assert( !( i_from & table_people && i_join & table_people ) );
-    assert( !( i_from & table_extra && i_join & table_extra ) );
-
-    /* Generate FROM - psz_from */
-    if( i_from == table_media )
-        i_ret = AppendStringFmt( p_ml, &psz_from, "media" );
-    else if( i_from == table_album )
-        i_ret = AppendStringFmt( p_ml, &psz_from, "album" );
-    else if( i_from == table_extra )
-        i_ret = AppendStringFmt( p_ml, &psz_from, "extra" );
-    else if( i_from == table_people )
-    {
-        i_ret = AppendStringFmt( p_ml, &psz_from, "people AS people%s%s",
-                psz_peoplerole ? "_" : "", psz_peoplerole );
-        if( i_ret < 0 ) goto exit;
-
-        /* The ugly next statement is only required if persons are being
-         * selected. Otherwise the joins will handle this */
-        if( psz_peoplerole && *psz_peoplerole )
-        {
-            i_ret = AppendStringFmt( p_ml, &psz_where, "%s people_%s.role = %Q ",
-                                     ( psz_where && *psz_where ) ? " AND" : "",
-                                     psz_peoplerole, psz_peoplerole );
-            if( i_ret < 0 ) goto exit;
-        }
-    }
-    if( i_ret < 0 ) goto exit;
-
-    i_ret = AppendStringFmt( p_ml, &psz_query,
-                             "SELECT %s %s ", psz_distinct, psz_select );
-    if( i_ret < 0 ) goto exit;
-
-    i_ret = AppendStringFmt( p_ml, &psz_query, "FROM %s ", psz_from );
-    if( i_ret < 0 ) goto exit;
-
-    /* Create join conditions */
-    if( i_join & table_people )
-    {
-        /* we can join psz_peoplerole safely because
-         * if i_join = people, then i_from != people */
-        bool join = true;
-        for( int i = 0; i < i_num_frompersons ; i++ )
-        {
-            /* We assume ppsz_frompersons has unique entries and
-             * if ppsz_frompersons[i] is empty(but not NULL), then it
-             * means we accept any role */
-            if( ppsz_frompersons[i] && *ppsz_frompersons[i] )
-            {
-                if( strcmp( psz_peoplerole, ppsz_frompersons[i] ) == 0 )
-                    join = false;
-                AppendStringFmt( p_ml, &psz_join, "%smedia_to_people AS people_%sx ",
-                        psz_join == NULL ? "" : ",", ppsz_frompersons[i] );
-                /* This is possible because from is usually the media table */
-                AppendStringFmt( p_ml, &psz_on, "%speople_%sx.media_id = media.id ",
-                        psz_on == NULL ? "" : " AND ", ppsz_frompersons[i] );
-                AppendStringFmt( p_ml, &psz_join2, "%speople AS people_%s ",
-                        psz_join2 == NULL ? "" : ",", ppsz_frompersons[i] );
-                AppendStringFmt( p_ml, &psz_on2, "%s ( people_%sx.people_id = people_%s.id AND "
-                        "people_%s.role = %Q )", psz_on2 == NULL ? "" : " AND ",
-                        ppsz_frompersons[i], ppsz_frompersons[i],
-                        ppsz_frompersons[i], ppsz_frompersons[i]  );
-            }
-            else if( ppsz_frompersons[i] )
-            {
-                if( strcmp( psz_peoplerole, ppsz_frompersons[i] ) == 0 )
-                    join = false;
-                AppendStringFmt( p_ml, &psz_join, "%smedia_to_people AS peoplex ",
-                        psz_join == NULL ? "" : "," );
-                /* This is possible because from is usually the media table */
-                AppendStringFmt( p_ml, &psz_on, "%speoplex.media_id = media.id ",
-                        psz_on == NULL ? "" : " AND " );
-                AppendStringFmt( p_ml, &psz_join2, "%speople AS people ",
-                        psz_join2 == NULL ? "" : "," );
-                AppendStringFmt( p_ml, &psz_on2, "%s peoplex.people_id = people.id",
-                        psz_on2 == NULL ? "" : " AND " );
-            }
-        }
-        if( join )
-        {
-            if( psz_peoplerole && *psz_peoplerole )
-            {
-                AppendStringFmt( p_ml, &psz_join, "%smedia_to_people AS people_%sx ",
-                        psz_join == NULL ? "" : ",", psz_peoplerole );
-                /* This is possible because from is always the media table */
-                AppendStringFmt( p_ml, &psz_on, "%speople_%sx.media_id = media.id ",
-                        psz_on == NULL ? "" : " AND ", psz_peoplerole );
-                AppendStringFmt( p_ml, &psz_join2, "%speople AS people_%s ",
-                        psz_join2 == NULL ? "" : ",", psz_peoplerole );
-                AppendStringFmt( p_ml, &psz_on2, "%s ( people_%sx.people_id = people_%s.id AND "
-                        "people_%s.role = %Q )", psz_on2 == NULL ? "" : " AND ",
-                        psz_peoplerole, psz_peoplerole,
-                        psz_peoplerole, psz_peoplerole );
-            }
-            else
-            {
-                AppendStringFmt( p_ml, &psz_join, "%smedia_to_people AS peoplex ",
-                        psz_join == NULL ? "" : "," );
-                /* This is possible because from is usually the media table */
-                AppendStringFmt( p_ml, &psz_on, "%speoplex.media_id = media.id ",
-                        psz_on == NULL ? "" : " AND " );
-                AppendStringFmt( p_ml, &psz_join2, "%speople ",
-                        psz_join2 == NULL ? "" : "," );
-                AppendStringFmt( p_ml, &psz_on2, "%s peoplex.people_id = people.id",
-                        psz_on2 == NULL ? "" : " AND " );
-
-            }
-        }
-    }
-    if( i_join & table_album )
-    {
-        AppendStringFmt( p_ml, &psz_join, "%salbum", psz_join == NULL ? "" : "," );
-        AppendStringFmt( p_ml, &psz_on, "%s album.id = media.album_id ",
-                psz_on == NULL ? "" : " AND " );
-    }
-    if( i_join & table_extra )
-    {
-        AppendStringFmt( p_ml, &psz_join, "%sextra", psz_join == NULL ? "" : "," );
-        AppendStringFmt( p_ml, &psz_on, "%s extra.id = media.id ",
-                psz_on == NULL ? "" : " AND " );
-    }
-
-    /* Complete the join clauses */
-    if( psz_join )
-    {
-        AppendStringFmt( p_ml, &psz_query,
-                         "JOIN %s ON %s ", psz_join, psz_on );
-    }
-    if( psz_join2 )
-    {
-        AppendStringFmt( p_ml, &psz_query,
-                         "JOIN %s ON %s ", psz_join2, psz_on2 );
-    }
-    if( psz_where && *psz_where )
-    {
-        AppendStringFmt( p_ml, &psz_query,
-                         "WHERE %s ", psz_where );
-    }
-    /* TODO: FIXME: Limit on media objects doesn't work! */
-    if( i_limit )
-    {
-        AppendStringFmt( p_ml, &psz_query,
-                         "LIMIT %d ", i_limit );
-    }
-
-    if( psz_sort )
-    {
-        AppendStringFmt( p_ml, &psz_query,
-                         "ORDER BY %s %s", psz_select, psz_sort );
-    }
-
-    if( i_ret > 0 ) i_ret = VLC_SUCCESS;
-
-    if( p_result_type ) *p_result_type = res_type;
-    if( !psz_query )    i_ret = VLC_EGENERIC;
-    else                *ppsz_query = strdup( psz_query );
-
-exit:
-    free( psz_query );
-    free( psz_where );
-    free( psz_tmp   );
-    free( psz_from  );
-    free( psz_join  );
-    free( psz_select );
-    free( psz_join2 );
-    free( psz_on    );
-    free( psz_on2   );
-    free( psz_peoplerole );
-    free( ppsz_frompersons );
-
-    if( i_ret != VLC_SUCCESS )
-        msg_Warn( p_ml, "an unknown error occurred (%d)", i_ret );
-
-    return i_ret;
-}
-
-#undef CASE_INT
-#define CASE_INT( casestr, fmt, table )                                     \
-case casestr:                                                               \
-assert( tree->comp != ML_COMP_HAS && tree->comp != ML_COMP_STARTS_WITH      \
-        && tree->comp != ML_COMP_ENDS_WITH );                               \
-*ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "%s %s %d", fmt,              \
-    tree->comp == ML_COMP_LESSER ? "<" :                                    \
-    tree->comp == ML_COMP_LESSER_OR_EQUAL ? "<=" :                          \
-    tree->comp == ML_COMP_GREATER ? ">" :                                   \
-    tree->comp == ML_COMP_GREATER_OR_EQUAL ? ">=" : "=", tree->value.i );   \
-if( *ppsz_where == NULL )                                                   \
-    goto parsefail;                                                         \
-*join |= table;                                                             \
-break
-
-#undef CASE_PSZ
-#define CASE_PSZ( casestr, fmt, table )                                       \
-case casestr:                                                                 \
-    assert( tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_EQUAL          \
-        || tree->comp == ML_COMP_STARTS_WITH                                  \
-        || tree->comp == ML_COMP_ENDS_WITH );                                 \
-    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "%s %s '%s%q%s'", fmt,      \
-        (ML_COMP_EQUAL)?"=":"LIKE",                                           \
-        tree->comp == ML_COMP_HAS                                             \
-        || tree->comp == ML_COMP_STARTS_WITH? "%%" : "",                      \
-            tree->value.str,                                                  \
-        tree->comp == ML_COMP_HAS                                             \
-        || tree->comp == ML_COMP_ENDS_WITH? "%%" : "" );                      \
-    if( *ppsz_where == NULL )                                                 \
-        goto parsefail;                                                       \
-    *join |= table;                                                           \
-    break
-
-#define SLDPJ sort, limit, distinct, pppsz_frompersons, i_frompersons, join
-static int BuildWhere( media_library_t* p_ml, char **ppsz_where, ml_ftree_t* tree,
-       char** sort, int* limit, const char** distinct,
-       char*** pppsz_frompersons, int* i_frompersons, int* join )
-{
-    assert( ppsz_where && sort && distinct );
-    if( !tree ) /* Base case */
-    {
-        return VLC_SUCCESS;
-    }
-
-    int i_ret = VLC_EGENERIC;
-    char* psz_left = NULL;
-    char* psz_right = NULL;
-
-    switch( tree->op )
-    {
-        case ML_OP_AND:
-        case ML_OP_OR:
-            i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ );
-            if( i_ret != VLC_SUCCESS )
-                goto parsefail;
-            i_ret = BuildWhere( p_ml, &psz_right, tree->right, SLDPJ );
-            if( i_ret != VLC_SUCCESS )
-                goto parsefail;
-            if( psz_left == NULL || psz_right == NULL )
-            {
-                msg_Err( p_ml, "Parsing failed for AND/OR" );
-                i_ret = VLC_EGENERIC;
-                goto parsefail;
-            }
-            if( asprintf( ppsz_where, "( %s %s %s )", psz_left,
-                ( tree->op == ML_OP_AND ? "AND" : "OR" ), psz_right ) == -1 )
-            {
-                i_ret = VLC_ENOMEM;
-                goto parsefail;
-            }
-            break;
-        case ML_OP_NOT:
-            i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ );
-            if( i_ret != VLC_SUCCESS )
-                goto parsefail;
-            if( psz_left == NULL )
-            {
-                msg_Err( p_ml, "Parsing failed at NOT" );
-                i_ret = VLC_EGENERIC;
-                goto parsefail;
-            }
-            if( asprintf( ppsz_where, "( NOT %s )", psz_left ) == -1 )
-            {
-                i_ret = VLC_ENOMEM;
-                goto parsefail;
-            }
-            break;
-        case ML_OP_SPECIAL:
-            i_ret = BuildWhere( p_ml, &psz_right, tree->right, SLDPJ );
-            if( i_ret != VLC_SUCCESS )
-                goto parsefail;
-            i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ );
-            if( i_ret != VLC_SUCCESS )
-                goto parsefail;
-            /* Ignore right parse tree as this is a special node */
-            *ppsz_where = strdup( psz_left ? psz_left : "" );
-            if( !*ppsz_where )
-            {
-                i_ret = VLC_ENOMEM;
-                goto parsefail;
-            }
-            break;
-        case ML_OP_NONE:
-            switch( tree->criteria )
-            {
-                case ML_PEOPLE:
-                    assert( tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_EQUAL
-                            || tree->comp == ML_COMP_STARTS_WITH
-                            || tree->comp == ML_COMP_ENDS_WITH );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql,
-                            "people%s%s.name LIKE '%s%q%s'",
-                            tree->lvalue.str ? "_" : "",
-                            tree->lvalue.str ? tree->lvalue.str : "",
-                            tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_STARTS_WITH ? "%%" : "",
-                            tree->value.str,
-                            tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_ENDS_WITH ? "%%" : "" );
-                    if( *ppsz_where == NULL )
-                        goto parsefail;
-                    *pppsz_frompersons = realloc( *pppsz_frompersons,
-                            ++*i_frompersons * sizeof( char* ) );
-                    *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str;
-                    *join |= table_people;
-                    break;
-                case ML_PEOPLE_ID:
-                    assert( tree->comp == ML_COMP_EQUAL );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql,
-                                "( people%s%s.id = %d )", tree->lvalue.str ? "_":"",
-                                tree->lvalue.str ? tree->lvalue.str:"",
-                                tree->value.i );
-                    if( *ppsz_where == NULL )
-                        goto parsefail;
-                    *pppsz_frompersons = realloc( *pppsz_frompersons,
-                            ++*i_frompersons * sizeof( char* ) );
-                    *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str;
-                    *join |= table_people;
-                    break;
-                case ML_PEOPLE_ROLE:
-                    assert( tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_EQUAL
-                            || tree->comp == ML_COMP_STARTS_WITH
-                            || tree->comp == ML_COMP_ENDS_WITH );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql,
-                            "people%s%s.role LIKE '%s%q%s'",
-                            tree->lvalue.str ? "_" : "",
-                            tree->lvalue.str ? tree->lvalue.str : "",
-                            tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_STARTS_WITH ? "%%" : "",
-                            tree->value.str,
-                            tree->comp == ML_COMP_HAS
-                            || tree->comp == ML_COMP_ENDS_WITH ? "%%" : "" );
-                    if( *ppsz_where == NULL )
-                        goto parsefail;
-                    *pppsz_frompersons = realloc( *pppsz_frompersons,
-                            ++*i_frompersons * sizeof( char* ) );
-                    *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str;
-                    *join |= table_people;
-                    break;
-                CASE_PSZ( ML_ALBUM, "album.title", table_album );
-                CASE_PSZ( ML_ALBUM_COVER, "album.cover", table_album );
-                case ML_ALBUM_ID:
-                    assert( tree->comp == ML_COMP_EQUAL );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql,
-                            "album.id = %d", tree->value.i );
-                    if( *ppsz_where == NULL )
-                        goto parsefail;
-                    *join |= table_album;
-                    break;
-                CASE_PSZ( ML_COMMENT, "media.comment", table_media );
-                CASE_PSZ( ML_COVER, "media.cover", table_media );
-                CASE_INT( ML_DURATION, "media.duration", table_media );
-                CASE_PSZ( ML_EXTRA, "extra.extra", table_extra );
-                CASE_INT( ML_FILESIZE, "media.filesize", table_media );
-                CASE_PSZ( ML_GENRE, "media.genre", table_media );
-                case ML_ID:
-                    assert( tree->comp == ML_COMP_EQUAL );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql,
-                            "media.id = %d", tree->value.i );
-                    if( *ppsz_where == NULL )
-                        goto parsefail;
-                    *join |= table_media;
-                    break;
-                CASE_PSZ( ML_LANGUAGE, "extra.language", table_extra );
-                CASE_INT( ML_LAST_PLAYED, "media.last_played", table_media );
-                CASE_PSZ( ML_ORIGINAL_TITLE, "media.original_title", table_media );
-                   msg_Warn( p_ml, "Deprecated Played Count tags" );
-                CASE_INT( ML_PLAYED_COUNT, "media.played_count", table_media );
-                CASE_INT( ML_SCORE, "media.score", table_media );
-                CASE_PSZ( ML_TITLE, "media.title", table_media );
-                CASE_INT( ML_TRACK_NUMBER, "media.track", table_media);
-                CASE_INT( ML_TYPE, "media.type", table_media );
-                CASE_PSZ( ML_URI, "media.uri", table_media );
-                CASE_INT( ML_VOTE, "media.vote", table_media );
-                CASE_INT( ML_YEAR, "media.year", table_media );
-                case ML_LIMIT:
-                    if( !*limit )
-                        *limit = tree->value.i;
-                    else
-                        msg_Warn( p_ml, "Double LIMIT found" );
-                    break;
-                case ML_SORT_DESC:
-                    *sort = sql_Printf( p_ml->p_sys->p_sql, "%s%s%s DESC ",
-                                        sort ? *sort : "", sort ? ", " : "",
-                                        tree->value.str );
-                    if( *sort == NULL )
-                        goto parsefail;
-                    break;
-                case ML_SORT_ASC:
-                    *sort = sql_Printf( p_ml->p_sys->p_sql, "%s%s%s ASC ",
-                                        sort ? *sort : "", sort ? ", " : "",
-                                        tree->value.str );
-                    if( *sort == NULL )
-                        goto parsefail;
-                    break;
-                case ML_DISTINCT:
-                    if( !**distinct )
-                        *distinct = "DISTINCT";
-                    else
-                        msg_Warn( p_ml, "Double DISTINCT found!" );
-                    break;
-                default:
-                    msg_Err( p_ml, "Invalid select type or unsupported: %d", tree->criteria );
-            }
-            break;
-        default:
-            msg_Err( p_ml, "Broken find tree!" );
-            i_ret = VLC_EGENERIC;
-            goto parsefail;
-    }
-
-    i_ret = VLC_SUCCESS;
-parsefail:
-    free( psz_left );
-    free( psz_right );
-    return i_ret;
-}
-
-
-#   undef CASE_INT
-#   undef CASE_PSZ
-
-#   undef table_media
-#   undef table_album
-#   undef table_people
-#   undef table_extra
diff --git a/modules/media_library/sql_update.c b/modules/media_library/sql_update.c
deleted file mode 100644 (file)
index b75f919..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/*****************************************************************************
- * sql_update.c: SQL-based media library: all database update functions
- *****************************************************************************
- * Copyright (C) 2008-2010 the VideoLAN team and AUTHORS
- * $Id$
- *
- * Authors: Antoine Lejeune <phytos@videolan.org>
- *          Jean-Philippe André <jpeg@videolan.org>
- *          Rémi Duraffort <ivoire@videolan.org>
- *          Adrien Maglo <magsoft@videolan.org>
- *          Srikanth Raju <srikiraju at gmail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "sql_media_library.h"
-
-
-/**
- * @brief Generic update in Media Library database
- *
- * @param p_ml the media library object
- * @param selected_type the type of the element we're selecting
- * @param where the list of ids or uri to change
- * @param changes list of changes to make in the entries
- * @return VLC_SUCCESS or VLC_EGENERIC
- * @note This function is transactional
- */
-int Update( media_library_t *p_ml, ml_select_e selected_type,
-        const char* psz_lvalue, ml_ftree_t *where, vlc_array_t *changes )
-{
-    int i_ret = VLC_EGENERIC;
-    char *psz_query = NULL;
-    char *psz_id_query = NULL;
-    char **pp_results = NULL;
-    int i_rows = 0, i_cols = 0;
-
-    i_ret = BuildUpdate( p_ml, &psz_query, &psz_id_query,
-                         psz_lvalue, selected_type, where, changes );
-
-    if( i_ret != VLC_SUCCESS )
-    {
-        msg_Err(p_ml,"Failed to generate update query" );
-        return i_ret;
-    }
-    i_ret = VLC_EGENERIC;
-
-    Begin( p_ml );
-    if( QuerySimple( p_ml, "%s", psz_query ) != VLC_SUCCESS )
-    {
-        msg_Err( p_ml, "Couldn't run the generated update query successfully" );
-        goto quitdelete;
-    }
-
-    /* Get the updated IDs to send events! */
-    if( Query( p_ml, &pp_results, &i_rows, &i_cols, psz_id_query )
-            != VLC_SUCCESS )
-        goto quitdelete;
-
-    i_ret = VLC_SUCCESS;
-quitdelete:
-    if( i_ret != VLC_SUCCESS )
-        Rollback( p_ml );
-    else
-    {
-        Commit( p_ml );
-        if( i_rows > 0 )
-        {
-            for( int i = 0; i < i_rows; i++ )
-            {
-                var_SetInteger( p_ml, "media-meta-change",
-                        atoi( pp_results[i*i_cols] ) );
-            }
-        }
-    }
-    FreeSQLResult( p_ml, pp_results );
-    free( psz_id_query );
-    free( psz_query );
-    return i_ret;
-}
-
-#define SET_STR( a )                                                        \
-if( !psz_set[i_type] )                                                      \
-{                                                                           \
-    psz_set[i_type] = sql_Printf( p_ml->p_sys->p_sql, a, find->value.str ); \
-    if( !psz_set[i_type] )                                                  \
-        goto quit_buildupdate;                                              \
-}                                                                           \
-break;
-
-#define SET_INT( a )                                                        \
-if( !psz_set[i_type] )                                                      \
-{                                                                           \
-    psz_set[i_type] = sql_Printf( p_ml->p_sys->p_sql, a, find->value.i );   \
-    if( !psz_set[i_type] )                                                  \
-        goto quit_buildupdate;                                              \
-}                                                                           \
-break;
-
-/* TODO: Build smarter updates by using IN () */
-static int BuildWhere( media_library_t* p_ml, char **ppsz_where, ml_ftree_t *tree )
-{
-    assert( ppsz_where );
-    char* psz_left = NULL;
-    char* psz_right = NULL;
-    int i_ret = VLC_SUCCESS;
-    switch( tree->op )
-    {
-        case ML_OP_AND:
-        case ML_OP_OR:
-            i_ret = BuildWhere( p_ml, &psz_left, tree->left );
-            if( i_ret != VLC_SUCCESS )
-                goto quit_buildwhere;
-            i_ret = BuildWhere( p_ml, &psz_right, tree->right );
-            if( i_ret != VLC_SUCCESS )
-                goto quit_buildwhere;
-            if( psz_left == NULL || psz_right == NULL )
-            {
-                msg_Err( p_ml, "Couldn't build AND/OR for Update statement" );
-                i_ret = VLC_EGENERIC;
-                goto quit_buildwhere;
-            }
-            if( asprintf( ppsz_where, "( %s %s %s )", psz_left,
-                ( tree->op == ML_OP_AND ? "AND" : "OR" ), psz_right ) == -1 )
-            {
-                i_ret = VLC_ENOMEM;
-                goto quit_buildwhere;
-            }
-            break;
-        case ML_OP_NOT:
-            i_ret = BuildWhere( p_ml, &psz_left, tree->left );
-            if( i_ret != VLC_SUCCESS )
-                goto quit_buildwhere;
-            if( psz_left == NULL )
-            {
-                msg_Err( p_ml, "Couldn't build NOT for Update statement" );
-                i_ret = VLC_EGENERIC;
-                goto quit_buildwhere;
-            }
-            if( asprintf( ppsz_where, "( NOT %s )", psz_left ) == -1 )
-            {
-                i_ret = VLC_ENOMEM;
-                goto quit_buildwhere;
-            }
-            break;
-        case ML_OP_SPECIAL:
-            msg_Err( p_ml, "Couldn't build special for Update statement" );
-            break;
-        case ML_OP_NONE:
-            switch( tree->criteria )
-            {
-                case ML_ID:
-                    assert( tree->comp == ML_COMP_EQUAL );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "media.id = %d",
-                                                tree->value.i );
-                    if( *ppsz_where == NULL )
-                        goto quit_buildwhere;
-                    break;
-                case ML_URI:
-                    assert( tree->comp == ML_COMP_EQUAL );
-                    *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "media.uri = %q",
-                                                tree->value.str );
-                    if( *ppsz_where == NULL )
-                        goto quit_buildwhere;
-                    break;
-                default:
-                    msg_Err( p_ml, "Trying to update with unsupported condition" );
-                    break;
-            }
-    }
-quit_buildwhere:
-    return i_ret;
-}
-
-/**
- * @brief Generic UPDATE query builder
- *
- * @param p_ml This media_library_t object
- * @param ppsz_query *ppsz_query will contain query for update
- * @param ppsz_id_query will contain query to get the ids of updated files
- * @param selected_type the type of the element we're selecting
- * @param where parse tree of where condition
- * @param changes list of changes to make in the entries
- * @return VLC_SUCCESS or VLC_EGENERIC
- */
-int BuildUpdate( media_library_t *p_ml,
-                 char **ppsz_query, char **ppsz_id_query,
-                 const char *psz_lvalue,
-                 ml_select_e selected_type,
-                 ml_ftree_t *where, vlc_array_t *changes )
-{
-    assert( ppsz_query );
-    assert( ppsz_id_query );
-
-    *ppsz_query = NULL;
-    int i_type;
-    int i_index;
-    int i_ret = VLC_ENOMEM;
-
-    char *psz_table = NULL;
-    /* TODO: Hack? */
-    char *psz_set[ ML_DIRECTORY + 1 ] = { NULL };
-    char *psz_fullset = NULL;
-    char *psz_extra = NULL; /*<< For an update to extra table */
-
-    char *psz_where = NULL;
-    char *psz_tmp = NULL;
-
-    int *pi_padd_ids = NULL;
-    int i_people_add = 0;
-
-    int i_album_id = 0;
-    char *psz_album = NULL;
-    char *psz_cover = NULL;
-
-
-    if( !where )
-    {
-        msg_Warn( p_ml, "You're trying to update no rows."
-               "Trying to guess update based on uri" );
-    }
-
-    /* Create the id/uri lists for WHERE part of the query */
-    i_ret = BuildWhere( p_ml, &psz_where, where );
-    if( i_ret != VLC_SUCCESS )
-        goto quit_buildupdate;
-    i_ret = VLC_ENOMEM;
-
-    /** Firstly, choose the right table */
-    switch( selected_type )
-    {
-        case ML_ALBUM:
-            psz_table = strdup( "album" );
-            break;
-        case ML_PEOPLE:
-            psz_table = strdup( "people" );
-            break;
-        case ML_MEDIA:
-            psz_table = strdup( "media" );
-            break;
-        default:
-            msg_Err( p_ml, "Not a valid element to Update!" );
-            i_ret = VLC_EGENERIC;
-            goto quit_buildupdate;
-            break;
-    }
-
-    if( !psz_table )
-        return VLC_ENOMEM;
-
-    /** Secondly, build the SET part of the query */
-    for( i_index = 0; i_index < vlc_array_count( changes ); i_index++ )
-    {
-        ml_element_t *find = ( ml_element_t * )
-                vlc_array_item_at_index( changes, i_index );
-        i_type = find->criteria;
-
-        switch( i_type )
-        {
-        case ML_ALBUM:
-            if( selected_type == ML_ALBUM )
-            {
-                if( !psz_set[i_type] )
-                {
-                    psz_set[i_type] = sql_Printf( p_ml->p_sys->p_sql,
-                                                  "title = %Q",
-                                                  find->value.str );
-                    if( !psz_set[i_type] )
-                    {
-                        msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                                __FILE__, __LINE__ );
-                        goto quit_buildupdate;
-                    }
-                }
-            }
-            else if( selected_type == ML_MEDIA )
-            {
-                if( !psz_album )
-                    psz_album = find->value.str;
-            }
-            else
-                assert( 0 );
-            break;
-        case ML_ALBUM_ID:
-            assert( selected_type != ML_ALBUM );
-            if( selected_type == ML_MEDIA )
-            {
-                if( i_album_id <= 0 )
-                {
-                    i_album_id = find->value.i;
-                    if( !psz_set[i_type] )
-                    {
-                        psz_set[i_type] = sql_Printf( p_ml->p_sys->p_sql,
-                                                      "album_id = '%d'",
-                                                      find->value.i );
-                        if( !psz_set[i_type] )
-                        {
-                            msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                                __FILE__, __LINE__ );
-                            goto quit_buildupdate;
-                        }
-                    }
-                }
-            }
-            break;
-        case ML_PEOPLE:
-            if( selected_type == ML_MEDIA )
-            {
-                pi_padd_ids = (int*) realloc( pi_padd_ids , ( ++i_people_add * sizeof(int) ) );
-                pi_padd_ids[ i_people_add - 1 ] = ml_GetInt( p_ml, ML_PEOPLE_ID,
-                                            find->lvalue.str, ML_PEOPLE, find->lvalue.str,
-                                            find->value.str );
-                if( pi_padd_ids[ i_people_add - 1 ] <= 0 )
-                {
-                    AddPeople( p_ml, find->value.str, find->lvalue.str );
-                    pi_padd_ids[ i_people_add - 1 ] = ml_GetInt( p_ml, ML_PEOPLE_ID,
-                                            find->lvalue.str, ML_PEOPLE, find->lvalue.str,
-                                            find->value.str );
-                }
-            }
-            else if( strcmp( psz_lvalue, find->lvalue.str ) )
-            {
-                msg_Err( p_ml, "Trying to update a different person type" );
-                return VLC_EGENERIC;
-            }
-            else
-            {
-                if( !psz_set[i_type] ) psz_set[i_type] =
-                    sql_Printf( p_ml->p_sys->p_sql, "name = %Q", find->value.str );
-            }
-            break;
-        case ML_PEOPLE_ID:
-            /* TODO: Implement smarter updates for this case? */
-            assert( selected_type == ML_MEDIA );
-            if( selected_type == ML_MEDIA )
-            {
-                bool b_update = true;
-                for( int i = 0; i < i_people_add; i++ )
-                {
-                   if( pi_padd_ids[ i ] == find->value.i )
-                   {
-                      b_update = false;
-                      break;
-                   }
-                }
-                if( b_update )
-                {
-                    pi_padd_ids = (int *)realloc( pi_padd_ids, ( ++i_people_add * sizeof(int) ) );
-                    pi_padd_ids[ i_people_add - 1 ] = find->value.i;
-                }
-            }
-            break;
-        case ML_PEOPLE_ROLE:
-            msg_Dbg( p_ml, "Can't update role" );
-            break;
-        case ML_COMMENT:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "comment = %Q" );
-        case ML_COVER:
-            assert( selected_type == ML_ALBUM || selected_type == ML_MEDIA );
-            psz_cover = find->value.str;
-            SET_STR( "cover = %Q" );
-        case ML_DISC_NUMBER:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "disc = '%d'" );
-        case ML_DURATION:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "duration = '%d'" );
-        case ML_EXTRA:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "extra = %Q" );
-        case ML_FIRST_PLAYED:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "first_played =='%d'" );
-        case ML_GENRE:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "genre = %Q" );
-        /* ID cannot be updated */
-        /* Import time can't be updated */
-        case ML_LAST_PLAYED:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "last_played = '%d'" );
-        case ML_ORIGINAL_TITLE:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "original_title = %Q" );
-        case ML_PLAYED_COUNT:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "played_count = '%d'" );
-        case ML_PREVIEW:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "preview = %Q" );
-        case ML_SKIPPED_COUNT:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "skipped_count = '%d'" );
-        case ML_SCORE:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "score = '%d'" );
-        case ML_TITLE:
-            assert( selected_type == ML_MEDIA );
-            SET_STR( "title = %Q" );
-        case ML_TRACK_NUMBER:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "track = '%d'" );
-        case ML_TYPE:
-            assert( selected_type == ML_MEDIA );
-            if( !psz_set[i_type] ) psz_set[i_type] =
-                sql_Printf( p_ml->p_sys->p_sql, "type = '%d'", find->value.i );
-            break;
-        case ML_URI:
-            assert( selected_type == ML_MEDIA );
-            if( !psz_set[i_type] )
-            {
-                psz_set[i_type] = sql_Printf( p_ml->p_sys->p_sql,
-                                              "uri = %Q",
-                                              find->value.str );
-            }
-            break;
-        case ML_VOTE:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "vote = '%d'" );
-        case ML_YEAR:
-            assert( selected_type == ML_MEDIA );
-            SET_INT( "year = '%d'" );
-        case ML_END:
-            goto exitfor;
-        default:
-            msg_Warn( p_ml, "Invalid type for update : %d", i_type );
-        }
-    }
-exitfor:
-
-    /* TODO: Album artist. Verify albumart */
-    if( i_album_id <= 0 && psz_album )
-    {
-        i_album_id = ml_GetAlbumId( p_ml, psz_album );
-        if( i_album_id < 0 ) //0 is Unknown
-        {
-            i_ret = AddAlbum( p_ml, psz_album, psz_cover, 0 );
-            if( i_ret != VLC_SUCCESS )
-            {
-
-                msg_Err( p_ml, "Couldn't AddAlbum at BuildUpdate():(%s, %d)",
-                        __FILE__, __LINE__ );
-                goto quit_buildupdate;
-            }
-            i_album_id = ml_GetAlbumId( p_ml, psz_album );
-            if( i_album_id < 0 )
-                goto quit_buildupdate;
-        }
-        psz_set[ML_ALBUM_ID] = sql_Printf( p_ml->p_sys->p_sql,
-                                      "album_id = '%d'", i_album_id );
-        if( !psz_set[ML_ALBUM_ID] )
-        {
-            msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                    __FILE__, __LINE__ );
-            goto quit_buildupdate;
-        }
-    }
-
-    for( unsigned i = 0; i <= ML_DIRECTORY; i++ )
-    {
-        if( psz_set[i] )
-        {
-            if( i == ML_EXTRA || i == ML_LANGUAGE )
-            {
-                free( psz_tmp );
-                if( asprintf( &psz_tmp, "%s%s%s", psz_extra ? psz_extra : "",
-                               psz_extra ? ", ": "",  psz_set[i] ) == -1 )
-                {
-                    msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                            __FILE__, __LINE__ );
-                    goto quit_buildupdate;
-                }
-                free( psz_extra );
-                psz_extra = strdup( psz_tmp );
-            }
-            else
-            {
-                free( psz_tmp );
-                if( asprintf( &psz_tmp, "%s%s%s", psz_fullset ? psz_fullset : "",
-                               psz_fullset ? ", ": "",  psz_set[i] ) == -1 )
-                {
-                    msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                            __FILE__, __LINE__ );
-                    goto quit_buildupdate;
-                }
-                free( psz_fullset );
-                psz_fullset = strdup( psz_tmp );
-            }
-        }
-    }
-    i_ret = VLC_SUCCESS;
-
-    /** Now build the right WHERE condition */
-    assert( psz_where && *psz_where );
-
-    /** Finally build the full query */
-    /** Pass if we have some people to add - Indirect update */
-    if( !psz_fullset && i_people_add == 0 )
-    {
-        i_ret = VLC_EGENERIC;
-        msg_Err( p_ml, "Nothing found to create update at BuildUpdate():(%s, %d)",
-                        __FILE__, __LINE__ );
-        goto quit_buildupdate;
-    }
-
-    if( psz_fullset ){
-        if( asprintf( ppsz_query, "UPDATE %s SET %s WHERE %s", psz_table,
-                      psz_fullset, psz_where ) == -1 )
-        {
-            msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                            __FILE__, __LINE__ );
-            goto quit_buildupdate;
-        }
-    }
-
-    if( selected_type == ML_MEDIA )
-    {
-        if( psz_extra )
-        {
-            if( asprintf( &psz_tmp, "%s; UPDATE extra SET %s WHERE %s",
-                        *ppsz_query, psz_extra, psz_where ) == -1 )
-            {
-                msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                            __FILE__, __LINE__ );
-                goto quit_buildupdate;
-            }
-            free( *ppsz_query );
-            *ppsz_query = psz_tmp;
-            psz_tmp = NULL;
-        }
-        char* psz_idstring = NULL;
-        if( i_people_add > 0 )
-        {
-            for( int i = 0; i < i_people_add; i++ )
-            {
-                if( asprintf( &psz_tmp, "%s%s%d", psz_idstring == NULL? "" : psz_idstring,
-                            psz_idstring == NULL ? "" : ",", pi_padd_ids[i] ) == -1 )
-                {
-                    free( psz_tmp );
-                    free( psz_idstring );
-                    msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                            __FILE__, __LINE__ );
-                    goto quit_buildupdate;
-                }
-                free( psz_idstring );
-                psz_idstring = psz_tmp;
-                psz_tmp = NULL;
-            }
-            /* Delete all connections with people whom we will update now! */
-            if( asprintf( &psz_tmp, "%s;DELETE FROM media_to_people WHERE EXISTS "
-                    "(SELECT media.id, people.id FROM media JOIN media_to_people "
-                    "AS temp ON media.id = temp.media_id "
-                    "JOIN people ON temp.people_id = people.id "
-                    "WHERE %s AND people.role IN "
-                    "(SELECT people.role FROM people WHERE people.id IN (%s)) "
-                    "AND people.id NOT IN (%s) "
-                    "AND temp.media_id = media_to_people.media_id AND "
-                    "temp.people_id = media_to_people.people_id )",
-                    *ppsz_query == NULL ? "": *ppsz_query, psz_where,
-                    psz_idstring, psz_idstring ) == -1 )
-            {
-                free( psz_idstring );
-                msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                                __FILE__, __LINE__ );
-                goto quit_buildupdate;
-            }
-            free( *ppsz_query );
-            *ppsz_query = psz_tmp;
-            psz_tmp = NULL;
-            free( psz_idstring );
-        }
-        for( int i = 0; i < i_people_add ; i++ )
-        {
-            if( pi_padd_ids[i] > 0 )
-            {
-                /* OR IGNORE will avoid errors from collisions from old media
-                 * Perhaps this hack can be fixed...FIXME */
-                if( asprintf( &psz_tmp, "%s;INSERT OR IGNORE into media_to_people "
-                "(media_id,people_id) SELECT media.id, %d FROM media WHERE %s",
-                *ppsz_query == NULL ? "" : *ppsz_query, pi_padd_ids[i],
-                psz_where ) == -1 )
-                {
-                    msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                                    __FILE__, __LINE__ );
-                    goto quit_buildupdate;
-                }
-                FREENULL( *ppsz_query );
-                *ppsz_query = psz_tmp;
-                psz_tmp = NULL;
-            }
-        }
-    }
-
-    if( asprintf( ppsz_id_query, "SELECT id AS %s_id FROM %s WHERE %s",
-                psz_table, psz_table, psz_where ) == -1 )
-    {
-        msg_Err( p_ml, "Couldn't create string at BuildUpdate():(%s, %d)",
-                        __FILE__, __LINE__ );
-        goto quit_buildupdate;
-    }
-#ifndef NDEBUG
-    msg_Dbg( p_ml, "updated media where %s", psz_where );
-#endif
-    goto quit_buildupdate_success;
-
-quit_buildupdate:
-    msg_Warn( p_ml, "BuildUpdate() could not generate update sql query" );
-quit_buildupdate_success:
-    free( psz_tmp );
-    free( psz_table );
-    free( psz_fullset );
-    free( psz_extra );
-    free( pi_padd_ids );
-    for( int i = 0; i <= ML_DIRECTORY; i++ )
-        free( psz_set[ i ] );
-
-    return i_ret;
-}
-
-#undef SET_STR
-#undef SET_INT
-
-/**
- * @brief Update a ml_media_t
- *
- * @param p_ml the media library object
- * @param p_media media to synchronise in the database
- * @return VLC_SUCCESS or VLC_EGENERIC
- * @note: the media id may be 0, in this case, the update is based
- *        on the url (less powerful). This function is threadsafe
- *
- * This synchronises all non NULL and non zero fields of p_media
- * Synchronization of album and people is TODO
- */
-int UpdateMedia( media_library_t *p_ml, ml_media_t *p_media )
-{
-    assert( p_media->i_id || ( p_media->psz_uri && *p_media->psz_uri ) );
-    vlc_array_t *changes = vlc_array_new();
-    ml_element_t *find = NULL;
-    int i_ret = VLC_EGENERIC;
-
-    ml_LockMedia( p_media );
-#define APPEND_ICHANGES( cond, crit ) \
-    if( cond ) { \
-        find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) ); \
-        find->criteria = crit; \
-        find->value.i = cond; \
-        vlc_array_append( changes, find ); \
-    }
-#define APPEND_SCHANGES( cond, crit ) \
-    if( cond ) { \
-        find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) ); \
-        find->criteria = crit; \
-        find->value.str = cond; \
-        vlc_array_append( changes, find ); \
-    }
-
-    APPEND_SCHANGES( p_media->psz_title, ML_TITLE );
-    APPEND_ICHANGES( p_media->i_type, ML_TYPE );
-    APPEND_ICHANGES( p_media->i_duration, ML_DURATION );
-    APPEND_SCHANGES( p_media->psz_preview, ML_PREVIEW );
-    APPEND_SCHANGES( p_media->psz_cover, ML_COVER );
-    APPEND_ICHANGES( p_media->i_disc_number, ML_DISC_NUMBER );
-    APPEND_ICHANGES( p_media->i_track_number, ML_TRACK_NUMBER );
-    APPEND_ICHANGES( p_media->i_year, ML_YEAR);
-    APPEND_SCHANGES( p_media->psz_genre, ML_GENRE );
-    APPEND_ICHANGES( p_media->i_album_id, ML_ALBUM_ID );
-    APPEND_SCHANGES( p_media->psz_album, ML_ALBUM );
-    APPEND_ICHANGES( p_media->i_skipped_count, ML_SKIPPED_COUNT );
-    APPEND_ICHANGES( p_media->i_last_skipped, ML_LAST_SKIPPED );
-    APPEND_ICHANGES( p_media->i_played_count, ML_PLAYED_COUNT );
-    APPEND_ICHANGES( p_media->i_last_played, ML_LAST_PLAYED );
-    APPEND_ICHANGES( p_media->i_first_played, ML_FIRST_PLAYED );
-    APPEND_ICHANGES( p_media->i_vote, ML_VOTE );
-    APPEND_ICHANGES( p_media->i_score, ML_SCORE );
-    APPEND_SCHANGES( p_media->psz_comment, ML_COMMENT );
-    APPEND_SCHANGES( p_media->psz_extra, ML_EXTRA );
-    APPEND_SCHANGES( p_media->psz_language, ML_LANGUAGE );
-
-    if( p_media->psz_uri && p_media->i_id )
-    {
-        find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) );
-        find->criteria = ML_URI;
-        find->value.str = p_media->psz_uri;
-        vlc_array_append( changes, find );
-    }
-    /*TODO: implement extended meta */
-    /* We're not taking import time! Good */
-
-#undef APPEND_ICHANGES
-#undef APPEND_SCHANGES
-    ml_person_t* person = p_media->p_people;
-    while( person )
-    {
-        if( person->i_id > 0 )
-        {
-            find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) );
-            find->criteria = ML_PEOPLE_ID;
-            find->lvalue.str = person->psz_role;
-            find->value.i = person->i_id;
-            vlc_array_append( changes, find );
-        }
-        else if( person->psz_name && *person->psz_name )
-        {
-            find = ( ml_element_t* ) calloc( 1, sizeof( ml_element_t ) );
-            find->criteria = ML_PEOPLE;
-            find->lvalue.str = person->psz_role;
-            find->value.str = person->psz_name;
-            vlc_array_append( changes, find );
-        }
-        person = person->p_next;
-    }
-
-    ml_ftree_t* p_where = NULL;
-    ml_ftree_t* p_where_elt = ( ml_ftree_t* ) calloc( 1, sizeof( ml_ftree_t ) );
-    if( p_media->i_id )
-    {
-        p_where_elt->criteria = ML_ID;
-        p_where_elt->value.i = p_media->i_id ;
-        p_where_elt->comp = ML_COMP_EQUAL;
-        p_where = ml_FtreeFastAnd( p_where, p_where_elt );
-    }
-    else if( p_media->psz_uri )
-    {
-        p_where_elt->criteria = ML_URI;
-        p_where_elt->value.str = p_media->psz_uri;
-        p_where_elt->comp = ML_COMP_EQUAL;
-        p_where = ml_FtreeFastAnd( p_where, p_where_elt );
-    }
-    else
-    {
-        goto quit1;
-    }
-    i_ret = Update( p_ml, ML_MEDIA, NULL, p_where, changes );
-
-quit1:
-    ml_FreeFindTree( p_where );
-    for( int i = 0; i < vlc_array_count( changes ); i++ )
-        /* Note: DO NOT free the strings because
-         * they belong to the ml_media_t object */
-        free( vlc_array_item_at_index( changes, i ) );
-    vlc_array_destroy( changes );
-    ml_UnlockMedia( p_media );
-    return i_ret;
-}
-
-/**
- * @brief Update an album's cover art
- * @param p_ml The Media Library
- * @param i_album_id Album's ID
- * @param psz_cover New cover art
- * @return VLC success/error code
- **/
-int SetArtCover( media_library_t *p_ml,
-                   int i_album_id, const char *psz_cover )
-{
-    assert( i_album_id != 0 );
-    assert( psz_cover != NULL );
-
-    char *psz_query = sql_Printf( p_ml->p_sys->p_sql,
-              "UPDATE album SET cover = %Q WHERE id = '%d'",
-              psz_cover, i_album_id );
-
-    if( !psz_query )
-        return VLC_ENOMEM;
-
-    if( QuerySimple( p_ml, "%s", psz_query ) != VLC_SUCCESS )
-    {
-        msg_Warn( p_ml, "Could not update the album's cover art "
-                "(Database error)" );
-        free( psz_query );
-        return VLC_EGENERIC;
-    }
-
-    free( psz_query );
-    return VLC_SUCCESS;
-}
index ce6c1f3686f6edd44e06498b3fea259d668bda78..2563a8d463fc790ff34599cd166d9c8b0a80ae1e 100644 (file)
@@ -935,7 +935,6 @@ modules/lua/libs/volume.c
 modules/lua/meta.c
 modules/lua/vlc.c
 modules/lua/vlc.h
-modules/media_library/sql_media_library.c
 modules/meta_engine/folder.c
 modules/meta_engine/taglib.cpp
 modules/misc/audioscrobbler.c