mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-01 20:00:13 +02:00
add a createdOn property to playlists, and sort sourcetree
This commit is contained in:
11
data/sql/dbmigrate-22_to_23.sql
Normal file
11
data/sql/dbmigrate-22_to_23.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- Script to migate from db version 22 to 23.
|
||||
-- Only change in this version is that playlists gained a createdOn date.
|
||||
-- Set all playlists to created to now.
|
||||
--
|
||||
-- Separate each command with %%
|
||||
|
||||
ALTER TABLE playlist ADD COLUMN createdOn INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE playlist SET createdOn = strftime( '%s','now' );
|
||||
|
||||
UPDATE settings SET v = '23' WHERE k == 'schema_version';
|
@@ -88,5 +88,6 @@
|
||||
<file>./data/www/auth.html</file>
|
||||
<file>./data/www/auth.na.html</file>
|
||||
<file>./data/www/tomahawk_banner_small.png</file>
|
||||
<file>./data/sql/dbmigrate-22_to_23.sql</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -143,11 +143,12 @@ void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const
|
||||
data[1].toString(), //title
|
||||
data[2].toString(), //info
|
||||
data[3].toString(), //creator
|
||||
data[4].toString(), // dynamic type
|
||||
static_cast<GeneratorMode>(data[5].toInt()), // dynamic mode
|
||||
data[6].toBool(), //shared
|
||||
data[7].toInt(), //lastmod
|
||||
data[8].toString() ) ); //GUID
|
||||
data[4].toUInt(), // createdOn
|
||||
data[5].toString(), // dynamic type
|
||||
static_cast<GeneratorMode>(data[6].toInt()), // dynamic mode
|
||||
data[7].toBool(), //shared
|
||||
data[8].toInt(), //lastmod
|
||||
data[9].toString() ) ); //GUID
|
||||
addDynamicPlaylist( p );
|
||||
}
|
||||
|
||||
|
@@ -73,22 +73,6 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
|
||||
cre.addBindValue( m_playlist->mode() );
|
||||
}
|
||||
cre.exec();
|
||||
|
||||
// save the controls -- wait, no controls in a new playlist :P
|
||||
// cre = lib->newquery();
|
||||
// cre.prepare( "INSERT INTO dynamic_playlist_controls( id, selectedType, match, input) "
|
||||
// "VALUES( :id, :selectedType, :match, :input )" );
|
||||
// foreach( const dyncontrol_ptr& control, m_playlist->generator()->controls() ) {
|
||||
//
|
||||
// cre.bindValue( ":id", control->id() );
|
||||
// cre.bindValue( ":selectedType", control->selectedType() );
|
||||
// cre.bindValue( ":match", control->match() );
|
||||
// cre.bindValue( ":input", control->input() );
|
||||
//
|
||||
// qDebug() << "CREATE DYNPLAYLIST CONTROL:" << cre.boundValues();
|
||||
//
|
||||
// cre.exec();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@@ -88,12 +88,16 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
|
||||
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) );
|
||||
Q_ASSERT( !source().isNull() );
|
||||
|
||||
uint now = QDateTime::currentDateTime().toTime_t();
|
||||
m_playlist->setCreatedOn( now );
|
||||
|
||||
TomahawkSqlQuery cre = lib->newquery();
|
||||
cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist) "
|
||||
"VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist )" );
|
||||
cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) "
|
||||
"VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist, :createdOn )" );
|
||||
|
||||
cre.bindValue( ":source", source()->isLocal() ? QVariant(QVariant::Int) : source()->id() );
|
||||
cre.bindValue( ":dynplaylist", dynamic );
|
||||
cre.bindValue( ":createdOn", now );
|
||||
if( !m_playlist.isNull() ) {
|
||||
cre.bindValue( ":guid", m_playlist->guid() );
|
||||
cre.bindValue( ":shared", m_playlist->shared() );
|
||||
|
@@ -30,7 +30,7 @@ void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
|
||||
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
|
||||
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
|
||||
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid" )
|
||||
.arg( source()->isLocal() ? "IS NULL" :
|
||||
QString( "=%1" ).arg( source()->id() )
|
||||
@@ -39,14 +39,15 @@ void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi )
|
||||
QList<dynplaylist_ptr> plists;
|
||||
while ( query.next() )
|
||||
{
|
||||
QVariantList data = QVariantList() << query.value(6).toString() //current rev
|
||||
QVariantList data = QVariantList() << query.value(7).toString() //current rev
|
||||
<< query.value(1).toString() //title
|
||||
<< query.value(2).toString() //info
|
||||
<< query.value(3).toString() //creator
|
||||
<< query.value(7).toString() // dynamic type
|
||||
<< static_cast<GeneratorMode>(query.value(8).toInt()) // dynamic mode
|
||||
<< query.value(5).toBool() //shared
|
||||
<< query.value(4).toInt() //lastmod
|
||||
<< query.value(4).toString() //createdOn
|
||||
<< query.value(8).toString() // dynamic type
|
||||
<< static_cast<GeneratorMode>(query.value(9).toInt()) // dynamic mode
|
||||
<< query.value(6).toBool() //shared
|
||||
<< query.value(5).toInt() //lastmod
|
||||
<< query.value(0).toString(); //GUID
|
||||
emit playlistLoaded( source(), data );
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
|
||||
query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision "
|
||||
query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision, createdOn "
|
||||
"FROM playlist WHERE source %1 AND dynplaylist = 'false'" )
|
||||
.arg( source()->isLocal() ? "IS NULL" :
|
||||
QString( "= %1" ).arg( source()->id() )
|
||||
@@ -44,6 +44,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi )
|
||||
query.value(1).toString(), //title
|
||||
query.value(2).toString(), //info
|
||||
query.value(3).toString(), //creator
|
||||
query.value(7).toInt(), //lastmod
|
||||
query.value(5).toBool(), //shared
|
||||
query.value(4).toInt(), //lastmod
|
||||
query.value(0).toString() //GUID
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "result.h"
|
||||
#include "artist.h"
|
||||
#include "album.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
/* !!!! You need to manually generate schema.sql.h when the schema changes:
|
||||
cd src/libtomahawk/database
|
||||
@@ -37,7 +38,7 @@
|
||||
*/
|
||||
#include "schema.sql.h"
|
||||
|
||||
#define CURRENT_SCHEMA_VERSION 22
|
||||
#define CURRENT_SCHEMA_VERSION 23
|
||||
|
||||
|
||||
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
@@ -69,6 +70,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
qDebug() << endl << "****************************" << endl;
|
||||
qDebug() << "Schema version too old: " << v << ". Current version is:" << CURRENT_SCHEMA_VERSION;
|
||||
qDebug() << "Moving" << dbname << newname;
|
||||
qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname;
|
||||
qDebug() << endl << "****************************" << endl;
|
||||
|
||||
qry.clear();
|
||||
@@ -77,7 +79,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
db.close();
|
||||
db.removeDatabase( "tomahawk" );
|
||||
|
||||
if( QFile::rename( dbname, newname ) )
|
||||
if( QFile::copy( dbname, newname ) )
|
||||
{
|
||||
db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" );
|
||||
db.setDatabaseName( dbname );
|
||||
@@ -87,6 +89,13 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
TomahawkSqlQuery query = newquery();
|
||||
query.exec( "PRAGMA auto_vacuum = FULL" );
|
||||
schemaUpdated = updateSchema( v );
|
||||
|
||||
if( !schemaUpdated )
|
||||
{
|
||||
Q_ASSERT( false );
|
||||
QTimer::singleShot( 0, qApp, SLOT( quit() ) );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -149,9 +158,12 @@ DatabaseImpl::updateSearchIndex()
|
||||
|
||||
|
||||
bool
|
||||
DatabaseImpl::updateSchema( int currentver )
|
||||
DatabaseImpl::updateSchema( int oldVersion )
|
||||
{
|
||||
qDebug() << "Create tables... old version is" << currentver;
|
||||
// we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from t7he oldVersion
|
||||
if ( oldVersion == 0 ) // empty database, so create our tables and stuff
|
||||
{
|
||||
qDebug() << "Create tables... old version is" << oldVersion;
|
||||
QString sql( get_tomahawk_sql() );
|
||||
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
|
||||
db.transaction();
|
||||
@@ -169,6 +181,47 @@ DatabaseImpl::updateSchema( int currentver )
|
||||
|
||||
db.commit();
|
||||
return true;
|
||||
} else // update in place! run the proper upgrade script
|
||||
{
|
||||
int cur = oldVersion;
|
||||
db.transaction();
|
||||
while( cur < CURRENT_SCHEMA_VERSION ) {
|
||||
cur++;
|
||||
|
||||
QString path = QString( RESPATH "sql/dbmigrate-%1_to_%2.sql" ).arg( cur - 1 ).arg( cur );
|
||||
QFile script( path );
|
||||
if( !script.exists() || !script.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade..";
|
||||
return false;
|
||||
}
|
||||
QString sql = QString::fromUtf8( script.readAll() ).trimmed();
|
||||
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
|
||||
|
||||
foreach( const QString& sql, statements )
|
||||
{
|
||||
QString clean = cleanSql( sql ).trimmed();
|
||||
if( clean.isEmpty() )
|
||||
continue;
|
||||
|
||||
qDebug() << "Executing upgrade statement:" << clean;
|
||||
TomahawkSqlQuery q = newquery();
|
||||
q.exec( clean );
|
||||
}
|
||||
}
|
||||
db.commit();
|
||||
qDebug() << "DB Upgrade successful!";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
DatabaseImpl::cleanSql( const QString& sql )
|
||||
{
|
||||
QString fixed = sql;
|
||||
QRegExp r( "--[^\\n]*" );
|
||||
fixed.replace( r, QString() );
|
||||
return fixed.trimmed();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -84,9 +84,11 @@ signals:
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QString cleanSql( const QString& sql );
|
||||
|
||||
bool m_ready;
|
||||
|
||||
bool updateSchema( int currentver );
|
||||
bool updateSchema( int oldVersion );
|
||||
|
||||
QSqlDatabase db;
|
||||
|
||||
|
@@ -67,7 +67,8 @@ CREATE TABLE IF NOT EXISTS playlist (
|
||||
creator TEXT,
|
||||
lastmodified INTEGER NOT NULL DEFAULT 0,
|
||||
currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED,
|
||||
dynplaylist BOOLEAN DEFAULT false
|
||||
dynplaylist BOOLEAN DEFAULT false,
|
||||
createdOn INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
--INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist)
|
||||
@@ -263,4 +264,4 @@ CREATE TABLE IF NOT EXISTS settings (
|
||||
v TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '22');
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '23');
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
This file was automatically generated from ./schema.sql on Wed Mar 2 01:40:39 CET 2011.
|
||||
This file was automatically generated from schema.sql on Fri Apr 15 15:55:52 EDT 2011.
|
||||
*/
|
||||
|
||||
static const char * tomahawk_schema_sql =
|
||||
@@ -51,7 +51,8 @@ static const char * tomahawk_schema_sql =
|
||||
" creator TEXT,"
|
||||
" lastmodified INTEGER NOT NULL DEFAULT 0,"
|
||||
" currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED,"
|
||||
" dynplaylist BOOLEAN DEFAULT false"
|
||||
" dynplaylist BOOLEAN DEFAULT false,"
|
||||
" createdOn INTEGER NOT NULL DEFAULT 0"
|
||||
");"
|
||||
"CREATE TABLE IF NOT EXISTS playlist_item ("
|
||||
" guid TEXT PRIMARY KEY,"
|
||||
@@ -86,8 +87,6 @@ static const char * tomahawk_schema_sql =
|
||||
" match TEXT,"
|
||||
" input TEXT"
|
||||
");"
|
||||
""
|
||||
""
|
||||
"CREATE TABLE IF NOT EXISTS dynamic_playlist_revision ("
|
||||
" guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
|
||||
" controls TEXT, "
|
||||
@@ -173,7 +172,7 @@ static const char * tomahawk_schema_sql =
|
||||
" k TEXT NOT NULL PRIMARY KEY,"
|
||||
" v TEXT NOT NULL DEFAULT ''"
|
||||
");"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '22');"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '23');"
|
||||
;
|
||||
|
||||
const char * get_tomahawk_sql()
|
||||
|
@@ -99,6 +99,7 @@ Playlist::Playlist( const source_ptr& src,
|
||||
const QString& title,
|
||||
const QString& info,
|
||||
const QString& creator,
|
||||
uint createdOn,
|
||||
bool shared,
|
||||
int lastmod,
|
||||
const QString& guid )
|
||||
@@ -109,6 +110,7 @@ Playlist::Playlist( const source_ptr& src,
|
||||
, m_title( title )
|
||||
, m_info( info )
|
||||
, m_creator( creator )
|
||||
, m_createdOn( createdOn )
|
||||
, m_lastmodified( lastmod )
|
||||
, m_shared( shared )
|
||||
{
|
||||
@@ -129,6 +131,7 @@ Playlist::Playlist( const source_ptr& author,
|
||||
, m_title( title )
|
||||
, m_info ( info )
|
||||
, m_creator( creator )
|
||||
, m_createdOn( 0 ) // will be set by db command
|
||||
, m_lastmodified( 0 )
|
||||
, m_shared( shared )
|
||||
{
|
||||
|
@@ -77,6 +77,7 @@ public:
|
||||
source_ptr lastSource() const;
|
||||
void setLastSource( source_ptr s );
|
||||
|
||||
|
||||
private:
|
||||
QString m_guid;
|
||||
Tomahawk::query_ptr m_query;
|
||||
@@ -107,6 +108,7 @@ Q_PROPERTY( QString currentrevision READ currentrevision WRITE setCurrentrevi
|
||||
Q_PROPERTY( QString title READ title WRITE setTitle )
|
||||
Q_PROPERTY( QString info READ info WRITE setInfo )
|
||||
Q_PROPERTY( QString creator READ creator WRITE setCreator )
|
||||
Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn )
|
||||
Q_PROPERTY( bool shared READ shared WRITE setShared )
|
||||
|
||||
friend class ::DatabaseCommand_LoadAllPlaylists;
|
||||
@@ -139,6 +141,7 @@ public:
|
||||
QString guid() const { return m_guid; }
|
||||
bool shared() const { return m_shared; }
|
||||
unsigned int lastmodified() const { return m_lastmodified; }
|
||||
uint createdOn() const { return m_createdOn; }
|
||||
|
||||
const QList< plentry_ptr >& entries() { return m_entries; }
|
||||
virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev );
|
||||
@@ -155,6 +158,7 @@ public:
|
||||
void setCreator( const QString& s ) { m_creator = s; }
|
||||
void setGuid( const QString& s ) { m_guid = s; }
|
||||
void setShared( bool b ) { m_shared = b; }
|
||||
void setCreatedOn( uint createdOn ) { m_createdOn = createdOn; }
|
||||
// </IGNORE>
|
||||
|
||||
virtual QList<Tomahawk::query_ptr> tracks();
|
||||
@@ -214,6 +218,7 @@ protected:
|
||||
const QString& title,
|
||||
const QString& info,
|
||||
const QString& creator,
|
||||
uint createdOn,
|
||||
bool shared,
|
||||
int lastmod,
|
||||
const QString& guid = "" ); // populate db
|
||||
@@ -247,6 +252,7 @@ private:
|
||||
QString m_currentrevision;
|
||||
QString m_guid, m_title, m_info, m_creator;
|
||||
unsigned int m_lastmodified;
|
||||
unsigned int m_createdOn;
|
||||
bool m_shared;
|
||||
|
||||
QList< plentry_ptr > m_entries;
|
||||
|
@@ -48,12 +48,13 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
|
||||
const QString& title,
|
||||
const QString& info,
|
||||
const QString& creator,
|
||||
uint createdOn,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
bool shared,
|
||||
int lastmod,
|
||||
const QString& guid )
|
||||
: Playlist( src, currentrevision, title, info, creator, shared, lastmod, guid )
|
||||
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
|
||||
{
|
||||
qDebug() << "Creating Dynamic Playlist 1";
|
||||
// TODO instantiate generator
|
||||
|
@@ -166,6 +166,7 @@ private:
|
||||
const QString& title,
|
||||
const QString& info,
|
||||
const QString& creator,
|
||||
uint createdOn,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
bool shared,
|
||||
|
@@ -38,6 +38,7 @@ SourcesModel::SourcesModel( SourceTreeView* parent )
|
||||
, m_parent( parent )
|
||||
{
|
||||
setColumnCount( 1 );
|
||||
setSortRole( SortRole );
|
||||
|
||||
onSourceAdded( SourceList::instance()->sources() );
|
||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||
@@ -97,6 +98,32 @@ SourcesModel::data( const QModelIndex& index, int role ) const
|
||||
if ( role == Qt::SizeHintRole )
|
||||
{
|
||||
return QSize( 0, 18 );
|
||||
} else if ( role == SortRole )
|
||||
{
|
||||
if ( indexType( index ) == PlaylistSource )
|
||||
{
|
||||
playlist_ptr playlist = indexToPlaylist( index );
|
||||
if ( !playlist.isNull() )
|
||||
return playlist->createdOn();
|
||||
} else if ( indexType( index ) == DynamicPlaylistSource )
|
||||
{
|
||||
dynplaylist_ptr playlist = indexToDynamicPlaylist( index );
|
||||
if ( !playlist.isNull() )
|
||||
return playlist->createdOn();
|
||||
} else if( indexType( index ) == CollectionSource )
|
||||
{
|
||||
source_ptr source = indexToTreeItem( index )->source();
|
||||
if( source.isNull() )
|
||||
return 0; // Super Collection is first
|
||||
else if( source->isLocal() )
|
||||
return 1; // Then Local collection
|
||||
else // then all the rest
|
||||
return 5;
|
||||
} else
|
||||
{
|
||||
qDebug() << "RETURNING NULL SORT DATA!";
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return QStandardItemModel::data( index, role );
|
||||
|
@@ -40,6 +40,10 @@ public:
|
||||
DynamicPlaylistSource = 2
|
||||
};
|
||||
|
||||
enum ExtraRoles {
|
||||
SortRole = Qt::UserRole + 20,
|
||||
};
|
||||
|
||||
explicit SourcesModel( SourceTreeView* parent = 0 );
|
||||
|
||||
virtual QStringList mimeTypes() const;
|
||||
|
@@ -32,6 +32,7 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
|
||||
{
|
||||
setDynamicSortFilter( true );
|
||||
|
||||
setSortRole( SourcesModel::SortRole );
|
||||
setSourceModel( model );
|
||||
}
|
||||
|
||||
|
@@ -80,6 +80,9 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
setIndentation( 16 );
|
||||
setAnimated( true );
|
||||
|
||||
setSortingEnabled( true );
|
||||
sortByColumn( 1, Qt::AscendingOrder );
|
||||
|
||||
setItemDelegate( new SourceDelegate( this ) );
|
||||
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
|
Reference in New Issue
Block a user