Update to new worms version.

This commit is contained in:
voussoir 2022-07-15 22:30:06 -07:00
parent 12400b407c
commit ca353e9977
No known key found for this signature in database
GPG key ID: 5F7554F8C26DACCB
9 changed files with 131 additions and 122 deletions

View file

@ -56,17 +56,18 @@ def get_videos_from_args(args):
def add_channel_argparse(args): def add_channel_argparse(args):
ycdldb = closest_db() ycdldb = closest_db()
ycdldb.add_channel( with ycdldb.transaction:
channel_id=args.channel_id, ycdldb.add_channel(
automark=args.automark, channel_id=args.channel_id,
download_directory=args.download_directory, automark=args.automark,
get_videos=args.get_videos, download_directory=args.download_directory,
name=args.name, get_videos=args.get_videos,
queuefile_extension=args.queuefile_extension, name=args.name,
) queuefile_extension=args.queuefile_extension,
)
if args.autoyes or interactive.getpermission('Commit?'): if not (args.autoyes or interactive.getpermission('Commit?')):
ycdldb.commit() ycdldb.rollback()
return 0 return 0
@ -97,12 +98,16 @@ def delete_channel_argparse(args):
ycdldb = closest_db() ycdldb = closest_db()
needs_commit = False needs_commit = False
for channel in get_channels_from_args(args): with ycdldb.transaction:
channel.delete() for channel in get_channels_from_args(args):
needs_commit = True channel.delete()
needs_commit = True
if args.autoyes or interactive.getpermission('Commit?'): if not needs_commit:
ycdldb.commit() return 0
if not (args.autoyes or interactive.getpermission('Commit?')):
ycdldb.rollback()
return 0 return 0
@ -110,27 +115,27 @@ def download_video_argparse(args):
ycdldb = closest_db() ycdldb = closest_db()
needs_commit = False needs_commit = False
for video in get_videos_from_args(args): with ycdldb.transaction:
queuefile = ycdldb.download_video( for video in get_videos_from_args(args):
video, queuefile = ycdldb.download_video(
download_directory=args.download_directory, video,
force=args.force, download_directory=args.download_directory,
queuefile_extension=args.queuefile_extension, force=args.force,
) queuefile_extension=args.queuefile_extension,
if queuefile is not None: )
needs_commit = True if queuefile is not None:
needs_commit = True
if not needs_commit: if not needs_commit:
return 0 return 0
if args.autoyes or interactive.getpermission('Commit?'): if not (args.autoyes or interactive.getpermission('Commit?')):
ycdldb.commit() ycdldb.rollback()
return 0 return 0
def init_argparse(args): def init_argparse(args):
ycdldb = ycdl.ycdldb.YCDLDB(create=True) ycdldb = ycdl.ycdldb.YCDLDB(create=True)
ycdldb.commit()
pipeable.stdout(ycdldb.data_directory.absolute_path) pipeable.stdout(ycdldb.data_directory.absolute_path)
return 0 return 0
@ -139,24 +144,25 @@ def refresh_channels_argparse(args):
status = 0 status = 0
ycdldb = closest_db() ycdldb = closest_db()
if args.channels: with ycdldb.transaction:
channels = [ycdldb.get_channel(c) for c in args.channels] if args.channels:
for channel in channels: channels = [ycdldb.get_channel(c) for c in args.channels]
try: for channel in channels:
channel.refresh(force=args.force) try:
needs_commit = True channel.refresh(force=args.force)
except Exception as exc: needs_commit = True
log.warning(traceback.format_exc()) except Exception as exc:
status = 1 log.warning(traceback.format_exc())
else: status = 1
excs = ycdldb.refresh_all_channels(force=args.force, skip_failures=True) else:
needs_commit = True excs = ycdldb.refresh_all_channels(force=args.force, skip_failures=True)
needs_commit = True
if not needs_commit: if not needs_commit:
return status return status
if args.autoyes or interactive.getpermission('Commit?'): if not (args.autoyes or interactive.getpermission('Commit?')):
ycdldb.commit() ycdldb.rollback()
return status return status

View file

@ -73,6 +73,10 @@ def init_ycdldb(*args, **kwargs):
global ycdldb global ycdldb
ycdldb = ycdl.ycdldb.YCDLDB.closest_ycdldb(*args, **kwargs) ycdldb = ycdl.ycdldb.YCDLDB.closest_ycdldb(*args, **kwargs)
def refresh_all_channels():
with ycdldb.transaction:
ycdldb.refresh_all_channels(force=False, skip_failures=True)
def refresher_thread(rate): def refresher_thread(rate):
global last_refresh global last_refresh
while True: while True:
@ -87,8 +91,7 @@ def refresher_thread(rate):
log.info('Starting refresh job.') log.info('Starting refresh job.')
refresh_job = threading.Thread( refresh_job = threading.Thread(
target=ycdldb.refresh_all_channels, target=refresh_all_channels,
kwargs={'force': False, 'skip_failures': True, 'commit': True},
daemon=True, daemon=True,
) )
refresh_job.start() refresh_job.start()

View file

@ -18,7 +18,8 @@ def _get_or_insert_video(video_id):
try: try:
video = common.ycdldb.get_video(video_id) video = common.ycdldb.get_video(video_id)
except ycdl.exceptions.NoSuchVideo: except ycdl.exceptions.NoSuchVideo:
video = common.ycdldb.insert_video(video_id)['video'] with common.ycdldb.transaction:
video = common.ycdldb.insert_video(video_id)['video']
return video return video
@site.route('/all_channels.json') @site.route('/all_channels.json')
@ -67,9 +68,13 @@ def _render_videos_listing(videos, channel, state, orderby):
@site.route('/channel/<channel_id>/<state>') @site.route('/channel/<channel_id>/<state>')
def get_channel(channel_id, state=None): def get_channel(channel_id, state=None):
try: try:
channel = common.ycdldb.add_channel(channel_id, commit=True) channel = common.ycdldb.get_channel(channel_id)
except ycdl.ytapi.ChannelNotFound: except ycdl.exceptions.NoSuchChannel:
flask.abort(404) try:
with common.ycdldb.transaction:
channel = common.ycdldb.add_channel(channel_id)
except ycdl.ytapi.ChannelNotFound:
flask.abort(404)
orderby = request.args.get('orderby', None) orderby = request.args.get('orderby', None)
@ -116,7 +121,8 @@ def post_add_channel():
except ycdl.ytapi.ChannelNotFound: except ycdl.ytapi.ChannelNotFound:
return flasktools.json_response({}, status=404) return flasktools.json_response({}, status=404)
channel = common.ycdldb.add_channel(channel_id, get_videos=True, commit=True) with common.ycdldb.transaction:
channel = common.ycdldb.add_channel(channel_id, get_videos=True)
return flasktools.json_response(channel.jsonify()) return flasktools.json_response(channel.jsonify())
@site.route('/channel/<channel_id>/delete', methods=['POST']) @site.route('/channel/<channel_id>/delete', methods=['POST'])
@ -126,7 +132,8 @@ def post_delete_channel(channel_id):
except ycdl.exceptions.NoSuchChannel as exc: except ycdl.exceptions.NoSuchChannel as exc:
return flasktools.json_response(exc.jsonify(), status=404) return flasktools.json_response(exc.jsonify(), status=404)
channel.delete(commit=True) with common.ycdldb.transaction:
channel.delete()
response = {'id': channel.id, 'deleted': channel.deleted} response = {'id': channel.id, 'deleted': channel.deleted}
return flasktools.json_response(response) return flasktools.json_response(response)
@ -139,14 +146,16 @@ def post_refresh_channel(channel_id):
except ycdl.exceptions.NoSuchChannel as exc: except ycdl.exceptions.NoSuchChannel as exc:
return flasktools.json_response(exc.jsonify(), status=404) return flasktools.json_response(exc.jsonify(), status=404)
channel.refresh(force=force, commit=True) with common.ycdldb.transaction:
channel.refresh(force=force)
return flasktools.json_response(channel.jsonify()) return flasktools.json_response(channel.jsonify())
@site.route('/refresh_all_channels', methods=['POST']) @site.route('/refresh_all_channels', methods=['POST'])
def post_refresh_all_channels(): def post_refresh_all_channels():
force = request.form.get('force', False) force = request.form.get('force', False)
force = stringtools.truthystring(force, False) force = stringtools.truthystring(force, False)
common.ycdldb.refresh_all_channels(force=force, skip_failures=True, commit=True) with common.ycdldb.transaction:
common.ycdldb.refresh_all_channels(force=force, skip_failures=True)
common.last_refresh = time.time() common.last_refresh = time.time()
return flasktools.json_response({}) return flasktools.json_response({})
@ -157,7 +166,8 @@ def post_set_automark(channel_id):
channel = common.ycdldb.get_channel(channel_id) channel = common.ycdldb.get_channel(channel_id)
try: try:
channel.set_automark(state, commit=True) with common.ycdldb.transaction:
channel.set_automark(state)
except ycdl.exceptions.InvalidVideoState as exc: except ycdl.exceptions.InvalidVideoState as exc:
return flasktools.json_response(exc.jsonify(), status=400) return flasktools.json_response(exc.jsonify(), status=400)
@ -172,7 +182,8 @@ def post_set_autorefresh(channel_id):
try: try:
autorefresh = stringtools.truthystring(autorefresh) autorefresh = stringtools.truthystring(autorefresh)
channel.set_autorefresh(autorefresh, commit=True) with common.ycdldb.transaction:
channel.set_autorefresh(autorefresh)
except (ValueError, TypeError): except (ValueError, TypeError):
flask.abort(400) flask.abort(400)
@ -186,7 +197,8 @@ def post_set_download_directory(channel_id):
channel = common.ycdldb.get_channel(channel_id) channel = common.ycdldb.get_channel(channel_id)
try: try:
channel.set_download_directory(download_directory, commit=True) with common.ycdldb.transaction:
channel.set_download_directory(download_directory)
except pathclass.NotDirectory: except pathclass.NotDirectory:
exc = { exc = {
'error_type': 'NOT_DIRECTORY', 'error_type': 'NOT_DIRECTORY',
@ -204,7 +216,8 @@ def post_set_name(channel_id):
name = request.form['name'] name = request.form['name']
channel = common.ycdldb.get_channel(channel_id) channel = common.ycdldb.get_channel(channel_id)
channel.set_name(name, commit=True) with common.ycdldb.transaction:
channel.set_name(name)
response = {'id': channel.id, 'name': channel.name} response = {'id': channel.id, 'name': channel.name}
return flasktools.json_response(response) return flasktools.json_response(response)
@ -215,7 +228,8 @@ def post_set_queuefile_extension(channel_id):
extension = request.form['extension'] extension = request.form['extension']
channel = common.ycdldb.get_channel(channel_id) channel = common.ycdldb.get_channel(channel_id)
channel.set_queuefile_extension(extension, commit=True) with common.ycdldb.transaction:
channel.set_queuefile_extension(extension)
response = {'id': channel.id, 'queuefile_extension': channel.queuefile_extension} response = {'id': channel.id, 'queuefile_extension': channel.queuefile_extension}
return flasktools.json_response(response) return flasktools.json_response(response)

View file

@ -22,9 +22,9 @@ def post_mark_video_state():
return flasktools.json_response(exc.jsonify(), status=404) return flasktools.json_response(exc.jsonify(), status=404)
try: try:
for video in videos: with common.ycdldb.transaction:
video.mark_state(state, commit=False) for video in videos:
common.ycdldb.commit() video.mark_state(state)
except ycdl.exceptions.InvalidVideoState as exc: except ycdl.exceptions.InvalidVideoState as exc:
common.ycdldb.rollback() common.ycdldb.rollback()
return flasktools.json_response(exc.jsonify(), status=400) return flasktools.json_response(exc.jsonify(), status=400)
@ -42,8 +42,8 @@ def post_start_download():
except ycdl.exceptions.NoSuchVideo as exc: except ycdl.exceptions.NoSuchVideo as exc:
return flasktools.json_response(exc.jsonify(), status=404) return flasktools.json_response(exc.jsonify(), status=404)
for video in videos: with common.ycdldb.transaction:
common.ycdldb.download_video(video, commit=False) for video in videos:
common.ycdldb.commit() common.ycdldb.download_video(video)
return flasktools.json_response({'video_ids': video_ids, 'state': 'downloaded'}) return flasktools.json_response({'video_ids': video_ids, 'state': 'downloaded'})

View file

@ -44,7 +44,7 @@ class Migrator:
# be pointing to the version of B which has not been reconstructed yet, # be pointing to the version of B which has not been reconstructed yet,
# which is about to get renamed to B_old and then A's reference will be # which is about to get renamed to B_old and then A's reference will be
# broken. # broken.
self.ycdldb.sql_execute('PRAGMA foreign_keys = OFF') self.ycdldb.pragma_write('foreign_keys', 'OFF')
self.ycdldb.sql_execute('BEGIN') self.ycdldb.sql_execute('BEGIN')
for (name, table) in self.tables.items(): for (name, table) in self.tables.items():
if name not in self.existing_tables: if name not in self.existing_tables:
@ -323,8 +323,7 @@ def upgrade_all(data_directory):
cur = ycdldb.sql.cursor() cur = ycdldb.sql.cursor()
cur.execute('PRAGMA user_version') current_version = ycdldb.pragma_read('user_version')
current_version = cur.fetchone()[0]
needed_version = ycdl.constants.DATABASE_VERSION needed_version = ycdl.constants.DATABASE_VERSION
if current_version == needed_version: if current_version == needed_version:
@ -336,15 +335,10 @@ def upgrade_all(data_directory):
upgrade_function = 'upgrade_%d_to_%d' % (current_version, version_number) upgrade_function = 'upgrade_%d_to_%d' % (current_version, version_number)
upgrade_function = eval(upgrade_function) upgrade_function = eval(upgrade_function)
try: with ycdldb.transaction:
ycdldb.sql.execute('PRAGMA foreign_keys = ON') ycdldb.pragma_write('foreign_keys', 'ON')
upgrade_function(ycdldb) upgrade_function(ycdldb)
except Exception as exc: ycdldb.pragma_write('user_version', version_number)
ycdldb.rollback()
raise
else:
ycdldb.sql.cursor().execute('PRAGMA user_version = %d' % version_number)
ycdldb.commit()
current_version = version_number current_version = version_number
print('Upgrades finished.') print('Upgrades finished.')

View file

@ -24,8 +24,8 @@ def merge_db(from_db_path, to_db_path, channel):
to_db = sqlite3.connect(to_db_path) to_db = sqlite3.connect(to_db_path)
from_db = sqlite3.connect(from_db_path) from_db = sqlite3.connect(from_db_path)
to_version = to_db.execute('PRAGMA user_version').fetchone()[0] to_version = to_db.pragma_read('user_version')
from_version = from_db.execute('PRAGMA user_version').fetchone()[0] from_version = from_db.pragma_read('user_version')
if to_version != from_version: if to_version != from_version:
raise Exception(f'Databases have different versions: to={to_version}, from={from_version}.') raise Exception(f'Databases have different versions: to={to_version}, from={from_version}.')

View file

@ -1,19 +1,8 @@
from voussoirkit import sqlhelpers from voussoirkit import sqlhelpers
DATABASE_VERSION = 10 DATABASE_VERSION = 10
DB_VERSION_PRAGMA = f'''
PRAGMA user_version = {DATABASE_VERSION};
'''
DB_PRAGMAS = f'''
PRAGMA cache_size = 10000;
'''
DB_INIT = f''' DB_INIT = f'''
BEGIN;
----------------------------------------------------------------------------------------------------
{DB_PRAGMAS}
{DB_VERSION_PRAGMA}
CREATE TABLE IF NOT EXISTS channels( CREATE TABLE IF NOT EXISTS channels(
id TEXT, id TEXT,
name TEXT, name TEXT,
@ -23,6 +12,8 @@ CREATE TABLE IF NOT EXISTS channels(
automark TEXT, automark TEXT,
autorefresh INT autorefresh INT
); );
CREATE INDEX IF NOT EXISTS index_channel_id on channels(id);
----------------------------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS videos( CREATE TABLE IF NOT EXISTS videos(
id TEXT, id TEXT,
published INT, published INT,
@ -35,15 +26,11 @@ CREATE TABLE IF NOT EXISTS videos(
live_broadcast TEXT, live_broadcast TEXT,
state TEXT state TEXT
); );
CREATE INDEX IF NOT EXISTS index_channel_id on channels(id);
CREATE INDEX IF NOT EXISTS index_video_author_published on videos(author_id, published); CREATE INDEX IF NOT EXISTS index_video_author_published on videos(author_id, published);
CREATE INDEX IF NOT EXISTS index_video_author_state_published on videos(author_id, state, published); CREATE INDEX IF NOT EXISTS index_video_author_state_published on videos(author_id, state, published);
CREATE INDEX IF NOT EXISTS index_video_id on videos(id); CREATE INDEX IF NOT EXISTS index_video_id on videos(id);
CREATE INDEX IF NOT EXISTS index_video_published on videos(published); CREATE INDEX IF NOT EXISTS index_video_published on videos(published);
CREATE INDEX IF NOT EXISTS index_video_state_published on videos(state, published); CREATE INDEX IF NOT EXISTS index_video_state_published on videos(state, published);
----------------------------------------------------------------------------------------------------
COMMIT;
''' '''
SQL_COLUMNS = sqlhelpers.extract_table_column_map(DB_INIT) SQL_COLUMNS = sqlhelpers.extract_table_column_map(DB_INIT)

View file

@ -133,12 +133,13 @@ class Channel(ObjectBase):
videos = self.ycdldb.youtube.get_videos(new_ids) videos = self.ycdldb.youtube.get_videos(new_ids)
return videos return videos
@worms.transaction @worms.atomic
def delete(self): def delete(self):
log.info('Deleting %s.', self) log.info('Deleting %s.', self)
self.ycdldb.delete(table='videos', pairs={'author_id': self.id}) self.ycdldb.delete(table='videos', pairs={'author_id': self.id})
self.ycdldb.delete(table='channels', pairs={'id': self.id}) self.ycdldb.delete(table='channels', pairs={'id': self.id})
self.deleted = True
def get_most_recent_video_id(self) -> str: def get_most_recent_video_id(self) -> str:
''' '''
@ -172,7 +173,7 @@ class Channel(ObjectBase):
} }
return j return j
@worms.transaction @worms.atomic
def refresh(self, *, force=False, rss_assisted=True): def refresh(self, *, force=False, rss_assisted=True):
''' '''
Fetch new videos on the channel. Fetch new videos on the channel.
@ -251,7 +252,7 @@ class Channel(ObjectBase):
self.set_uploads_playlist_id(self.uploads_playlist) self.set_uploads_playlist_id(self.uploads_playlist)
return self.uploads_playlist return self.uploads_playlist
@worms.transaction @worms.atomic
def set_automark(self, state): def set_automark(self, state):
self.ycdldb.assert_valid_state(state) self.ycdldb.assert_valid_state(state)
@ -262,7 +263,7 @@ class Channel(ObjectBase):
self.ycdldb.update(table='channels', pairs=pairs, where_key='id') self.ycdldb.update(table='channels', pairs=pairs, where_key='id')
self.automark = state self.automark = state
@worms.transaction @worms.atomic
def set_autorefresh(self, autorefresh): def set_autorefresh(self, autorefresh):
autorefresh = self.normalize_autorefresh(autorefresh) autorefresh = self.normalize_autorefresh(autorefresh)
@ -273,7 +274,7 @@ class Channel(ObjectBase):
self.ycdldb.update(table='channels', pairs=pairs, where_key='id') self.ycdldb.update(table='channels', pairs=pairs, where_key='id')
self.autorefresh = autorefresh self.autorefresh = autorefresh
@worms.transaction @worms.atomic
def set_download_directory(self, download_directory): def set_download_directory(self, download_directory):
download_directory = self.normalize_download_directory(download_directory) download_directory = self.normalize_download_directory(download_directory)
@ -284,7 +285,7 @@ class Channel(ObjectBase):
self.ycdldb.update(table='channels', pairs=pairs, where_key='id') self.ycdldb.update(table='channels', pairs=pairs, where_key='id')
self.download_directory = download_directory self.download_directory = download_directory
@worms.transaction @worms.atomic
def set_name(self, name): def set_name(self, name):
name = self.normalize_name(name) name = self.normalize_name(name)
@ -295,7 +296,7 @@ class Channel(ObjectBase):
self.ycdldb.update(table='channels', pairs=pairs, where_key='id') self.ycdldb.update(table='channels', pairs=pairs, where_key='id')
self.name = name self.name = name
@worms.transaction @worms.atomic
def set_queuefile_extension(self, queuefile_extension): def set_queuefile_extension(self, queuefile_extension):
queuefile_extension = self.normalize_queuefile_extension(queuefile_extension) queuefile_extension = self.normalize_queuefile_extension(queuefile_extension)
@ -306,7 +307,7 @@ class Channel(ObjectBase):
self.ycdldb.update(table='channels', pairs=pairs, where_key='id') self.ycdldb.update(table='channels', pairs=pairs, where_key='id')
self.queuefile_extension = queuefile_extension self.queuefile_extension = queuefile_extension
@worms.transaction @worms.atomic
def set_uploads_playlist_id(self, playlist_id): def set_uploads_playlist_id(self, playlist_id):
log.debug('Setting %s upload playlist to %s.', self, playlist_id) log.debug('Setting %s upload playlist to %s.', self, playlist_id)
if not isinstance(playlist_id, str): if not isinstance(playlist_id, str):
@ -347,11 +348,12 @@ class Video(ObjectBase):
except exceptions.NoSuchChannel: except exceptions.NoSuchChannel:
return None return None
@worms.transaction @worms.atomic
def delete(self): def delete(self):
log.info('Deleting %s.', self) log.info('Deleting %s.', self)
self.ycdldb.delete(table='videos', pairs={'id': self.id}) self.ycdldb.delete(table='videos', pairs={'id': self.id})
self.deleted = True
def jsonify(self): def jsonify(self):
j = { j = {
@ -367,7 +369,7 @@ class Video(ObjectBase):
} }
return j return j
@worms.transaction @worms.atomic
def mark_state(self, state): def mark_state(self, state):
''' '''
Mark the video as ignored, pending, or downloaded. Mark the video as ignored, pending, or downloaded.

View file

@ -22,7 +22,7 @@ class YCDLDBChannelMixin:
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@worms.transaction @worms.atomic
def add_channel( def add_channel(
self, self,
channel_id, channel_id,
@ -88,7 +88,7 @@ class YCDLDBChannelMixin:
def get_channels_by_sql(self, query, bindings=None): def get_channels_by_sql(self, query, bindings=None):
return self.get_objects_by_sql(objects.Channel, query, bindings) return self.get_objects_by_sql(objects.Channel, query, bindings)
@worms.transaction @worms.atomic
def _rss_assisted_refresh(self, channels, skip_failures=False): def _rss_assisted_refresh(self, channels, skip_failures=False):
''' '''
Youtube provides RSS feeds for every channel. These feeds do not Youtube provides RSS feeds for every channel. These feeds do not
@ -155,7 +155,7 @@ class YCDLDBChannelMixin:
return excs return excs
@worms.transaction @worms.atomic
def refresh_all_channels( def refresh_all_channels(
self, self,
*, *,
@ -186,7 +186,7 @@ class YCDLDBVideoMixin:
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@worms.transaction @worms.atomic
def download_video( def download_video(
self, self,
video, video,
@ -300,9 +300,9 @@ class YCDLDBVideoMixin:
query = 'SELECT * FROM videos' + wheres + orderbys query = 'SELECT * FROM videos' + wheres + orderbys
log.debug('%s %s', query, bindings) # log.debug('%s %s', query, bindings)
explain = self.execute('EXPLAIN QUERY PLAN ' + query, bindings) # explain = self.execute('EXPLAIN QUERY PLAN ' + query, bindings)
log.debug('\n'.join(str(x) for x in explain.fetchall())) # log.debug('\n'.join(str(x) for x in explain.fetchall()))
rows = self.select(query, bindings) rows = self.select(query, bindings)
for row in rows: for row in rows:
@ -311,14 +311,14 @@ class YCDLDBVideoMixin:
def get_videos_by_sql(self, query, bindings=None): def get_videos_by_sql(self, query, bindings=None):
return self.get_objects_by_sql(objects.Video, query, bindings) return self.get_objects_by_sql(objects.Video, query, bindings)
@worms.transaction @worms.atomic
def insert_playlist(self, playlist_id): def insert_playlist(self, playlist_id):
video_generator = self.youtube.get_playlist_videos(playlist_id) video_generator = self.youtube.get_playlist_videos(playlist_id)
results = [self.insert_video(video) for video in video_generator] results = [self.insert_video(video) for video in video_generator]
return results return results
@worms.transaction @worms.atomic
def ingest_video(self, video): def ingest_video(self, video):
''' '''
Call `insert_video`, and additionally use the channel's automark to Call `insert_video`, and additionally use the channel's automark to
@ -353,7 +353,7 @@ class YCDLDBVideoMixin:
return status return status
@worms.transaction @worms.atomic
def insert_video(self, video, *, add_channel=True): def insert_video(self, video, *, add_channel=True):
if not isinstance(video, ytapi.Video): if not isinstance(video, ytapi.Video):
video = self.youtube.get_video(video) video = self.youtube.get_video(video)
@ -443,13 +443,14 @@ class YCDLDB(
# WORMS # WORMS
self._init_column_index() self._init_column_index()
self._init_caches() self._init_caches()
self.id_type = str
def _check_version(self): def _check_version(self):
''' '''
Compare database's user_version against constants.DATABASE_VERSION, Compare database's user_version against constants.DATABASE_VERSION,
raising exceptions.DatabaseOutOfDate if not correct. raising exceptions.DatabaseOutOfDate if not correct.
''' '''
existing = self.execute('PRAGMA user_version').fetchone()[0] existing = self.pragma_read('user_version')
if existing != constants.DATABASE_VERSION: if existing != constants.DATABASE_VERSION:
raise exceptions.DatabaseOutOfDate( raise exceptions.DatabaseOutOfDate(
existing=existing, existing=existing,
@ -475,25 +476,27 @@ class YCDLDB(
raise FileNotFoundError(msg) raise FileNotFoundError(msg)
self.data_directory.makedirs(exist_ok=True) self.data_directory.makedirs(exist_ok=True)
self.sql = sqlite3.connect(self.database_filepath) self.sql_read = self._make_sqlite_read_connection(self.database_filepath)
self.sql.row_factory = sqlite3.Row self.sql_write = self._make_sqlite_write_connection(self.database_filepath)
if existing_database: if existing_database:
if not skip_version_check: if not skip_version_check:
self._check_version() self._check_version()
self._load_pragmas() with self.transaction:
self._load_pragmas()
else: else:
self._first_time_setup() self._first_time_setup()
def _first_time_setup(self): def _first_time_setup(self):
log.info('Running first-time database setup.') log.info('Running first-time database setup.')
self.executescript(constants.DB_INIT) with self.transaction:
self.commit() self._load_pragmas()
self.pragma_write('user_version', constants.DATABASE_VERSION)
self.executescript(constants.DB_INIT)
def _load_pragmas(self): def _load_pragmas(self):
log.debug('Reloading pragmas.') log.debug('Reloading pragmas.')
self.executescript(constants.DB_PRAGMAS) self.pragma_write('cache_size', 10000)
self.commit()
@classmethod @classmethod
def closest_ycdldb(cls, youtube=None, path='.', *args, **kwargs): def closest_ycdldb(cls, youtube=None, path='.', *args, **kwargs):