Prima di tutto, non è chiaro dalla descrizione di ciò che hai fatto, ma hai bisogno di una PlaylistSongs
tabella che contenga a PlaylistId
e a SongId
, che descriva quali canzoni appartengono a quali playlist.
È in questa tabella che è necessario aggiungere le informazioni di ordinazione.
Il mio meccanismo preferito è con numeri reali. L'ho implementato di recente e ha funzionato come un fascino. Quando si desidera spostare un brano in una posizione specifica, si calcola il suo nuovo Ordering
valore come media dei Ordering
valori del brano precedente e del brano successivo. Se si utilizza un numero reale a 64 bit, si esaurirà la precisione all'incirca nello stesso momento in cui l'inferno si bloccherà, ma se si sta davvero scrivendo il proprio software per i posteri, quindi considerare di riassegnare dei bei Ordering
valori interi arrotondati a tutti i brani in ciascuno playlist ogni tanto.
Come bonus aggiuntivo, ecco il codice che ho scritto che lo implementa. Ovviamente non puoi usarlo così com'è, e sarebbe troppo lavoro per me in questo momento disinfettarlo per te, quindi lo sto solo postando per te per trarne idee.
La classe è ParameterTemplate
(qualunque cosa, non chiedere!) Il metodo ottiene l'elenco dei modelli di parametri a cui questo modello appartiene dal suo genitore ActivityTemplate
. (Qualunque cosa, non chiedere!) Il codice contiene un po 'di protezione contro la mancanza di precisione. Il divisore viene utilizzato per i test: il test unitario utilizza un divisore di grandi dimensioni in modo da esaurire rapidamente la precisione e quindi attivare il codice di protezione di precisione. Il secondo metodo è pubblico e "solo per uso interno; non invocare" in modo che il codice di test possa invocarlo. (Non potrebbe essere un pacchetto privato perché il mio codice di test non si trova nello stesso pacchetto del codice che verifica.) Il campo che controlla l'ordinamento viene chiamatoOrdering
, accessibile tramite getOrdering()
e setOrdering()
. Non vedi alcun SQL perché sto usando la mappatura relazionale degli oggetti tramite Hibernate.
/**
* Moves this {@link ParameterTemplate} to the given index in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* The index must be greater than or equal to zero, and less than or equal to the number of entries in the list. Specifying an index of zero will move this item to the top of
* the list. Specifying an index which is equal to the number of entries will move this item to the end of the list. Any other index will move this item to the position
* specified, also moving other items in the list as necessary. The given index cannot be equal to the current index of the item, nor can it be equal to the current index plus
* one. If the given index is below the current index of the item, then the item will be moved so that its new index will be equal to the given index. If the given index is
* above the current index, then the new index of the item will be the given index minus one.
*
* NOTE: this method flushes the persistor and refreshes the parent node so as to guarantee that the changes will be immediately visible in the list of {@link
* ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* @param toIndex the desired new index of this {@link ParameterTemplate} in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*/
public void moveAt( int toIndex )
{
moveAt( toIndex, 2.0 );
}
/**
* For internal use only; do not invoke.
*/
public boolean moveAt( int toIndex, double divisor )
{
MutableList<ParameterTemplate<?>> parameterTemplates = getLogicDomain().getMutableCollections().newArrayList();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
assert parameterTemplates.getLength() >= 1; //guaranteed since at the very least, this parameter template must be in the list.
int fromIndex = parameterTemplates.indexOf( this );
assert 0 <= toIndex;
assert toIndex <= parameterTemplates.getLength();
assert 0 <= fromIndex;
assert fromIndex < parameterTemplates.getLength();
assert fromIndex != toIndex;
assert fromIndex != toIndex - 1;
double order;
if( toIndex == 0 )
{
order = parameterTemplates.fetchFirstElement().getOrdering() - 1.0;
}
else if( toIndex == parameterTemplates.getLength() )
{
order = parameterTemplates.fetchLastElement().getOrdering() + 1.0;
}
else
{
double prevOrder = parameterTemplates.get( toIndex - 1 ).getOrdering();
parameterTemplates.moveAt( fromIndex, toIndex );
double nextOrder = parameterTemplates.get( toIndex + (toIndex > fromIndex ? 0 : 1) ).getOrdering();
assert prevOrder <= nextOrder;
order = (prevOrder + nextOrder) / divisor;
if( order <= prevOrder || order >= nextOrder ) //if the accuracy of the double has been exceeded
{
parameterTemplates.clear();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
for( int i = 0; i < parameterTemplates.getLength(); i++ )
parameterTemplates.get( i ).setOrdering( i * 1.0 );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
moveAt( toIndex );
return true;
}
}
setOrdering( order );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
assert getParentActivityTemplate().getParameterTemplates().indexOf( this ) == (toIndex > fromIndex ? toIndex - 1 : toIndex);
return false;
}