Added core support for DB synchronization.
This commit is contained in:
parent
9c007b3de5
commit
d6edd3f11d
@ -50,7 +50,10 @@ public class MediaLibrary {
|
|||||||
staleBookmarks.each { dbapi.delete(it) } } }
|
staleBookmarks.each { dbapi.delete(it) } } }
|
||||||
|
|
||||||
public def rescanLibrary() {
|
public def rescanLibrary() {
|
||||||
def results = [ total: 0, ignored: 0, new: 0]
|
def results = [ total: 0, ignored: 0, new: 0, present: 0, absent: 0]
|
||||||
|
|
||||||
|
List<MediaFile> missingFiles = dbapi.getMediaFiles()
|
||||||
|
List<MediaFile> foundFiles = []
|
||||||
|
|
||||||
Date startDate = new Date()
|
Date startDate = new Date()
|
||||||
libraryRoot.eachFileRecurse { file ->
|
libraryRoot.eachFileRecurse { file ->
|
||||||
@ -60,7 +63,23 @@ public class MediaLibrary {
|
|||||||
|
|
||||||
results.total++
|
results.total++
|
||||||
if (!mf) results.ignored++
|
if (!mf) results.ignored++
|
||||||
else if (mf.dateAdded > startDate) results.new++ }
|
else {
|
||||||
|
foundFiles << mf
|
||||||
|
if (missingFiles.contains(mf)) missingFiles.remove(mf)
|
||||||
|
if (mf.dateAdded > startDate) results.new++ } }
|
||||||
|
|
||||||
|
foundFiles.each { mf ->
|
||||||
|
if (!mf.presentLocally) {
|
||||||
|
mf.presentLocally = true
|
||||||
|
dbapi.update(mf) } }
|
||||||
|
|
||||||
|
missingFiles.each { mf ->
|
||||||
|
if (mf.presentLocally) {
|
||||||
|
mf.presentLocally = false
|
||||||
|
dbapi.update(mf) } }
|
||||||
|
|
||||||
|
results.present = foundFiles.size()
|
||||||
|
results.absent = missingFiles.size()
|
||||||
|
|
||||||
return results }
|
return results }
|
||||||
|
|
||||||
|
@ -927,4 +927,72 @@ public class DbApi {
|
|||||||
|
|
||||||
static def getInstanceFields(Class modelClass) {
|
static def getInstanceFields(Class modelClass) {
|
||||||
return modelClass.fields.findAll { !Modifier.isStatic(it.modifiers) } }
|
return modelClass.fields.findAll { !Modifier.isStatic(it.modifiers) } }
|
||||||
|
|
||||||
|
/// ### DB Sync/Replication
|
||||||
|
|
||||||
|
public def diffWith(DbApi that) {
|
||||||
|
|
||||||
|
def results = [
|
||||||
|
ours: [ modelIds: [:], associations: [:] ],
|
||||||
|
theirs:[ modelIds: [:], associations: [:] ] ]
|
||||||
|
|
||||||
|
[Album, Artist, Image, MediaFile, Playlist, Bookmark,
|
||||||
|
Tag].each { modelClass ->
|
||||||
|
|
||||||
|
List<UUID> ourIds = this.getAllIds(modelClass)
|
||||||
|
List<UUID> theirIds = that.getAllIds(modelClass)
|
||||||
|
|
||||||
|
results.ours.modelIds[modelClass] = ourIds - theirIds
|
||||||
|
results.theirs.modelIds[modelClass] = theirIds - ourIds }
|
||||||
|
|
||||||
|
['albums_images', 'albums_media_files', 'artists_albums',
|
||||||
|
'artists_images', 'artists_media_files', 'media_files_tags',
|
||||||
|
'playlists_media_files'].each { tableName ->
|
||||||
|
|
||||||
|
def query = 'SELECT * FROM ' + tableName;
|
||||||
|
def allOurRows = this.sql.rows(query)
|
||||||
|
def allTheirRows = that.sql.rows(query)
|
||||||
|
|
||||||
|
def ourRows = allOurRows.clone()
|
||||||
|
def theirRows = allTheirRows.clone()
|
||||||
|
|
||||||
|
allOurRows.each { ourRow ->
|
||||||
|
allTheirRows.each { theirRow ->
|
||||||
|
if (ourRow[0] == theirRow[0]) {
|
||||||
|
ourRows.remove(ourRow)
|
||||||
|
theirRows.remove(theirRow) } } }
|
||||||
|
|
||||||
|
results.ours.associations[tableName] = ourRows
|
||||||
|
results.theirs.associations[tableName] = theirRows }
|
||||||
|
|
||||||
|
return results }
|
||||||
|
|
||||||
|
public def ingestDiff(DbApi that, def diff) {
|
||||||
|
|
||||||
|
diff.modelIds.each { modelClass, ids ->
|
||||||
|
ids.each { id -> this.create(that.getById(modelClass, id)) } }
|
||||||
|
|
||||||
|
diff.associations.each { tableName, rows ->
|
||||||
|
String placeholders = null
|
||||||
|
String query = null
|
||||||
|
rows.each { row ->
|
||||||
|
if (!placeholders)
|
||||||
|
placeholders = (1..row.size()).collect { '?' }.join(', ')
|
||||||
|
|
||||||
|
if (!query)
|
||||||
|
query = "INSERT INTO ${tableName} VALUES (${placeholders})"
|
||||||
|
|
||||||
|
logger.debug("Adding association.\n\tSQL: {}\n\tPARAMS: {}",
|
||||||
|
query, row.values() as List)
|
||||||
|
this.sql.executeInsert(query, row.values() as List) } } }
|
||||||
|
|
||||||
|
public def syncWith(DbApi that, boolean pull = true,
|
||||||
|
boolean push = false) {
|
||||||
|
def diff = this.diffWith(that)
|
||||||
|
|
||||||
|
if (pull) this.ingestDiff(that, diff.theirs)
|
||||||
|
if (push) that.ingestDiff(this, diff.ours)
|
||||||
|
|
||||||
|
return diff }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user