From 108849f4155c2f011af06fc30095d9cf7aca4885 Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 23 Jun 2018 13:21:11 +0200 Subject: [PATCH] Finished creation of methods for working with CQL --- App/database/__init__.py | 193 +++++++++++++++++++++++++++++- App/db_script_pycharm.ddl | 8 +- Design/DB_STRUCTURE/db_script.cql | 12 +- 3 files changed, 198 insertions(+), 15 deletions(-) diff --git a/App/database/__init__.py b/App/database/__init__.py index b0f904d..c7c9b4f 100644 --- a/App/database/__init__.py +++ b/App/database/__init__.py @@ -1,6 +1,12 @@ +import uuid + from cassandra.cluster import Cluster from cassandra.auth import PlainTextAuthProvider +from collections import namedtuple + +from datetime import datetime + # Singleton class class DatabaseOperationsBase(object): @@ -11,6 +17,8 @@ def __new__(cls, username: str=None, password: str=None): if username is None or password is None: raise ValueError("You must provide the DB user and password at least the first time") DatabaseOperationsBase.__instance = object.__new__(cls) + DatabaseOperationsBase.__instance.__username = username + DatabaseOperationsBase.__instance.__password = password auth_provider = PlainTextAuthProvider(username=username, password=password) cluster = Cluster(auth_provider=auth_provider) DatabaseOperationsBase.__instance.__session = cluster.connect() @@ -26,14 +34,17 @@ def __createTables(self): for query in queries: self.__session.execute(query) + def finishConnection(self): + self.__session.shutdown() + class InsertOperations(DatabaseOperationsBase): def __new__(cls, *args, **kwargs): return super().__new__(cls) def registerNewUser(self, user_id: int, username: str, name: str): - query = """INSERT INTO YouTubeMDApp.User(user_id, username, name) VALUES (%s, %s, %s);""" - self.__session.execute(query, (user_id, username, name)) + query = """INSERT INTO YouTubeMDApp.User(user_id, username, name, first_use) VALUES (%s, %s, %s, %s);""" + self.__session.execute(query, (user_id, username, name, datetime.now())) def registerPreferences(self, user_id: int, audio_quality: str, audio_format: str, os: str, should_ask_metadata: bool): @@ -73,7 +84,8 @@ def registerNewSongForPlaylist(self, playlist_id: str, file_id: str, playlist_qu def registerNewSongMetadata(self, title: str, artist: str, cover: str, duration: str, file_id: str): query = """ - INSERT INTO YouTubeMDApp.metadata(title, artist, cover, duration, music_file_id) VALUES (%s, %s, %s, %s, %s) + INSERT INTO YouTubeMDApp.metadata(title, artist, cover, song_duration, music_file_id) + VALUES (%s, %s, %s, %s, %s) """ self.__session.execute(query, (title, artist, cover, duration, file_id)) @@ -131,7 +143,6 @@ def updateUserDownloads(self, user_id: int): self.__session.execute(query, (user_id, )) def updateUserLastTimeActive(self, user_id: int): - from datetime import datetime query = """ UPDATE YouTubeMDApp.statistics SET last_time_active = %s WHERE user_id = %s """ @@ -152,6 +163,178 @@ def updatePlaylistTimesRequested(self, playlist_id: str): class SelectOperations(DatabaseOperationsBase): def __new__(cls, *args, **kwargs): - super().__new__(cls) + return super().__new__(cls) + + def selectUserData(self, user_id: int): + # type: () -> namedtuple + query = """SELECT username, name FROM YouTubeMDApp.User WHERE user_id = %s""" + return self.__session.execute(query, (user_id, )) + + def selectUserPreferences(self, user_id: int): + # type: () -> namedtuple + query = """ + SELECT audio_quality, audio_format, os, should_ask_metadata FROM YouTubeMDApp.preferences WHERE user_id = %s + """ + return self.__session.execute(query, (user_id, )) + + def selectUserHistoryForUserID(self, user_id: int): + # type: () -> namedtuple + query = """SELECT file_id FROM YouTubeMDApp.history WHERE user_id = %s""" + return self.__session.execute(query, (user_id,)) + + def selectMetadataForMusicID(self, music_id: str): + # type: () -> namedtuple + query = """SELECT title, artist, cover, song_duration FROM YouTubeMDApp.metadata WHERE music_file_id = %s""" + return self.__session.execute(query, (music_id,)) + + def searchMusicByVideoIDAndExtras(self, video_id: str, audio_quality: int, audio_format: int): + # type: () -> namedtuple + query = """ + SELECT file_id FROM YouTubeMDApp.music WHERE (video_id = %s, audio_quality = %s, audio_format = %s, + is_metadata_by_user = %s) + """ + return self.__session.execute(query, (video_id, audio_quality, audio_format, False)) + + def searchPlaylistByIDAndExtras(self, playlist_id: str, playlist_quality: int, playlist_format: int): + # type: () -> namedtuple + query = """ + SELECT playlist_unique_id FROM YouTubeMDApp.playlist WHERE (playlist_id = %s, playlist_quality = %s, + playlist_format = %s) + """ + return self.__session.execute(query, (playlist_id, playlist_quality, playlist_format)) + + def selectSongsOfPlaylist(self, playlist_unique_id: uuid): + # type: () -> namedtuple + query = """ + SELECT music_file_id FROM YouTubeMDApp.playlist_has_music WHERE playlist_unique_id = %s + """ + return self.__session.execute(query, (playlist_unique_id, )) + + def selectStatisticsForUser(self, user_id: int): + # type: () -> namedtuple + query = """ + SELECT lang, downloads, last_time_active FROM YouTubeMDApp.Statistics WHERE user_id = %s + """ + return self.__session.execute(query, (user_id, )) + + def selectTotal24ActiveUsers(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.Statistics WHERE last_time_active >= (%s - 1d) + """ + return self.__session.execute(query, (datetime.now(), )) + + def selectMostDownloadedSong(self): + # type: () -> namedtuple + query = """ + SELECT MAX(times_requested) FROM YouTubeMDApp.music + """ + return self.__session.execute(query) + + def selectMostDownloadedPlaylist(self): + # type: () -> namedtuple + query = """ + SELECT MAX(times_requested) FROM YouTubeMDApp.playlist + """ + return self.__session.execute(query) + + def selectMostUsedGeoLocation(self): + # type: () -> namedtuple + query = """ + SELECT lang, COUNT(lang) AS most_used_lang FROM YouTubeMDApp.Statistics GROUP BY lang ORDER BY most_used_lang + DESC + """ + return self.__session.execute(query) + + def selectTotalUsers(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.User + """ + return self.__session.execute(query) + + def selectTotalRequestedSongs(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(file_id) FROM YouTubeMDApp.music + """ + return self.__session.execute(query) + + def selectTotalSongsRequests(self): + # type: () -> namedtuple + query = """ + SELECT SUM(times_requested) FROM YouTubeMDApp.music + """ + return self.__session.execute(query) + + def selectTotalRequestedPlaylists(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(playlist_unique_id) FROM YouTubeMDApp.playlist + """ + return self.__session.execute(query) + + def selectTotalPlaylistsRequests(self): + # type: () -> namedtuple + query = """ + SELECT SUM(times_requested) FROM YouTubeMDApp.playlist + """ + return self.__session.execute(query) + + def selectMostCommonQuality(self): + # type: () -> namedtuple + query = """ + SELECT audio_quality, COUNT(audio_quality) AS most_used_audio_quality FROM YouTubeMDApp.preferences + GROUP BY audio_quality ORDER BY most_used_audio_quality DESC + """ + return self.__session.execute(query) + + def selectMostCommonFormat(self): + # type: () -> namedtuple + query = """ + SELECT audio_format, COUNT(audio_format) AS most_used_audio_format FROM YouTubeMDApp.preferences + GROUP BY audio_format ORDER BY most_used_audio_format DESC + """ + return self.__session.execute(query) + + def selectMostCommonOS(self): + # type: () -> namedtuple + query = """ + SELECT os, COUNT(os) AS most_used_os FROM YouTubeMDApp.preferences GROUP BY os ORDER BY most_used_os DESC + """ + return self.__session.execute(query) + + def selectUsersRegistered30DaysAgo(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.User WHERE first_use >= (%s - 1mo) + """ + return self.__session.execute(query, (datetime.now(), )) + + def selectUsersRegistered7DaysAgo(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.User WHERE first_use >= (%s - 1w) + """ + return self.__session.execute(query, (datetime.now(), )) + def selectUsersRegisteredLatest24Hours(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.User WHERE first_use >= (%s - 1d) + """ + return self.__session.execute(query, (datetime.now(), )) + def selectUsersRegisteredAYearAgo(self): + # type: () -> namedtuple + query = """ + SELECT COUNT(user_id) FROM YouTubeMDApp.User WHERE first_use >= (%s - 1y) + """ + return self.__session.execute(query, (datetime.now(), )) + + def selectLatestRegisteredUSer(self): + # type: () -> namedtuple + query = """ + SELECT user_id FROM YouTubeMDApp.User WHERE first_use = (SELECT MAX(first_use) FROM YouTubeMDApp.User) + """ + return self.__session.execute(query) diff --git a/App/db_script_pycharm.ddl b/App/db_script_pycharm.ddl index 4c5539d..0445840 100644 --- a/App/db_script_pycharm.ddl +++ b/App/db_script_pycharm.ddl @@ -1,10 +1,10 @@ CREATE KEYSPACE IF NOT EXISTS YouTubeMDApp WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}; USE YouTubeMDApp; CREATE TABLE IF NOT EXISTS history (user_id int NOT NULL, file_id varchar NOT NULL); -CREATE TABLE IF NOT EXISTS metadata (title varchar, artist varchar, cover text, duration varchar, music_file_id varchar NOT NULL, PRIMARY KEY (music_file_id)); +CREATE TABLE IF NOT EXISTS metadata (title varchar, artist varchar, cover text, song_duration duration, music_file_id varchar NOT NULL, PRIMARY KEY (music_file_id)); CREATE TABLE IF NOT EXISTS music (file_id varchar NOT NULL,video_id varchar, audio_quality int, audio_format int, times_requested counter, is_metadata_by_user boolean, PRIMARY KEY (file_id)); -CREATE TABLE IF NOT EXISTS playlist (playlist_id varchar NOT NULL, number_elements int, times_requested counter, PRIMARY KEY (playlist_id)); -CREATE TABLE IF NOT EXISTS playlist_has_music (playlist_playlist_id varchar NOT NULL, music_file_id varchar NOT NULL, playlist_quality int, playlist_format int); +CREATE TABLE IF NOT EXISTS playlist (playlist_unique_id UUID NOT NULL, playlist_id varchar NOT NULL, playlist_quality int, playlist_format int, number_elements int, times_requested counter, PRIMARY KEY (playlist_unique_id)); +CREATE TABLE IF NOT EXISTS playlist_has_music (playlist_unique_id UUID NOT NULL, music_file_id varchar NOT NULL); CREATE TABLE IF NOT EXISTS preferences (audio_quality varchar, audio_format varchar, os varchar, should_ask_metadata boolean, user_id int NOT NULL, PRIMARY KEY (user_id)); -CREATE TABLE IF NOT EXISTS "User" (user_id int NOT NULL, username varchar, name text, PRIMARY KEY (user_id)); +CREATE TABLE IF NOT EXISTS "User" (user_id int NOT NULL, username varchar, name text, first_use datetime, PRIMARY KEY (user_id)); CREATE TABLE IF NOT EXISTS Statistics (lang varchar, downloads counter, last_time_active datetime, user_id int NOT NULL, PRIMARY KEY(user_id)); \ No newline at end of file diff --git a/Design/DB_STRUCTURE/db_script.cql b/Design/DB_STRUCTURE/db_script.cql index ae468fb..0445840 100644 --- a/Design/DB_STRUCTURE/db_script.cql +++ b/Design/DB_STRUCTURE/db_script.cql @@ -1,10 +1,10 @@ CREATE KEYSPACE IF NOT EXISTS YouTubeMDApp WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}; USE YouTubeMDApp; CREATE TABLE IF NOT EXISTS history (user_id int NOT NULL, file_id varchar NOT NULL); -CREATE TABLE IF NOT EXISTS metadata (title varchar, artist varchar, cover text, duration varchar, music_file_id varchar NOT NULL, PRIMARY KEY (music_file_id)); -CREATE TABLE IF NOT EXISTS music (file_id varchar NOT NULL,video_id varchar, audio_quality int, audio_format int, times_requested int, is_metadata_by_user boolean, PRIMARY KEY (file_id)); -CREATE TABLE IF NOT EXISTS playlist (playlist_id varchar NOT NULL, number_elements int, times_requested int, PRIMARY KEY (playlist_id)); -CREATE TABLE IF NOT EXISTS playlist_has_music (playlist_playlist_id varchar NOT NULL, music_file_id varchar NOT NULL, playlist_quality int, playlist_format int); +CREATE TABLE IF NOT EXISTS metadata (title varchar, artist varchar, cover text, song_duration duration, music_file_id varchar NOT NULL, PRIMARY KEY (music_file_id)); +CREATE TABLE IF NOT EXISTS music (file_id varchar NOT NULL,video_id varchar, audio_quality int, audio_format int, times_requested counter, is_metadata_by_user boolean, PRIMARY KEY (file_id)); +CREATE TABLE IF NOT EXISTS playlist (playlist_unique_id UUID NOT NULL, playlist_id varchar NOT NULL, playlist_quality int, playlist_format int, number_elements int, times_requested counter, PRIMARY KEY (playlist_unique_id)); +CREATE TABLE IF NOT EXISTS playlist_has_music (playlist_unique_id UUID NOT NULL, music_file_id varchar NOT NULL); CREATE TABLE IF NOT EXISTS preferences (audio_quality varchar, audio_format varchar, os varchar, should_ask_metadata boolean, user_id int NOT NULL, PRIMARY KEY (user_id)); -CREATE TABLE IF NOT EXISTS "User" (user_id int NOT NULL, username varchar, name text, PRIMARY KEY (user_id)); -CREATE TABLE IF NOT EXISTS Statistics (lang varchar, downloads int, last_time_active datetime, user_id int NOT NULL, PRIMARY KEY(user_id)); \ No newline at end of file +CREATE TABLE IF NOT EXISTS "User" (user_id int NOT NULL, username varchar, name text, first_use datetime, PRIMARY KEY (user_id)); +CREATE TABLE IF NOT EXISTS Statistics (lang varchar, downloads counter, last_time_active datetime, user_id int NOT NULL, PRIMARY KEY(user_id)); \ No newline at end of file