Add column for photo's st_dev, st_ino to facilitate lost&found.

This commit is contained in:
voussoir 2020-09-15 14:56:45 -07:00
parent 5f9627da61
commit 9578dc4d67
4 changed files with 82 additions and 5 deletions

View file

@ -42,7 +42,7 @@ ffmpeg = _load_ffmpeg()
# Database #########################################################################################
DATABASE_VERSION = 14
DATABASE_VERSION = 15
DB_VERSION_PRAGMA = f'''
PRAGMA user_version = {DATABASE_VERSION};
'''
@ -91,6 +91,7 @@ CREATE INDEX IF NOT EXISTS index_bookmarks_author_id on bookmarks(author_id);
CREATE TABLE IF NOT EXISTS photos(
id TEXT PRIMARY KEY NOT NULL,
filepath TEXT COLLATE NOCASE,
dev_ino TEXT,
override_filename TEXT COLLATE NOCASE,
extension TEXT,
width INT,
@ -108,6 +109,7 @@ CREATE TABLE IF NOT EXISTS photos(
);
CREATE INDEX IF NOT EXISTS index_photos_id on photos(id);
CREATE INDEX IF NOT EXISTS index_photos_filepath on photos(filepath COLLATE NOCASE);
CREATE INDEX IF NOT EXISTS index_photos_dev_ino on photos(dev_ino);
CREATE INDEX IF NOT EXISTS index_photos_override_filename on
photos(override_filename COLLATE NOCASE);
CREATE INDEX IF NOT EXISTS index_photos_created on photos(created);

View file

@ -951,16 +951,19 @@ class Photo(ObjectBase):
self.photodb.log.debug('Reloading metadata for %s', self)
self.bytes = None
self.dev_ino = None
self.width = None
self.height = None
self.area = None
self.ratio = None
self.duration = None
try:
self.bytes = self.real_path.size
except pathclass.NotExists:
pass
if self.real_path.is_file:
stat = self.real_path.stat
self.bytes = stat.st_size
(dev, ino) = (stat.st_dev, stat.st_ino)
if dev and ino:
self.dev_ino = f'{dev},{ino}'
if self.bytes is None:
pass
@ -986,6 +989,7 @@ class Photo(ObjectBase):
'ratio': self.ratio,
'duration': self.duration,
'bytes': self.bytes,
'dev_ino': self.dev_ino,
}
self.photodb.sql_update(table='photos', pairs=data, where_key='id')

View file

@ -389,6 +389,16 @@ class PDBPhotoMixin:
def get_photo(self, id):
return self.get_thing_by_id('photo', id)
def get_photo_by_inode(self, dev, ino):
dev_ino = f'{dev},{ino}'
query = 'SELECT * FROM photos WHERE dev_ino == ?'
bindings = [dev_ino]
photo_row = self.sql_select_one(query, bindings)
if photo_row is None:
raise exceptions.NoSuchPhoto(dev_ino)
photo = self.get_cached_instance('photo', photo_row)
return photo
def get_photo_by_path(self, filepath):
filepath = pathclass.Path(filepath)
query = 'SELECT * FROM photos WHERE filepath == ?'
@ -470,6 +480,7 @@ class PDBPhotoMixin:
'author_id': author_id,
'searchhidden': searchhidden,
# These will be filled in during the metadata stage.
'dev_ino': None,
'bytes': None,
'width': None,
'height': None,

View file

@ -261,6 +261,66 @@ def upgrade_13_to_14(photodb):
photodb.config['user']['max_username_length'] = photodb.config['user'].pop('max_length')
photodb.save_config()
def upgrade_14_to_15(photodb):
'''
Added the dev_ino column to photos.
'''
photodb.sql_execute('PRAGMA foreign_keys = OFF')
photodb.sql_execute('BEGIN')
photodb.sql_execute('ALTER TABLE photos RENAME TO photos_old')
photodb.sql_execute('''
CREATE TABLE photos(
id TEXT PRIMARY KEY NOT NULL,
filepath TEXT COLLATE NOCASE,
dev_ino TEXT,
override_filename TEXT COLLATE NOCASE,
extension TEXT,
width INT,
height INT,
ratio REAL,
area INT,
duration INT,
bytes INT,
created INT,
thumbnail TEXT,
tagged_at INT,
author_id TEXT,
searchhidden INT,
FOREIGN KEY(author_id) REFERENCES users(id)
);
''')
photodb.sql_execute('''
INSERT INTO photos SELECT
id,
filepath,
NULL,
override_filename,
extension,
width,
height,
ratio,
area,
duration,
bytes,
created,
thumbnail,
tagged_at,
author_id,
searchhidden
FROM photos_old
''')
photodb.sql_execute('DROP TABLE photos_old')
photodb.sql_execute('CREATE INDEX index_photos_dev_ino ON photos(dev_ino);')
for photo in photodb.get_photos_by_recent():
if not photo.real_path.is_file:
continue
stat = photo.real_path.stat
(dev, ino) = (stat.st_dev, stat.st_ino)
if dev == 0 or ino == 0:
continue
dev_ino = f'{dev},{ino}'
photodb.sql_execute('UPDATE photos SET dev_ino = ? WHERE id == ?', [dev_ino, photo.id])
def upgrade_all(data_directory):
'''
Given the directory containing a phototagger database, apply all of the