link playlists to a userid

+ fix favorites foreign key
+ add migration to add userid foreign key to playlists table
This commit is contained in:
cwilvx
2024-06-09 11:08:18 +03:00
parent 8fa64b3a4d
commit fcf1469428
6 changed files with 102 additions and 41 deletions
+1 -1
View File
@@ -8,9 +8,9 @@
- Rewrite stores to use dictionaries instead of list pools - Rewrite stores to use dictionaries instead of list pools
- last updated date on tracks added via watchdog is broken - last updated date on tracks added via watchdog is broken
- hide "remove from playlist" option on system playlists - hide "remove from playlist" option on system playlists
- Support auth headers
# DONE # DONE
- Support auth headers
- Add recently played playlist - Add recently played playlist
- Move user track logs to user zero - Move user track logs to user zero
- Move future logs to appropriate user id - Move future logs to appropriate user id
+3 -3
View File
@@ -139,8 +139,8 @@ class SQLiteAuthMethods:
""" """
Delete a user by username. Delete a user by username.
""" """
sql = "DELETE FROM users WHERE username = ?" sql = "DELETE FROM users WHERE id = ?"
print("deleting user: ", username)
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (username,)) cur.execute(sql, (3,))
cur.close() cur.close()
+19 -27
View File
@@ -1,6 +1,8 @@
import json import json
from collections import OrderedDict from collections import OrderedDict
from flask_jwt_extended import current_user
from app.db.sqlite.utils import SQLiteManager, tuple_to_playlist, tuples_to_playlists from app.db.sqlite.utils import SQLiteManager, tuple_to_playlist, tuples_to_playlists
from app.utils.dates import create_new_date from app.utils.dates import create_new_date
@@ -27,10 +29,12 @@ class SQLitePlaylistMethods:
last_updated, last_updated,
name, name,
settings, settings,
trackhashes trackhashes,
) VALUES(:image, :last_updated, :name, :settings, :trackhashes) userid
) VALUES(:image, :last_updated, :name, :settings, :trackhashes, :userid)
""" """
playlist["userid"] = current_user["id"]
playlist = OrderedDict(sorted(playlist.items())) playlist = OrderedDict(sorted(playlist.items()))
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
@@ -41,24 +45,9 @@ class SQLitePlaylistMethods:
p_tuple = (pid, *playlist.values()) p_tuple = (pid, *playlist.values())
return tuple_to_playlist(p_tuple) return tuple_to_playlist(p_tuple)
@staticmethod
def get_playlist_by_name(name: str):
sql = "SELECT * FROM playlists WHERE name = ?"
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (name,))
data = cur.fetchone()
cur.close()
if data is not None:
return tuple_to_playlist(data)
return None
@staticmethod @staticmethod
def count_playlist_by_name(name: str): def count_playlist_by_name(name: str):
sql = "SELECT COUNT(*) FROM playlists WHERE name = ?" sql = f"SELECT COUNT(*) FROM playlists WHERE name = ? and userid = {current_user['id']}"
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (name,)) cur.execute(sql, (name,))
@@ -71,7 +60,7 @@ class SQLitePlaylistMethods:
@staticmethod @staticmethod
def get_all_playlists(): def get_all_playlists():
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute("SELECT * FROM playlists") cur.execute(f"SELECT * FROM playlists WHERE userid = {current_user['id']}")
playlists = cur.fetchall() playlists = cur.fetchall()
cur.close() cur.close()
@@ -82,7 +71,7 @@ class SQLitePlaylistMethods:
@staticmethod @staticmethod
def get_playlist_by_id(playlist_id: int): def get_playlist_by_id(playlist_id: int):
sql = "SELECT * FROM playlists WHERE id = ?" sql = f"SELECT * FROM playlists WHERE id = ? and userid = {current_user['id']}"
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (playlist_id,)) cur.execute(sql, (playlist_id,))
@@ -103,7 +92,7 @@ class SQLitePlaylistMethods:
Adds a string item to a json dumped list using a playlist id and field name. Adds a string item to a json dumped list using a playlist id and field name.
Takes the playlist ID, a field name, an item to add to the field. Takes the playlist ID, a field name, an item to add to the field.
""" """
sql = f"SELECT {field} FROM playlists WHERE id = ?" sql = f"SELECT {field} FROM playlists WHERE id = ? and userid = {current_user['id']}"
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (playlist_id,)) cur.execute(sql, (playlist_id,))
@@ -134,12 +123,12 @@ class SQLitePlaylistMethods:
@classmethod @classmethod
def update_playlist(cls, playlist_id: int, playlist: dict): def update_playlist(cls, playlist_id: int, playlist: dict):
sql = """UPDATE playlists SET sql = f"""UPDATE playlists SET
image = ?, image = ?,
last_updated = ?, last_updated = ?,
name = ?, name = ?,
settings = ? settings = ?
WHERE id = ? WHERE id = ? and userid = {current_user['id']}
""" """
del playlist["id"] del playlist["id"]
@@ -156,7 +145,7 @@ class SQLitePlaylistMethods:
@classmethod @classmethod
def update_settings(cls, playlist_id: int, settings: dict): def update_settings(cls, playlist_id: int, settings: dict):
sql = """UPDATE playlists SET settings = ? WHERE id = ?""" sql = f"""UPDATE playlists SET settings = ? WHERE id = ? and userid = {current_user['id']}"""
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (json.dumps(settings), playlist_id)) cur.execute(sql, (json.dumps(settings), playlist_id))
@@ -165,14 +154,14 @@ class SQLitePlaylistMethods:
@staticmethod @staticmethod
def delete_playlist(pid: str): def delete_playlist(pid: str):
sql = "DELETE FROM playlists WHERE id = ?" sql = f"DELETE FROM playlists WHERE id = ? and userid = {current_user['id']}"
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (pid,)) cur.execute(sql, (pid,))
@staticmethod @staticmethod
def remove_banner(playlistid: int): def remove_banner(playlistid: int):
sql = """UPDATE playlists SET image = NULL WHERE id = ?""" sql = f"""UPDATE playlists SET image = NULL WHERE id = ? and userid = {current_user['id']}"""
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (playlistid,)) cur.execute(sql, (playlistid,))
@@ -186,7 +175,10 @@ class SQLitePlaylistMethods:
sql = """UPDATE playlists SET trackhashes = ? WHERE id = ?""" sql = """UPDATE playlists SET trackhashes = ? WHERE id = ?"""
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
cur.execute("SELECT trackhashes FROM playlists WHERE id = ?", (playlistid,)) cur.execute(
f"SELECT trackhashes FROM playlists WHERE id = ? and userid = {current_user['id']}",
(playlistid,),
)
data = cur.fetchone() data = cur.fetchone()
if data is None: if data is None:
+4 -4
View File
@@ -9,16 +9,16 @@ CREATE TABLE IF NOT EXISTS playlists (
last_updated text not null, last_updated text not null,
name text not null, name text not null,
settings text, settings text,
trackhashes text trackhashes text,
userid integer not null,
constraint fk_users foreign key (userid) references users(id) on delete cascade
); );
CREATE TABLE IF NOT EXISTS favorites ( CREATE TABLE IF NOT EXISTS favorites (
id integer PRIMARY KEY, id integer PRIMARY KEY,
hash text not null, hash text not null,
type text not null, type text not null,
timestamp integer not null default 0, timestamp integer not null default 0
userid integer not null,
foreign key (userid) references users(id) on delete cascade
); );
CREATE TABLE IF NOT EXISTS settings ( CREATE TABLE IF NOT EXISTS settings (
+7 -2
View File
@@ -83,7 +83,9 @@ class SQLiteManager:
def __enter__(self) -> Cursor: def __enter__(self) -> Cursor:
if self.conn is not None: if self.conn is not None:
return self.conn.cursor() cur = self.conn.cursor()
cur.execute("PRAGMA foreign_keys = ON")
return cur
if self.test_db_path: if self.test_db_path:
db_path = self.test_db_path db_path = self.test_db_path
@@ -97,7 +99,10 @@ class SQLiteManager:
db_path, db_path,
timeout=15, timeout=15,
) )
return self.conn.cursor()
cur = self.conn.cursor()
cur.execute("PRAGMA foreign_keys = ON")
return cur
def __exit__(self, exc_type, exc_value, exc_traceback): def __exit__(self, exc_type, exc_value, exc_traceback):
trial_count = 0 trial_count = 0
+68 -4
View File
@@ -83,15 +83,79 @@ class _4AddUserIdToFavoritesTable(Migration):
@staticmethod @staticmethod
def migrate(): def migrate():
# check if userid column exists # check if userid column exists
exists_sql = "select count(*) from pragma_table_info('favorites') where name = 'userid'" exists_sql = (
sql = "ALTER TABLE favorites ADD userid INTEGER NOT NULL DEFAULT 1 REFERENCES users(id) ON DELETE CASCADE" "select count(*) from pragma_table_info('favorites') where name = 'userid'"
)
sql = """
ALTER TABLE favorites ADD userid INTEGER NOT NULL DEFAULT 1;
ALTER TABLE favorites RENAME TO _favorites;
CREATE TABLE IF NOT EXISTS favorites (
id integer PRIMARY KEY,
hash text not null,
type text not null,
timestamp integer not null default 0,
userid integer not null,
constraint fk_users foreign key (userid) references users(id) on delete cascade
);
INSERT INTO favorites SELECT * FROM _favorites;
DROP TABLE _favorites;
"""
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
data = cur.execute(exists_sql) data = cur.execute(exists_sql)
data = data.fetchone() data = data.fetchone()
if data[0] == 1: if data[0] == 1:
return# INFO: column already exists return # INFO: column already exists
cur.executescript(sql) cur.executescript(sql)
class _5AddUserIdToPlaylistsTable(Migration):
"""
Adds a userid column to the playlists table.
"""
@staticmethod
def migrate():
# check if userid column exists
exists_sql = (
"select count(*) from pragma_table_info('playlists') where name = 'userid'"
)
# Add the userid column to the playlists table
# Rename the old table to _playlists
# Create a new playlists table with the userid column
# Then, copy the data from the old table to the new table
# Finally, drop the old table
sql = """
ALTER TABLE playlists ADD userid INTEGER NOT NULL DEFAULT 1;
ALTER TABLE playlists RENAME TO _playlists;
CREATE TABLE IF NOT EXISTS playlists (
id integer PRIMARY KEY,
image text,
last_updated text not null,
name text not null,
settings text,
trackhashes text,
userid integer not null,
constraint fk_users foreign key (userid) references users(id) on delete cascade
);
INSERT INTO playlists SELECT * FROM _playlists;
DROP TABLE _playlists;
"""
with SQLiteManager(userdata_db=True) as cur:
# INFO: Check if the column already exists
data = cur.execute(exists_sql)
data = data.fetchone()
# INFO: If the column already exists, return
if data[0] == 1:
return # INFO: column already exists
# INFO: Execute the sql
cur.executescript(sql)