- [x] Use similar format for source as destination in backups (source drive ID and path), so that external drives can be also considered as sources and can work even when drive letter doesn’t match.
- [x] Add field
'name' TEXT
todrives
table (see below). - [x]
drive-ksuid
should be primary key of drives (no need to have two IDs). - [x] Allow more paths to be contained in one archive (m:n relation backup:destination).
- [x] Save timestamp of last backup for each individual path on each drive (so that user can see when was a specific path backed up on a specific drive).
- use singular table naming – shorter SQL statements and better for possible ORM (napr, drive, backup)
- rename destinations to source (or something that better decsribes it)
- add human-friendly name to drive
- allow m:n relation between backup:source
- allow m:n relation between source:drive (to know when was some path backed up on which drive)
- TABLE drive:
- PK drive_ksuid (INTEGER)
- name (TEXT) – this should be human-friendly name (e.g. “seagate drive”)
- TABLE archive:
- PK id
- name (TEXT) – this will be used as the file name (It should probably include file extension that will enforce archiving/compression type (e.g. name=”photos-2020.7z”). Otherwise we need another field with backup type.)
- TABLE backup:
- PK archive+drive
- FK archive
- FK drive – on which drive is the archive stored
- path (TEXT) – this should be relative path to a folder on the drive
- TABLE source
- PK id
- FK archive
- FK drive – source drive
- path (TEXT) – relative path to a folder/file on drive that’s being backed up
- TABLE timestamp
- PK source+drive
- FK source
- FK drive
- datetime (INTEGER is probably most efficient)
when starting the backup or updating archive.
This probably needs a new command.
There is an archive defined, but backups haven’t been executed yet. Probably related to the previous TODO (occured after trying to create an archive with the same name that was previously “removed”).
{0001-01-01 00:00:00 +0000 UTC false} {2021-05-14 13:36:01 +0000 UTC true} {0001-01-01 00:00:00 +0000 UTC false} sql: Scan error on column index 0, name "source_id": converting NULL to int64 is unsupported sql: Scan error on column index 0, name "source_id": converting NULL to int64 is unsupported +-----------+---------------+-------------+--------------+---------+-------------+ | SOURCE ID | SOURCE DRIVE | SOURCE PATH | DESTINATIONS | ARCHIVE | ARCHIVED AT | +-----------+---------------+-------------+--------------+---------+-------------+ | 0 | Not accesible | | | | Nil | +-----------+---------------+-------------+--------------+---------+-------------+
Steps to reproduce:
- Create an archive with 2 sources and one destination.
start-backup
on both sourcesremove-backup
- Create a new archive with exactly the same arguments
Aftermath:
- A new archive is created automatically (with timestamped name) – this is generally a bad idea, because it’s not what the user wanted. Automatic creation could be optionally configured for example.
- Original archive still exists and was not removed from the DB.
- Original sources still exist and were not removed from the DB – they still point to the original archive.
The bug concerns these lines:
stmt := `SELECT id FROM source WHERE drive_ksuid = ? AND path = ?`
row := conn.db.QueryRow(stmt, drive_ksuid, path)
err = row.Scan(&id)
if err == nil {
fmt.Println("Source path already exists, archive will be updated.")
return -1
}
If these conditions are true, then a new source is not created (because
function returns -1
) and database is corrupted as archive doesn’t have a
source. See Error on =list-backups= for what this bug causes.
If the function was meant to update archive_id
for the source row, this is
also incorrect, because existing archive shouldn’t be changed just because the
drive and the path are the same (they are not the primary key).
Similar bug with the same symptoms can be created by creating a new backup with sources already existing in the database, but with a different archive name (bug with the same archive name is described in Error on =list-backups=).
Steps to reproduce:
- Create a backup with one source and one destination.
- Remove it as
BackupSoftware.exe remove-backup -p P:\BAK\archive.7z
(use correct path) archive
andbackup
entries are deleted, butsource
stays
Steps to reproduce:
- Create a backup with one source and one destination.
- Remove it as
\BackupSoftware.exe remove-backup -i 18 -d 1rUkdB28YaZ6mCmzStA1LfKY026
(use correct id and ksuid) - Output:
Archive couldnt be deleted because it is used in -1 more records. Destination was removed successfully.
backup
entry was deleted, butsource
andarchive
stay
remove-backup
uses archive ids to remove archive from a drive. If this
information is not shown anywhere to the user, user (and scripted tools) can’t
use this feature.
Maybe command list-archives
would solve this issue.
When the archive is opened in 7Zip, it can’t be changed and it leaves tmp file on the drive which prevents further backup runs.
Why can’t we just use file system functions?
This is the suspect: Drive is already in DB and .drive file exists.
It should be kept in add-drive
command, but not shown anywhere else where it
is superfluous infromation.
Duplicity leads to errors and the name will surely change in future once we rename the application.
cmd/backup.go:432: var drive_db_path = drive_letter + ":/sqlite-database.db" cmd/backup.go:448: var source_path = drive_letter + ":/sqlite-database.db" cmd/backup.go:485: drive_db_path := drive_letter + ":/sqlite-database.db" cmd/backup.go:517: drive_db_path := drive_letter + ":/sqlite-database.db" cmd/backup.go:563: helper.CopyFile(newest_drive_letter+":/sqlite-database.db", database_path) cmd/backup.go:624: var drive_db_path = drive_letter + ":/sqlite-database.db" database/database.go:713: fmt.Println("sqlite-database.db created") helpers/helper.go:53: return appdata_path + "/BackupSoft/sqlite-database.db"
.tar etc.
Multiple backup operations. This can be also done as a shell script.
DB consistency, correctness of archived/restored files… Maybe this should be higher on the priority list?