Changed the core schema to use UUIDs instead of SERIALs for all record IDs.
This commit is contained in:
parent
8ea88337b0
commit
9c007b3de5
@ -133,11 +133,14 @@ public class MediaLibrary {
|
|||||||
|
|
||||||
public def getByIdOrName(Class modelClass, String input) {
|
public def getByIdOrName(Class modelClass, String input) {
|
||||||
def match
|
def match
|
||||||
if (safeToInteger(input)) {
|
|
||||||
match = dbapi.getById(modelClass, safeToInteger(input))
|
if (safeToUUID(input)) {
|
||||||
|
match = dbapi.getById(modelClass, safeToUUID(input))
|
||||||
if (match) match = [match] }
|
if (match) match = [match] }
|
||||||
|
|
||||||
else {
|
else {
|
||||||
match = dbapi.getByName(modelClass, input)
|
match = dbapi.getByIdLike(modelClass, input)
|
||||||
|
if (!match) match = dbapi.getByName(modelClass, input)
|
||||||
if (!match) match = dbapi.getLike(modelClass, ["name"], [input]) }
|
if (!match) match = dbapi.getLike(modelClass, ["name"], [input]) }
|
||||||
return match }
|
return match }
|
||||||
|
|
||||||
@ -252,6 +255,11 @@ public class MediaLibrary {
|
|||||||
if (b != parentPath.length) return ""
|
if (b != parentPath.length) return ""
|
||||||
return (['.'] + childPath[b..<childPath.length]).join('/') }
|
return (['.'] + childPath[b..<childPath.length]).join('/') }
|
||||||
|
|
||||||
|
public static UUID safeToUUID(def val) {
|
||||||
|
if (val == null) return null
|
||||||
|
try { return UUID.fromString(val as String) }
|
||||||
|
catch (IllegalArgumentException iae) { return null } }
|
||||||
|
|
||||||
public static Integer safeToInteger(def val) {
|
public static Integer safeToInteger(def val) {
|
||||||
if (val == null) return null
|
if (val == null) return null
|
||||||
try { return val.trim() as Integer }
|
try { return val.trim() as Integer }
|
||||||
|
@ -46,11 +46,32 @@ public class DbApi {
|
|||||||
logger.debug('Selecting models.\n\tSQL: {}', query)
|
logger.debug('Selecting models.\n\tSQL: {}', query)
|
||||||
return sql.rows(query).collect { recordToModel(modelClass, it) } }
|
return sql.rows(query).collect { recordToModel(modelClass, it) } }
|
||||||
|
|
||||||
public def getById(Class modelClass, int id) {
|
public List<UUID> getAllIds(Class modelClass) {
|
||||||
|
String query = 'SELECT id FROM ' +
|
||||||
|
pluralize(nameFromModel(modelClass.simpleName))
|
||||||
|
|
||||||
|
logger.debug('Selecting model ids.\n\tSQL: {}', query)
|
||||||
|
return sql.rows(query).collect { it.id } }
|
||||||
|
|
||||||
|
public Model getById(Class<? extends Model> modelClass, UUID id) {
|
||||||
def model = modelClass.newInstance()
|
def model = modelClass.newInstance()
|
||||||
model.id = id
|
model.id = id
|
||||||
return refresh(model) }
|
return refresh(model) }
|
||||||
|
|
||||||
|
public List<Model> getByIdLike(Class<? extends Model> modelClass,
|
||||||
|
String partialId) {
|
||||||
|
String likeVal = partialId + '%'
|
||||||
|
String query = new StringBuilder()
|
||||||
|
.append('SELECT * FROM ')
|
||||||
|
.append(pluralize(nameFromModel(modelClass.simpleName)))
|
||||||
|
.append(' WHERE id LIKE ?')
|
||||||
|
.toString()
|
||||||
|
|
||||||
|
logger.debug('Selectin models like id.\n\tSQL: {}\n\tPARAMS: {}',
|
||||||
|
query, likeVal)
|
||||||
|
return sql.rows(query, likeVal)
|
||||||
|
.collect { recordToModel(modelClass, it) } }
|
||||||
|
|
||||||
public def refresh(def model) {
|
public def refresh(def model) {
|
||||||
def query = new StringBuilder()
|
def query = new StringBuilder()
|
||||||
.append('SELECT * FROM ')
|
.append('SELECT * FROM ')
|
||||||
@ -110,7 +131,7 @@ public class DbApi {
|
|||||||
case Tag: return getTagsWhere(criteria) } }
|
case Tag: return getTagsWhere(criteria) } }
|
||||||
|
|
||||||
public def save(def model) {
|
public def save(def model) {
|
||||||
if (model.id > 0) return update(model)
|
if (model.id) return update(model)
|
||||||
else return create(model) }
|
else return create(model) }
|
||||||
|
|
||||||
public def update(def model) {
|
public def update(def model) {
|
||||||
@ -142,9 +163,8 @@ public class DbApi {
|
|||||||
def columns = []
|
def columns = []
|
||||||
def params = []
|
def params = []
|
||||||
|
|
||||||
getInstanceFields(model.class)
|
if (!model.id) model.id = UUID.randomUUID()
|
||||||
.findAll { it.name != 'id' }
|
getInstanceFields(model.class).each { field ->
|
||||||
.each { field ->
|
|
||||||
//if (field.class.getAnnotation(Entity)) // check to see if we
|
//if (field.class.getAnnotation(Entity)) // check to see if we
|
||||||
// have nested models
|
// have nested models
|
||||||
columns << '"' + nameFromModel(field.name) + '"'
|
columns << '"' + nameFromModel(field.name) + '"'
|
||||||
@ -160,7 +180,7 @@ public class DbApi {
|
|||||||
.append(')').toString()
|
.append(')').toString()
|
||||||
|
|
||||||
logger.debug('Creating model.\n\tSQL: {}\n\tPARAMS: {}', query, params)
|
logger.debug('Creating model.\n\tSQL: {}\n\tPARAMS: {}', query, params)
|
||||||
model.id = sql.executeInsert(query, params)[0][0]
|
sql.executeInsert(query, params)
|
||||||
return model }
|
return model }
|
||||||
|
|
||||||
public def delete(def model) {
|
public def delete(def model) {
|
||||||
@ -176,7 +196,7 @@ public class DbApi {
|
|||||||
return sql.updateCount }
|
return sql.updateCount }
|
||||||
|
|
||||||
public def associate(Class modelClass1, Class modelClass2 ,
|
public def associate(Class modelClass1, Class modelClass2 ,
|
||||||
Integer firstId, Integer secondId) {
|
UUID firstId, UUID secondId) {
|
||||||
String linkTable = pluralize(nameFromModel(modelClass1.simpleName)) +
|
String linkTable = pluralize(nameFromModel(modelClass1.simpleName)) +
|
||||||
'_' + pluralize(nameFromModel(modelClass2.simpleName))
|
'_' + pluralize(nameFromModel(modelClass2.simpleName))
|
||||||
String col1 = nameFromModel(modelClass1.simpleName) + '_id'
|
String col1 = nameFromModel(modelClass1.simpleName) + '_id'
|
||||||
@ -203,7 +223,7 @@ public class DbApi {
|
|||||||
|
|
||||||
/// ### Album-specific methods
|
/// ### Album-specific methods
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
public Album getAlbumById(int id) { return getById(Album, id) }
|
public Album getAlbumById(UUID id) { return getById(Album, id) }
|
||||||
|
|
||||||
public List<Album> getAlbums() { return getAll(Album) }
|
public List<Album> getAlbums() { return getAll(Album) }
|
||||||
|
|
||||||
@ -268,7 +288,7 @@ public class DbApi {
|
|||||||
|
|
||||||
/// ### Artist-specific methods
|
/// ### Artist-specific methods
|
||||||
public List<Artist> getArtists() { return getAll(Artist) }
|
public List<Artist> getArtists() { return getAll(Artist) }
|
||||||
public Artist getArtistById(int id) { return getById(Artist, id) }
|
public Artist getArtistById(UUID id) { return getById(Artist, id) }
|
||||||
|
|
||||||
public Artist getArtistByName(String name) {
|
public Artist getArtistByName(String name) {
|
||||||
def artists = getByName(Artist, name)
|
def artists = getByName(Artist, name)
|
||||||
@ -314,7 +334,7 @@ public class DbApi {
|
|||||||
public List<Artist> getArtistsLikeName(String name) {
|
public List<Artist> getArtistsLikeName(String name) {
|
||||||
return getLike(Artist, ['name'], [name]) }
|
return getLike(Artist, ['name'], [name]) }
|
||||||
|
|
||||||
public def addAlbumArtist(int albumId, int artistId) {
|
public def addAlbumArtist(UUID albumId, UUID artistId) {
|
||||||
return associate(Artist, Album, artistId, albumId) }
|
return associate(Artist, Album, artistId, albumId) }
|
||||||
|
|
||||||
public void removeEmptyArtists() {
|
public void removeEmptyArtists() {
|
||||||
@ -330,7 +350,7 @@ public class DbApi {
|
|||||||
sql.execute(query) }
|
sql.execute(query) }
|
||||||
|
|
||||||
/// ### Bookmark-specific methods
|
/// ### Bookmark-specific methods
|
||||||
public Bookmark getBookmarkById(int id) { return getById(Bookmark, id) }
|
public Bookmark getBookmarkById(UUID id) { return getById(Bookmark, id) }
|
||||||
|
|
||||||
public List<Bookmark> getBookmarkByName(String name) {
|
public List<Bookmark> getBookmarkByName(String name) {
|
||||||
return getByName(Bookmark, name) }
|
return getByName(Bookmark, name) }
|
||||||
@ -394,10 +414,10 @@ public class DbApi {
|
|||||||
.collect { recordToModel(Bookmark, it) } }
|
.collect { recordToModel(Bookmark, it) } }
|
||||||
|
|
||||||
/// ### Image-specific methods
|
/// ### Image-specific methods
|
||||||
public Image getImageById(int id) { return getById(Image, id) }
|
public Image getImageById(UUID id) { return getById(Image, id) }
|
||||||
|
|
||||||
/// ### MediaFile-specific methods
|
/// ### MediaFile-specific methods
|
||||||
public MediaFile getMediaFileById(int id) { return getById(MediaFile, id) }
|
public MediaFile getMediaFileById(UUID id) { return getById(MediaFile, id) }
|
||||||
|
|
||||||
public List<MediaFile> getMediaFileByName(String name) {
|
public List<MediaFile> getMediaFileByName(String name) {
|
||||||
return getByName(MediaFile, name) }
|
return getByName(MediaFile, name) }
|
||||||
@ -460,21 +480,25 @@ public class DbApi {
|
|||||||
sqlParams << params.name }
|
sqlParams << params.name }
|
||||||
|
|
||||||
if (params.discNumber) {
|
if (params.discNumber) {
|
||||||
query.append('mf.disc_number = ?')
|
whereClauses << 'mf.disc_number = ?'
|
||||||
sqlParams << params.discNumber }
|
sqlParams << params.discNumber }
|
||||||
|
|
||||||
if (params.trackNumber) {
|
if (params.trackNumber) {
|
||||||
query.append('mf.track_number = ?')
|
whereClauses << 'mf.track_number = ?'
|
||||||
sqlParams << params.trackNumber }
|
sqlParams << params.trackNumber }
|
||||||
|
|
||||||
if (params.filePath) {
|
if (params.filePath) {
|
||||||
query.append('mf.file_path = ?')
|
whereClauses << 'mf.file_path = ?'
|
||||||
sqlParams << params.filePath }
|
sqlParams << params.filePath }
|
||||||
|
|
||||||
if (params.fileHash) {
|
if (params.fileHash) {
|
||||||
query.append('mf.file_hash = ?')
|
whereClauses << 'mf.file_hash = ?'
|
||||||
sqlParams << params.fileHash }
|
sqlParams << params.fileHash }
|
||||||
|
|
||||||
|
if (params.containsKey('presentLocally')) {
|
||||||
|
whereClauses << 'mf.present_locally = ?'
|
||||||
|
sqlParams << params.presentLocally }
|
||||||
|
|
||||||
if (params.tags) {
|
if (params.tags) {
|
||||||
params.tags.eachWithIndex { tag, idx ->
|
params.tags.eachWithIndex { tag, idx ->
|
||||||
String L = "mft${idx}";
|
String L = "mft${idx}";
|
||||||
@ -518,13 +542,13 @@ public class DbApi {
|
|||||||
logger.debug('Finding untagged media files.\n\tSQL: {}', query)
|
logger.debug('Finding untagged media files.\n\tSQL: {}', query)
|
||||||
return sql.rows(query).collect { recordToModel(MediaFile, it) } }
|
return sql.rows(query).collect { recordToModel(MediaFile, it) } }
|
||||||
|
|
||||||
public def associateMediaFileWithAlbum(int mediaFileId, int albumId) {
|
public def associateMediaFileWithAlbum(UUID mediaFileId, UUID albumId) {
|
||||||
return associate(Album, MediaFile, albumId, mediaFileId) }
|
return associate(Album, MediaFile, albumId, mediaFileId) }
|
||||||
|
|
||||||
public def associateMediaFileWithArtist(int mediaFileId, int artistId) {
|
public def associateMediaFileWithArtist(UUID mediaFileId, UUID artistId) {
|
||||||
return associate(Album, MediaFile, artistId, mediaFileId) }
|
return associate(Album, MediaFile, artistId, mediaFileId) }
|
||||||
|
|
||||||
public def incrementPlayCount(int mediaFileId) {
|
public def incrementPlayCount(UUID mediaFileId) {
|
||||||
def query = 'UPDATE media_files SET play_count = play_count + 1 WHERE ID = ?'
|
def query = 'UPDATE media_files SET play_count = play_count + 1 WHERE ID = ?'
|
||||||
def params = [mediaFileId]
|
def params = [mediaFileId]
|
||||||
|
|
||||||
@ -541,7 +565,7 @@ public class DbApi {
|
|||||||
|
|
||||||
/// ### Playlist-specific methods
|
/// ### Playlist-specific methods
|
||||||
public List<Playlist> getPlaylists() { return getAll(Playlist) }
|
public List<Playlist> getPlaylists() { return getAll(Playlist) }
|
||||||
public Playlist getPlaylistById(int id) { return getById(Playlist, id) }
|
public Playlist getPlaylistById(UUID id) { return getById(Playlist, id) }
|
||||||
|
|
||||||
public List<Playlist> getPlaylistByName(String name) {
|
public List<Playlist> getPlaylistByName(String name) {
|
||||||
return getByName(Playlist, name) }
|
return getByName(Playlist, name) }
|
||||||
@ -613,7 +637,7 @@ public class DbApi {
|
|||||||
return sql.rows(query, sqlParams)
|
return sql.rows(query, sqlParams)
|
||||||
.collect { recordToModel(Playlist, it) } }
|
.collect { recordToModel(Playlist, it) } }
|
||||||
|
|
||||||
public int getNextPlaylistPosition(int playlistId) {
|
public int getNextPlaylistPosition(UUID playlistId) {
|
||||||
String query = """\
|
String query = """\
|
||||||
SELECT COALESCE(MAX(position), 0) + 1
|
SELECT COALESCE(MAX(position), 0) + 1
|
||||||
FROM playlists_media_files
|
FROM playlists_media_files
|
||||||
@ -624,7 +648,7 @@ public class DbApi {
|
|||||||
|
|
||||||
return sql.firstRow(query, playlistId)[0] }
|
return sql.firstRow(query, playlistId)[0] }
|
||||||
|
|
||||||
private int incrementPlaylistPositions(int playlistId, int startPosition,
|
private int incrementPlaylistPositions(UUID playlistId, int startPosition,
|
||||||
int incrementAmount) {
|
int incrementAmount) {
|
||||||
String query = """\
|
String query = """\
|
||||||
UPDATE playlists_media_files
|
UPDATE playlists_media_files
|
||||||
@ -636,8 +660,8 @@ public class DbApi {
|
|||||||
query, params)
|
query, params)
|
||||||
return sql.executeUpdate(query, params) }
|
return sql.executeUpdate(query, params) }
|
||||||
|
|
||||||
public Playlist addToPlaylist(int playlistId,
|
public Playlist addToPlaylist(UUID playlistId,
|
||||||
List<Integer> mediaFileIds, int startPosition = -1) {
|
List<UUID> mediaFileIds, int startPosition = -1) {
|
||||||
|
|
||||||
String query
|
String query
|
||||||
def params
|
def params
|
||||||
@ -665,7 +689,7 @@ public class DbApi {
|
|||||||
p.lastUsed = new Timestamp(new Date().time)
|
p.lastUsed = new Timestamp(new Date().time)
|
||||||
return update(p) } }
|
return update(p) } }
|
||||||
|
|
||||||
public Playlist addToPlaylist(int playlistId, int mediaFileId,
|
public Playlist addToPlaylist(UUID playlistId, UUID mediaFileId,
|
||||||
int position = -1) {
|
int position = -1) {
|
||||||
|
|
||||||
String query
|
String query
|
||||||
@ -690,7 +714,7 @@ public class DbApi {
|
|||||||
p.lastUsed = new Timestamp(new Date().time)
|
p.lastUsed = new Timestamp(new Date().time)
|
||||||
return update(p) } }
|
return update(p) } }
|
||||||
|
|
||||||
public Playlist removeFromPlaylist(int playlistId, int mediaFileId) {
|
public Playlist removeFromPlaylist(UUID playlistId, UUID mediaFileId) {
|
||||||
String getPositionQuery = """\
|
String getPositionQuery = """\
|
||||||
SELECT position FROM playlists_media_files
|
SELECT position FROM playlists_media_files
|
||||||
WHERE playlist_id = ? AND media_file_id = ?"""
|
WHERE playlist_id = ? AND media_file_id = ?"""
|
||||||
@ -735,7 +759,7 @@ public class DbApi {
|
|||||||
|
|
||||||
return getById(Playlist, playlistId) } }
|
return getById(Playlist, playlistId) } }
|
||||||
|
|
||||||
public Playlist removeAllFromPlaylist(int playlistId) {
|
public Playlist removeAllFromPlaylist(UUID playlistId) {
|
||||||
return withTransaction {
|
return withTransaction {
|
||||||
def p = getById(Playlist, playlistId)
|
def p = getById(Playlist, playlistId)
|
||||||
if (!p) return null
|
if (!p) return null
|
||||||
@ -762,7 +786,7 @@ public class DbApi {
|
|||||||
sql.execute(query) }
|
sql.execute(query) }
|
||||||
|
|
||||||
/// ### Tag-specific methods
|
/// ### Tag-specific methods
|
||||||
public Tag getTagById(int id) { return getById(Tag, id) }
|
public Tag getTagById(UUID id) { return getById(Tag, id) }
|
||||||
public Tag getTagByName(String name) { return getByName(Tag, name)[0] }
|
public Tag getTagByName(String name) { return getByName(Tag, name)[0] }
|
||||||
public List<Tag> getTags() { return getAll(Tag, 'name ASC') }
|
public List<Tag> getTags() { return getAll(Tag, 'name ASC') }
|
||||||
|
|
||||||
@ -807,7 +831,7 @@ public class DbApi {
|
|||||||
query, sqlParams)
|
query, sqlParams)
|
||||||
return sql.rows(query, sqlParams).collect { recordToModel(Tag, it) } }
|
return sql.rows(query, sqlParams).collect { recordToModel(Tag, it) } }
|
||||||
|
|
||||||
public def tagMediaFiles(List<Integer> mediaFileIds, List<String> tagNames) {
|
public def tagMediaFiles(List<UUID> mediaFileIds, List<String> tagNames) {
|
||||||
String insertQuery = 'INSERT INTO media_files_tags VALUES (?, ?)'
|
String insertQuery = 'INSERT INTO media_files_tags VALUES (?, ?)'
|
||||||
String checkQuery = 'SELECT * FROM media_files_tags WHERE media_file_id = ? AND tag_id = ?'
|
String checkQuery = 'SELECT * FROM media_files_tags WHERE media_file_id = ? AND tag_id = ?'
|
||||||
def params
|
def params
|
||||||
@ -828,8 +852,7 @@ public class DbApi {
|
|||||||
params)
|
params)
|
||||||
sql.executeInsert(insertQuery, params) } } } } }
|
sql.executeInsert(insertQuery, params) } } } } }
|
||||||
|
|
||||||
public def untagMediaFiles(List<Integer> mediaFileIds,
|
public def untagMediaFiles(List<UUID> mediaFileIds, List<String> tagNames) {
|
||||||
List<String> tagNames) {
|
|
||||||
|
|
||||||
withTransaction {
|
withTransaction {
|
||||||
List<Tag> tags = tagNames.collect(this.&getTagByName).findAll()
|
List<Tag> tags = tagNames.collect(this.&getTagByName).findAll()
|
||||||
|
@ -2,11 +2,12 @@ package com.jdbernard.wdiwtlt.db.models;
|
|||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class Bookmark extends Model {
|
public class Bookmark extends Model {
|
||||||
public String name;
|
public String name;
|
||||||
public int playlistId;
|
public UUID playlistId;
|
||||||
public int mediaFileId;
|
public UUID mediaFileId;
|
||||||
public int playIndex;
|
public int playIndex;
|
||||||
public int playTimeMs = 0;
|
public int playTimeMs = 0;
|
||||||
public boolean userCreated;
|
public boolean userCreated;
|
||||||
|
@ -16,6 +16,7 @@ public class MediaFile extends Model {
|
|||||||
public String metaInfoSource = TAG_INFO;
|
public String metaInfoSource = TAG_INFO;
|
||||||
public Timestamp dateAdded = new Timestamp(new Date().getTime());
|
public Timestamp dateAdded = new Timestamp(new Date().getTime());
|
||||||
public Timestamp lastPlayed;
|
public Timestamp lastPlayed;
|
||||||
|
public boolean presentLocally = true;
|
||||||
public String comment;
|
public String comment;
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package com.jdbernard.wdiwtlt.db.models;
|
package com.jdbernard.wdiwtlt.db.models;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Model implements Comparable<Model> {
|
public class Model implements Comparable<Model> {
|
||||||
public Integer id;
|
public UUID id;
|
||||||
|
|
||||||
public boolean equals(Object thatObj) {
|
public boolean equals(Object thatObj) {
|
||||||
if (thatObj == null) return false;
|
if (thatObj == null) return false;
|
||||||
if (this.getClass() != thatObj.getClass()) return false;
|
if (this.getClass() != thatObj.getClass()) return false;
|
||||||
|
|
||||||
Model that = (Model) thatObj;
|
Model that = (Model) thatObj;
|
||||||
|
|
||||||
|
if (this.id == null || that.id == null) return false;
|
||||||
return this.id.equals(that.id); }
|
return this.id.equals(that.id); }
|
||||||
|
|
||||||
public int compareTo(Model that) {
|
public int compareTo(Model that) {
|
||||||
|
@ -2,12 +2,13 @@ package com.jdbernard.wdiwtlt.db.models;
|
|||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class Playlist extends Model {
|
public class Playlist extends Model {
|
||||||
public boolean userCreated = false;
|
public boolean userCreated = false;
|
||||||
public String name;
|
public String name;
|
||||||
public int mediaFileCount = 0;
|
public int mediaFileCount = 0;
|
||||||
public Integer copiedFromId = null;
|
public UUID copiedFromId = null;
|
||||||
public Timestamp createdAt = new Timestamp(new Date().getTime());
|
public Timestamp createdAt = new Timestamp(new Date().getTime());
|
||||||
public Timestamp lastUsed = new Timestamp(new Date().getTime());
|
public Timestamp lastUsed = new Timestamp(new Date().getTime());
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
CREATE TABLE artists (
|
CREATE TABLE artists (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
name VARCHAR UNIQUE NOT NULL
|
name VARCHAR UNIQUE NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX artists_name_idx ON artists(name);
|
CREATE INDEX artists_name_idx ON artists(name);
|
||||||
|
|
||||||
CREATE TABLE albums (
|
CREATE TABLE albums (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
name VARCHAR NOT NULL,
|
name VARCHAR NOT NULL,
|
||||||
year INTEGER,
|
year INTEGER,
|
||||||
track_total INTEGER
|
track_total INTEGER
|
||||||
@ -15,7 +15,7 @@ CREATE TABLE albums (
|
|||||||
CREATE INDEX albums_name_idx ON albums(name);
|
CREATE INDEX albums_name_idx ON albums(name);
|
||||||
|
|
||||||
CREATE TABLE media_files (
|
CREATE TABLE media_files (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
name VARCHAR NOT NULL,
|
name VARCHAR NOT NULL,
|
||||||
disc_number VARCHAR NOT NULL DEFAULT '1',
|
disc_number VARCHAR NOT NULL DEFAULT '1',
|
||||||
track_number INTEGER,
|
track_number INTEGER,
|
||||||
@ -25,53 +25,54 @@ CREATE TABLE media_files (
|
|||||||
meta_info_source VARCHAR NOT NULL, -- 'tag' or 'filesystem'
|
meta_info_source VARCHAR NOT NULL, -- 'tag' or 'filesystem'
|
||||||
date_added TIMESTAMP NOT NULL DEFAULT NOW(),
|
date_added TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
last_played TIMESTAMP,
|
last_played TIMESTAMP,
|
||||||
|
present_locally BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
comment VARCHAR DEFAULT ''
|
comment VARCHAR DEFAULT ''
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX media_files_name_idx ON media_files(name);
|
CREATE INDEX media_files_name_idx ON media_files(name);
|
||||||
|
|
||||||
CREATE TABLE artists_media_files (
|
CREATE TABLE artists_media_files (
|
||||||
artist_id INTEGER NOT NULL REFERENCES artists(id) ON DELETE CASCADE,
|
artist_id UUID NOT NULL REFERENCES artists(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
media_file_id INTEGER NOT NULL REFERENCES media_files(id) ON DELETE CASCADE,
|
media_file_id UUID NOT NULL REFERENCES media_files(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (artist_id, media_file_id)
|
PRIMARY KEY (artist_id, media_file_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE albums_media_files (
|
CREATE TABLE albums_media_files (
|
||||||
album_id INTEGER NOT NULL REFERENCES albums(id) ON DELETE CASCADE,
|
album_id UUID NOT NULL REFERENCES albums(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
media_file_id INTEGER NOT NULL REFERENCES media_files(id) ON DELETE CASCADE,
|
media_file_id UUID NOT NULL REFERENCES media_files(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (album_id, media_file_id)
|
PRIMARY KEY (album_id, media_file_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE tags (
|
CREATE TABLE tags (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
name VARCHAR UNIQUE NOT NULL,
|
name VARCHAR UNIQUE NOT NULL,
|
||||||
description VARCHAR NOT NULL DEFAULT ''
|
description VARCHAR NOT NULL DEFAULT ''
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE playlists (
|
CREATE TABLE playlists (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
user_created BOOLEAN NOT NULL DEFAULT FALSE,
|
user_created BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
name VARCHAR NOT NULL,
|
name VARCHAR NOT NULL,
|
||||||
media_file_count INTEGER NOT NULL DEFAULT 0,
|
media_file_count INTEGER NOT NULL DEFAULT 0,
|
||||||
copied_from_id INTEGER DEFAULT NULL,
|
copied_from_id UUID DEFAULT NULL,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
last_used TIMESTAMP NOT NULL DEFAULT NOW()
|
last_used TIMESTAMP NOT NULL DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE playlists_media_files (
|
CREATE TABLE playlists_media_files (
|
||||||
playlist_id INTEGER NOT NULL REFERENCES playlists(id) ON DELETE CASCADE,
|
playlist_id UUID NOT NULL REFERENCES playlists(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
media_file_id INTEGER NOT NULL REFERENCES media_files(id) ON DELETE CASCADE,
|
media_file_id UUID NOT NULL REFERENCES media_files(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
position INTEGER NOT NULL DEFAULT 0,
|
position INTEGER NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (playlist_id, media_file_id, position),
|
PRIMARY KEY (playlist_id, media_file_id, position),
|
||||||
UNIQUE (playlist_id, position)
|
UNIQUE (playlist_id, position)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE bookmarks (
|
CREATE TABLE bookmarks (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
user_created BOOLEAN NOT NULL DEFAULT FALSE,
|
user_created BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
playlist_id INTEGER NOT NULL REFERENCES playlists(id) ON DELETE CASCADE,
|
playlist_id UUID NOT NULL REFERENCES playlists(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
media_file_id INTEGER NOT NULL REFERENCES media_files(id) ON DELETE CASCADE,
|
media_file_id UUID NOT NULL REFERENCES media_files(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
play_index INTEGER NOT NULL,
|
play_index INTEGER NOT NULL,
|
||||||
play_time_ms INTEGER NOT NULL DEFAULT 0,
|
play_time_ms INTEGER NOT NULL DEFAULT 0,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
@ -82,30 +83,30 @@ CREATE INDEX bookmarks_playlist_id_idx ON bookmarks (playlist_id);
|
|||||||
CREATE INDEX bookmarks_media_file_id_idx ON bookmarks (media_file_id);
|
CREATE INDEX bookmarks_media_file_id_idx ON bookmarks (media_file_id);
|
||||||
|
|
||||||
CREATE TABLE media_files_tags (
|
CREATE TABLE media_files_tags (
|
||||||
media_file_id INTEGER REFERENCES media_files(id) ON DELETE CASCADE,
|
media_file_id UUID REFERENCES media_files(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE,
|
tag_id UUID REFERENCES tags(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (media_file_id, tag_id)
|
PRIMARY KEY (media_file_id, tag_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE images (
|
CREATE TABLE images (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
url VARCHAR
|
url VARCHAR
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE artists_images (
|
CREATE TABLE artists_images (
|
||||||
artist_id INTEGER REFERENCES artists (id) ON DELETE CASCADE,
|
artist_id UUID REFERENCES artists (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
image_id INTEGER REFERENCES images (id) ON DELETE CASCADE,
|
image_id UUID REFERENCES images (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (artist_id, image_id)
|
PRIMARY KEY (artist_id, image_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE albums_images (
|
CREATE TABLE albums_images (
|
||||||
album_id INTEGER REFERENCES albums (id) ON DELETE CASCADE,
|
album_id UUID REFERENCES albums (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
image_id INTEGER REFERENCES images (id) ON DELETE CASCADE,
|
image_id UUID REFERENCES images (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (album_id, image_id)
|
PRIMARY KEY (album_id, image_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE artists_albums (
|
CREATE TABLE artists_albums (
|
||||||
artist_id INTEGER NOT NULL REFERENCES artists (id) ON DELETE CASCADE,
|
artist_id UUID NOT NULL REFERENCES artists (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
album_id INTEGER NOT NULL REFERENCES albums (id) ON DELETE CASCADE,
|
album_id UUID NOT NULL REFERENCES albums (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
PRIMARY KEY (artist_id, album_id)
|
PRIMARY KEY (artist_id, album_id)
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user