readcursor -> cursor

This commit is contained in:
dave 2020-10-05 22:41:01 -07:00
parent f3d888be35
commit bfcb528ddf
1 changed files with 109 additions and 109 deletions

View File

@ -9,9 +9,9 @@ logging = logging.getLogger("database")
keys_in_table = ["title", "album", "artist", "type", "size"]
def dict_factory(cursor, row):
def dict_factory(c, row):
d = {}
for idx, col in enumerate(cursor.description):
for idx, col in enumerate(c.description):
d[col[0]] = row[idx]
return d
@ -28,7 +28,7 @@ def hash_password(unicode_string):
return sha512(unicode_string.encode('UTF-8')).hexdigest()
def readcursor(func):
def cursor(func):
"""
Provides a cursor to the wrapped method as the first arg.
"""
@ -37,8 +37,8 @@ def readcursor(func):
if len(args) >= 2 and isinstance(args[1], sqlite3.Cursor):
return func(*args, **kwargs)
else:
with closing(self.db.cursor()) as cursor:
return func(self, cursor, *args[1:], **kwargs)
with closing(self.db.cursor()) as c:
return func(self, c, *args[1:], **kwargs)
return wrapped
@ -135,31 +135,31 @@ class PysonicDatabase(object):
'value' TEXT);""",
"""INSERT INTO meta VALUES ('db_version', '1');"""]
with closing(self.db.cursor()) as cursor:
cursor.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='meta'")
with closing(self.db.cursor()) as c:
c.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='meta'")
# Initialize DB
if len(cursor.fetchall()) == 0:
if len(c.fetchall()) == 0:
logging.warning("Initializing database")
for query in queries:
cursor.execute(query)
cursor.execute("COMMIT")
c.execute(query)
c.execute("COMMIT")
else:
# Migrate if old db exists
# cursor.execute("""UPDATE meta SET value=? WHERE key="db_version";""", (str(version), ))
# c.execute("""UPDATE meta SET value=? WHERE key="db_version";""", (str(version), ))
# logging.warning("db schema is version {}".format(version))
pass
@readcursor
def get_stats(self, cursor):
songs = cursor.execute("SELECT COUNT(*) as cnt FROM songs").fetchone()['cnt']
artists = cursor.execute("SELECT COUNT(*) as cnt FROM artists").fetchone()['cnt']
albums = cursor.execute("SELECT COUNT(*) as cnt FROM albums").fetchone()['cnt']
@cursor
def get_stats(self, c):
songs = c.execute("SELECT COUNT(*) as cnt FROM songs").fetchone()['cnt']
artists = c.execute("SELECT COUNT(*) as cnt FROM artists").fetchone()['cnt']
albums = c.execute("SELECT COUNT(*) as cnt FROM albums").fetchone()['cnt']
return dict(songs=songs, artists=artists, albums=albums)
# Music related
@readcursor
def add_root(self, cursor, path, name="Library"):
@cursor
def add_root(self, c, path, name="Library"):
"""
Add a new library root. Returns the root ID or raises on collision
:param path: normalized absolute path to add to the library
@ -169,14 +169,14 @@ class PysonicDatabase(object):
"""
assert path.startswith("/")
try:
cursor.execute("INSERT INTO libraries ('name', 'path') VALUES (?, ?)", (name, path, ))
cursor.execute("COMMIT")
return cursor.lastrowid
c.execute("INSERT INTO libraries ('name', 'path') VALUES (?, ?)", (name, path, ))
c.execute("COMMIT")
return c.lastrowid
except sqlite3.IntegrityError:
raise DuplicateRootException("Root '{}' already exists".format(path))
@readcursor
def get_libraries(self, cursor, id=None):
@cursor
def get_libraries(self, c, id=None):
libs = []
q = "SELECT * FROM libraries"
params = []
@ -186,13 +186,13 @@ class PysonicDatabase(object):
params.append(id)
if conditions:
q += " WHERE " + " AND ".join(conditions)
cursor.execute(q, params)
for row in cursor:
c.execute(q, params)
for row in c:
libs.append(row)
return libs
@readcursor
def get_artists(self, cursor, id=None, dirid=None, sortby="name", order=None, name_contains=None):
@cursor
def get_artists(self, c, id=None, dirid=None, sortby="name", order=None, name_contains=None):
assert order in ["asc", "desc", None]
artists = []
q = "SELECT * FROM artists"
@ -211,13 +211,13 @@ class PysonicDatabase(object):
q += " WHERE " + " AND ".join(conditions)
if sortby:
q += " ORDER BY {} {}".format(sortby, order.upper() if order else "ASC")
cursor.execute(q, params)
for row in cursor:
c.execute(q, params)
for row in c:
artists.append(row)
return artists
@readcursor
def get_albums(self, cursor, id=None, artist=None, sortby="name", order=None, limit=None, name_contains=None):
@cursor
def get_albums(self, c, id=None, artist=None, sortby="name", order=None, limit=None, name_contains=None):
"""
:param limit: int or tuple of int, int. translates directly to sql logic.
"""
@ -264,13 +264,13 @@ class PysonicDatabase(object):
q += " LIMIT {}".format(limit) if isinstance(limit, int) \
else " LIMIT {}, {}".format(*limit)
cursor.execute(q, params)
for row in cursor:
c.execute(q, params)
for row in c:
albums.append(row)
return albums
@readcursor
def get_songs(self, cursor, id=None, genre=None, sortby="title", order=None, limit=None, title_contains=None):
@cursor
def get_songs(self, c, id=None, genre=None, sortby="title", order=None, limit=None, title_contains=None):
# TODO make this query massively uglier by joining albums and artists so that artistid etc can be a filter
# or maybe lookup those IDs in the library layer?
if order:
@ -326,13 +326,13 @@ class PysonicDatabase(object):
if limit:
q += " LIMIT {}".format(limit) # TODO support limit pagination
cursor.execute(q, params)
for row in cursor:
c.execute(q, params)
for row in c:
songs.append(row)
return songs
@readcursor
def get_genres(self, cursor, genre_id=None):
@cursor
def get_genres(self, c, genre_id=None):
genres = []
q = "SELECT * FROM genres"
params = []
@ -342,19 +342,19 @@ class PysonicDatabase(object):
params.append(genre_id)
if conditions:
q += " WHERE " + " AND ".join(conditions)
cursor.execute(q, params)
for row in cursor:
c.execute(q, params)
for row in c:
genres.append(row)
return genres
@readcursor
def get_cover(self, cursor, coverid):
@cursor
def get_cover(self, c, coverid):
cover = None
for cover in cursor.execute("SELECT * FROM covers WHERE id = ?", (coverid, )):
for cover in c.execute("SELECT * FROM covers WHERE id = ?", (coverid, )):
return cover
@readcursor
def get_subsonic_musicdir(self, cursor, dirid):
@cursor
def get_subsonic_musicdir(self, c, dirid):
"""
The world is a harsh place.
Again, this bullshit exists only to serve subsonic clients. Given a directory ID it returns a dict containing:
@ -367,7 +367,7 @@ class PysonicDatabase(object):
"""
# find directory
dirinfo = None
for dirinfo in cursor.execute("SELECT * FROM dirs WHERE id = ?", (dirid, )):
for dirinfo in c.execute("SELECT * FROM dirs WHERE id = ?", (dirid, )):
pass
assert dirinfo
@ -375,7 +375,7 @@ class PysonicDatabase(object):
# see if it matches the artists or albums table
artist = None
for artist in cursor.execute("SELECT * FROM artists WHERE dir = ?", (dirid, )):
for artist in c.execute("SELECT * FROM artists WHERE dir = ?", (dirid, )):
pass
# if artist:
@ -383,7 +383,7 @@ class PysonicDatabase(object):
if artist:
ret = ("artist", dirinfo, artist)
children = []
for album in cursor.execute("SELECT * FROM albums WHERE artistid = ?", (artist["id"], )):
for album in c.execute("SELECT * FROM albums WHERE artistid = ?", (artist["id"], )):
children.append(("album", album))
ret[2]['children'] = children
return ret
@ -391,45 +391,45 @@ class PysonicDatabase(object):
# else if album:
# get child tracks
album = None
for album in cursor.execute("SELECT * FROM albums WHERE dir = ?", (dirid, )):
for album in c.execute("SELECT * FROM albums WHERE dir = ?", (dirid, )):
pass
if album:
ret = ("album", dirinfo, album)
artist_info = cursor.execute("SELECT * FROM artists WHERE id = ?", (album["artistid"], )).fetchall()[0]
artist_info = c.execute("SELECT * FROM artists WHERE id = ?", (album["artistid"], )).fetchall()[0]
children = []
for song in cursor.execute("SELECT * FROM songs WHERE albumid = ? ORDER BY track, title ASC;", (album["id"], )):
for song in c.execute("SELECT * FROM songs WHERE albumid = ? ORDER BY track, title ASC;", (album["id"], )):
song["_artist"] = artist_info
children.append(("song", song))
ret[2]['children'] = children
return ret
# Playlist related
@readcursor
def add_playlist(self, cursor, ownerid, name, song_ids, public=False):
@cursor
def add_playlist(self, c, ownerid, name, song_ids, public=False):
"""
Create a playlist
"""
now = time()
cursor.execute("INSERT INTO playlists (ownerid, name, public, created, changed) VALUES (?, ?, ?, ?, ?)",
c.execute("INSERT INTO playlists (ownerid, name, public, created, changed) VALUES (?, ?, ?, ?, ?)",
(ownerid, name, public, now, now))
plid = cursor.lastrowid
plid = c.lastrowid
for song_id in song_ids:
self.add_to_playlist(cursor, plid, song_id)
cursor.execute("COMMIT")
self.add_to_playlist(c, plid, song_id)
c.execute("COMMIT")
@readcursor
def add_to_playlist(self, cursor, playlist_id, song_id):
@cursor
def add_to_playlist(self, c, playlist_id, song_id):
# TODO deal with order column
cursor.execute("INSERT INTO playlist_entries (playlistid, songid) VALUES (?, ?)", (playlist_id, song_id))
c.execute("INSERT INTO playlist_entries (playlistid, songid) VALUES (?, ?)", (playlist_id, song_id))
@readcursor
def get_playlist(self, cursor, playlist_id):
return cursor.execute("SELECT * FROM playlists WHERE id=?", (playlist_id, )).fetchone()
@cursor
def get_playlist(self, c, playlist_id):
return c.execute("SELECT * FROM playlists WHERE id=?", (playlist_id, )).fetchone()
@readcursor
def get_playlist_songs(self, cursor, playlist_id):
@cursor
def get_playlist_songs(self, c, playlist_id):
songs = []
q = """
SELECT
@ -451,65 +451,65 @@ class PysonicDatabase(object):
WHERE pe.playlistid = ?
ORDER BY pe.'order' ASC;
"""
for row in cursor.execute(q, (playlist_id, )):
for row in c.execute(q, (playlist_id, )):
songs.append(row)
return songs
@readcursor
def get_playlists(self, cursor, user_id):
@cursor
def get_playlists(self, c, user_id):
playlists = []
for row in cursor.execute("SELECT * FROM playlists WHERE ownerid=? or public=1", (user_id, )):
for row in c.execute("SELECT * FROM playlists WHERE ownerid=? or public=1", (user_id, )):
playlists.append(row)
return playlists
@readcursor
def remove_index_from_playlist(self, cursor, playlist_id, index):
cursor.execute("DELETE FROM playlist_entries WHERE playlistid=? LIMIT ?, 1", (playlist_id, index, ))
cursor.execute("COMMIT")
@cursor
def remove_index_from_playlist(self, c, playlist_id, index):
c.execute("DELETE FROM playlist_entries WHERE playlistid=? LIMIT ?, 1", (playlist_id, index, ))
c.execute("COMMIT")
@readcursor
def empty_playlist(self, cursor, playlist_id):
#TODO combine with # TODO combine with
cursor.execute("DELETE FROM playlist_entries WHERE playlistid=?", (playlist_id, ))
cursor.execute("COMMIT")
@cursor
def empty_playlist(self, c, playlist_id):
#TODO combine with ??
c.execute("DELETE FROM playlist_entries WHERE playlistid=?", (playlist_id, ))
c.execute("COMMIT")
@readcursor
def delete_playlist(self, cursor, playlist_id):
cursor.execute("DELETE FROM playlists WHERE id=?", (playlist_id, ))
cursor.execute("COMMIT")
@cursor
def delete_playlist(self, c, playlist_id):
c.execute("DELETE FROM playlists WHERE id=?", (playlist_id, ))
c.execute("COMMIT")
@readcursor
def update_album_played(self, cursor, album_id, last_played=None):
cursor.execute("UPDATE albums SET played=? WHERE id=?", (last_played, album_id, ))
cursor.execute("COMMIT")
@cursor
def update_album_played(self, c, album_id, last_played=None):
c.execute("UPDATE albums SET played=? WHERE id=?", (last_played, album_id, ))
c.execute("COMMIT")
@readcursor
def increment_album_plays(self, cursor, album_id):
cursor.execute("UPDATE albums SET plays = plays + 1 WHERE id=?", (album_id, ))
cursor.execute("COMMIT")
@cursor
def increment_album_plays(self, c, album_id):
c.execute("UPDATE albums SET plays = plays + 1 WHERE id=?", (album_id, ))
c.execute("COMMIT")
@readcursor
def increment_track_plays(self, cursor, track_id):
cursor.execute("UPDATE songs SET plays = plays + 1 WHERE id=?", (track_id, ))
cursor.execute("COMMIT")
@cursor
def increment_track_plays(self, c, track_id):
c.execute("UPDATE songs SET plays = plays + 1 WHERE id=?", (track_id, ))
c.execute("COMMIT")
# User related
@readcursor
def add_user(self, cursor, username, password, is_admin=False):
cursor.execute("INSERT INTO users (username, password, admin) VALUES (?, ?, ?)",
@cursor
def add_user(self, c, username, password, is_admin=False):
c.execute("INSERT INTO users (username, password, admin) VALUES (?, ?, ?)",
(username, hash_password(password), is_admin))
cursor.execute("COMMIT")
c.execute("COMMIT")
@readcursor
def update_user(self, cursor, username, password, is_admin=False):
cursor.execute("UPDATE users SET password=?, admin=? WHERE username=?;",
@cursor
def update_user(self, c, username, password, is_admin=False):
c.execute("UPDATE users SET password=?, admin=? WHERE username=?;",
(hash_password(password), is_admin, username))
cursor.execute("COMMIT")
c.execute("COMMIT")
@readcursor
def get_user(self, cursor, user):
@cursor
def get_user(self, c, user):
try:
column = "id" if type(user) is int else "username"
return cursor.execute("SELECT * FROM users WHERE {}=?;".format(column), (user, )).fetchall()[0]
return c.execute("SELECT * FROM users WHERE {}=?;".format(column), (user, )).fetchall()[0]
except IndexError:
raise NotFoundError("User doesn't exist")