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 #########################################################################################
DATABASE_VERSION = 14 DATABASE_VERSION = 15
DB_VERSION_PRAGMA = f''' DB_VERSION_PRAGMA = f'''
PRAGMA user_version = {DATABASE_VERSION}; 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( CREATE TABLE IF NOT EXISTS photos(
id TEXT PRIMARY KEY NOT NULL, id TEXT PRIMARY KEY NOT NULL,
filepath TEXT COLLATE NOCASE, filepath TEXT COLLATE NOCASE,
dev_ino TEXT,
override_filename TEXT COLLATE NOCASE, override_filename TEXT COLLATE NOCASE,
extension TEXT, extension TEXT,
width INT, 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_id on photos(id);
CREATE INDEX IF NOT EXISTS index_photos_filepath on photos(filepath COLLATE NOCASE); 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 CREATE INDEX IF NOT EXISTS index_photos_override_filename on
photos(override_filename COLLATE NOCASE); photos(override_filename COLLATE NOCASE);
CREATE INDEX IF NOT EXISTS index_photos_created on photos(created); 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.photodb.log.debug('Reloading metadata for %s', self)
self.bytes = None self.bytes = None
self.dev_ino = None
self.width = None self.width = None
self.height = None self.height = None
self.area = None self.area = None
self.ratio = None self.ratio = None
self.duration = None self.duration = None
try: if self.real_path.is_file:
self.bytes = self.real_path.size stat = self.real_path.stat
except pathclass.NotExists: self.bytes = stat.st_size
pass (dev, ino) = (stat.st_dev, stat.st_ino)
if dev and ino:
self.dev_ino = f'{dev},{ino}'
if self.bytes is None: if self.bytes is None:
pass pass
@ -986,6 +989,7 @@ class Photo(ObjectBase):
'ratio': self.ratio, 'ratio': self.ratio,
'duration': self.duration, 'duration': self.duration,
'bytes': self.bytes, 'bytes': self.bytes,
'dev_ino': self.dev_ino,
} }
self.photodb.sql_update(table='photos', pairs=data, where_key='id') self.photodb.sql_update(table='photos', pairs=data, where_key='id')

View file

@ -389,6 +389,16 @@ class PDBPhotoMixin:
def get_photo(self, id): def get_photo(self, id):
return self.get_thing_by_id('photo', 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): def get_photo_by_path(self, filepath):
filepath = pathclass.Path(filepath) filepath = pathclass.Path(filepath)
query = 'SELECT * FROM photos WHERE filepath == ?' query = 'SELECT * FROM photos WHERE filepath == ?'
@ -470,6 +480,7 @@ class PDBPhotoMixin:
'author_id': author_id, 'author_id': author_id,
'searchhidden': searchhidden, 'searchhidden': searchhidden,
# These will be filled in during the metadata stage. # These will be filled in during the metadata stage.
'dev_ino': None,
'bytes': None, 'bytes': None,
'width': None, 'width': None,
'height': 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.config['user']['max_username_length'] = photodb.config['user'].pop('max_length')
photodb.save_config() 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): def upgrade_all(data_directory):
''' '''
Given the directory containing a phototagger database, apply all of the Given the directory containing a phototagger database, apply all of the