示例#1
0
/**
 * @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;
}
示例#2
0
文件: sql_search.c 项目: Mettbrot/vlc
/**
 * @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;
}