Commit 82bfc966 by John Doe

remove missing files and folders on update

parent 3720f9af
......@@ -7,6 +7,12 @@ class UpdateFolder
def initialize(folder, entries)
@folder = folder
@entries = entries
# initialiaze array of current entries, ids are removed
# as they are updated, so any id's left in this
# array are no longer present on the remote db
# and will be destroyed
@subfolder_ids = folder.subfolders.ids
@file_ids = folder.db_files.ids
super()
end
......@@ -18,6 +24,20 @@ class UpdateFolder
info.slice(*DbFolder.defined_attributes))
# process the contents of the folder
__parse_folder_entries(@folder, @entries)
# delete any files or folders still in the
# tracked ID arrays, they haven't been touched
# so they must have been removed from the remote
# db some other way (eg nilmtool)
unless @file_ids.empty?
@folder.db_files.destroy(*@file_ids)
add_warning('Removed files no longer in the remote database')
end
unless @subfolder_ids.empty?
@folder.subfolders.destroy(*@subfolder_ids)
add_warning('Removed folders no longer in the remote database')
end
# save the result
@folder.save!
self
......@@ -103,14 +123,16 @@ class UpdateFolder
default_name)
base = __base_entry(entry_group)
unless base # corrupt file, don't process
@warnings << "#{entry_group.count} orphan decimations in #{folder.name}"
add_warning("#{entry_group.count} orphan decimations in #{folder.name}")
return
end
# find or create the file
file = folder.db_files.find_by_path(base[:path])
file ||= DbFile.new(db_folder: folder,
path: base[:path], name: default_name)
# remove the id (if present) to mark this file as updated
@file_ids -= [file.id]
# return the Updater, don't run it
UpdateFile.new(file, base, entry_group - [base])
end
......@@ -131,6 +153,9 @@ class UpdateFolder
path = __build_path(entries)
folder = parent.subfolders.find_by_path(path)
folder ||= DbFolder.new(parent: parent, path: path, name: default_name)
# remove the id (if present) to mark this folder as updated
@subfolder_ids -= [folder.id]
# return the Updater, don't run it
UpdateFolder.new(folder, entries)
end
......
......@@ -22,6 +22,8 @@ module ServiceStatus
end
def add_error(message)
# ignore duplicates
return if @errors.include?(message)
@errors << String(message)
end
......@@ -30,6 +32,8 @@ module ServiceStatus
end
def add_warning(message)
# ignore duplicates
return if @warnings.include?(message)
@warnings << String(message)
end
......
......@@ -25,12 +25,12 @@ simple_db = [
describe 'UpdateDb' do
describe '*run*' do
def update_with_schema(schema)
def update_with_schema(schema, db: nil)
# stub the database adapter
adapter = instance_double(DbAdapter)
allow(adapter).to receive(:schema).and_return(Array.new(schema))
# run the update
@db = Db.new
@db = db || Db.new
@service = UpdateDb.new(db: @db)
@service.run(db_adapter: adapter)
@root = @db.root_folder
......@@ -129,8 +129,41 @@ describe 'UpdateDb' do
# updates to remote db
describe 'given changes to remote db' do
it 'removes missing files'
it 'removes missing folders'
it 'removes missing files' do
# create Db with a file 'temp'
update_with_schema([helper.entry('/folder1/temp'),
helper.entry('/folder1/info',
metadata: { name: 'f1' })
])
temp = DbFile.find_by_name('temp')
# the file 'temp' should be here
expect(temp).to be_present
# update Db without 'temp'
update_with_schema([helper.entry('/folder1/info',
metadata: { name: 'f1' })
], db: @db)
# it should be gone
expect(DbFile.find_by_name('temp')).to be nil
# ...and the service should have a warning
expect(@service.warnings?).to be true
end
it 'removes missing folders' do
# create Db with a folder 'temp'
update_with_schema([helper.entry('/folder1/stub'),
helper.entry('/folder1/temp/info',
metadata: { name: 'temp' })
])
temp = DbFolder.find_by_name('temp')
# the file 'temp' should be here
expect(temp).to be_present
# update Db without 'temp'
update_with_schema([helper.entry('/folder1/stub')],
db: @db)
# it should be gone
expect(DbFolder.find_by_name('temp')).to be nil
# ...and the service should have a warning
expect(@service.warnings?).to be true
end
it 'adds new files'
it 'adds new folders'
end
......
......@@ -26,6 +26,13 @@ describe 'ServiceStatus' do
expect(x.warnings.length).to eq(1)
end
it 'ignores duplicate messages' do
x = ModuleTester.new
x.add_error('the same thing')
x.add_error('the same thing')
expect(x.errors.length).to eq(1)
end
it 'raises error if *run* is not implemented' do
x = ModuleTester.new
expect { x.run }.to raise_error(RuntimeError)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment