diff --git a/0.5_test/__pycache__/add_func.cpython-311.pyc b/0.5_stable/__pycache__/add_func.cpython-311.pyc similarity index 100% rename from 0.5_test/__pycache__/add_func.cpython-311.pyc rename to 0.5_stable/__pycache__/add_func.cpython-311.pyc diff --git a/0.5_test/__pycache__/dbconnection.cpython-311.pyc b/0.5_stable/__pycache__/dbconnection.cpython-311.pyc similarity index 100% rename from 0.5_test/__pycache__/dbconnection.cpython-311.pyc rename to 0.5_stable/__pycache__/dbconnection.cpython-311.pyc diff --git a/0.5_test/__pycache__/dbtable.cpython-311.pyc b/0.5_stable/__pycache__/dbtable.cpython-311.pyc similarity index 55% rename from 0.5_test/__pycache__/dbtable.cpython-311.pyc rename to 0.5_stable/__pycache__/dbtable.cpython-311.pyc index 57cc343..1d2d43e 100644 Binary files a/0.5_test/__pycache__/dbtable.cpython-311.pyc and b/0.5_stable/__pycache__/dbtable.cpython-311.pyc differ diff --git a/0.5_test/__pycache__/project_config.cpython-311.pyc b/0.5_stable/__pycache__/project_config.cpython-311.pyc similarity index 100% rename from 0.5_test/__pycache__/project_config.cpython-311.pyc rename to 0.5_stable/__pycache__/project_config.cpython-311.pyc diff --git a/0.5_test/__pycache__/texts.cpython-311.pyc b/0.5_stable/__pycache__/texts.cpython-311.pyc similarity index 100% rename from 0.5_test/__pycache__/texts.cpython-311.pyc rename to 0.5_stable/__pycache__/texts.cpython-311.pyc diff --git a/0.5_test/config.yaml b/0.5_stable/config.yaml similarity index 100% rename from 0.5_test/config.yaml rename to 0.5_stable/config.yaml diff --git a/0.5_test/dbconnection.py b/0.5_stable/dbconnection.py similarity index 100% rename from 0.5_test/dbconnection.py rename to 0.5_stable/dbconnection.py diff --git a/0.5_test/dbtable.py b/0.5_stable/dbtable.py similarity index 88% rename from 0.5_test/dbtable.py rename to 0.5_stable/dbtable.py index de7b92c..5dc138a 100644 --- a/0.5_test/dbtable.py +++ b/0.5_stable/dbtable.py @@ -4,7 +4,6 @@ from dbconnection import * ''' FIXME: -1) Не работает санация для insert_one! ''' class DbTable: @@ -55,18 +54,15 @@ class DbTable: for i in range(len(vals)): if type(vals[i]) == str: vals[i] = "'" + vals[i] + "'" + pass else: vals[i] = str(vals[i]) - # sql = "INSERT INTO " + self.table_name() + "(" - # sql += ", ".join(self.column_names_without_id()) + ") VALUES(" - # sql += ", ".join(vals) + ")" - query = "INSERT INTO " + self.table_name() + "(" + ", ".join(self.column_names_without_id()) + ") VALUES(%s)" - print(query) - cur = self.dbconn.conn.cursor() values = ", ".join(vals) + query = f"""INSERT INTO {self.table_name()}({", ".join(self.column_names_without_id())}) VALUES({values})""" + cur = self.dbconn.conn.cursor() # cur.execute(sql) try: - cur.execute(query, (values,)) + cur.execute(query) self.dbconn.conn.commit() except psycopg2.errors.UniqueViolation: self.dbconn.conn.rollback() diff --git a/0.5_test/main.py b/0.5_stable/main.py similarity index 90% rename from 0.5_test/main.py rename to 0.5_stable/main.py index 89d60d5..cc735d6 100644 --- a/0.5_test/main.py +++ b/0.5_stable/main.py @@ -12,10 +12,10 @@ from tables.cath_table import * TODO: 1) Реализовать ввод порядкового номера - done 2) Удалить проверки на "русскоязычный ввод" - done -3) Устранить SQLi с помощью санации атрибутов - Не выполнено +3) Устранить SQLi с помощью санации атрибутов - done +4) UPDATE для отдельный таблиц/общий? FIXME: -1) Не работает санация для insert_one! ''' @@ -40,14 +40,8 @@ class Main: cth = CathTable() dsh = DishTable() - cth.insert_one(["Завтрак"]) - cth.insert_one(["Обэд"]) - cth.insert_one(["Ужин"]) - - dsh.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) - dsh.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) - dsh.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) - dsh.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) + cth.example_insert() + dsh.example_insert() def db_drop(self): cth = CathTable() diff --git a/0.5_test/project_config.py b/0.5_stable/project_config.py similarity index 100% rename from 0.5_test/project_config.py rename to 0.5_stable/project_config.py diff --git a/0.5_test/tables/__pycache__/cath_table.cpython-311.pyc b/0.5_stable/tables/__pycache__/cath_table.cpython-311.pyc similarity index 57% rename from 0.5_test/tables/__pycache__/cath_table.cpython-311.pyc rename to 0.5_stable/tables/__pycache__/cath_table.cpython-311.pyc index 514e2fc..377335f 100644 Binary files a/0.5_test/tables/__pycache__/cath_table.cpython-311.pyc and b/0.5_stable/tables/__pycache__/cath_table.cpython-311.pyc differ diff --git a/0.5_stable/tables/__pycache__/dish_table.cpython-311.pyc b/0.5_stable/tables/__pycache__/dish_table.cpython-311.pyc new file mode 100644 index 0000000..1ee25bb Binary files /dev/null and b/0.5_stable/tables/__pycache__/dish_table.cpython-311.pyc differ diff --git a/0.5_test/tables/cath_table.py b/0.5_stable/tables/cath_table.py similarity index 89% rename from 0.5_test/tables/cath_table.py rename to 0.5_stable/tables/cath_table.py index 40bdb34..9545e22 100644 --- a/0.5_test/tables/cath_table.py +++ b/0.5_stable/tables/cath_table.py @@ -38,3 +38,8 @@ class CathTable(DbTable): # cur.execute(sql, {"offset": num - 1}) # print(cur) + def example_insert(self): + self.insert_one(["Завтрак"]) + self.insert_one(["Обед"]) + self.insert_one(["Ужин"]) + return \ No newline at end of file diff --git a/0.5_test/tables/dish_table.py b/0.5_stable/tables/dish_table.py similarity index 86% rename from 0.5_test/tables/dish_table.py rename to 0.5_stable/tables/dish_table.py index 51833b7..f01817c 100644 --- a/0.5_test/tables/dish_table.py +++ b/0.5_stable/tables/dish_table.py @@ -72,13 +72,6 @@ class DishTable(DbTable): Укажите название удаляемого блюда (0 - отмена): ") if ins_name == "0": return "1" - - elif(add_func.is_cyr_or_dig(ins_name.strip())==0): - ins_name = input("Название должно состоять только из символов кириллицы. Повторите ввод!\ - Укажите название удаляемого блюда (0 - отмена): ") - if ins_name == "0": - return "1" - else: print('Такое блюдо уже существует') ins_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") @@ -98,4 +91,9 @@ class DishTable(DbTable): DishTable().insert_one(insert) - \ No newline at end of file + def example_insert(self): + self.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) + self.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) + self.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) + self.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) + return \ No newline at end of file diff --git a/0.5_test/tables/people_table.py b/0.5_stable/tables/people_table.py similarity index 100% rename from 0.5_test/tables/people_table.py rename to 0.5_stable/tables/people_table.py diff --git a/0.5_test/tables/phones_table.py b/0.5_stable/tables/phones_table.py similarity index 100% rename from 0.5_test/tables/phones_table.py rename to 0.5_stable/tables/phones_table.py diff --git a/0.5_test/texts.py b/0.5_stable/texts.py similarity index 100% rename from 0.5_test/texts.py rename to 0.5_stable/texts.py diff --git a/0.5_test/tables/__pycache__/dish_table.cpython-311.pyc b/0.5_test/tables/__pycache__/dish_table.cpython-311.pyc deleted file mode 100644 index 398b4ea..0000000 Binary files a/0.5_test/tables/__pycache__/dish_table.cpython-311.pyc and /dev/null differ diff --git a/0.6_test/__pycache__/add_func.cpython-311.pyc b/0.6_test/__pycache__/add_func.cpython-311.pyc new file mode 100644 index 0000000..9d04437 Binary files /dev/null and b/0.6_test/__pycache__/add_func.cpython-311.pyc differ diff --git a/0.6_test/__pycache__/dbconnection.cpython-311.pyc b/0.6_test/__pycache__/dbconnection.cpython-311.pyc new file mode 100644 index 0000000..f85e242 Binary files /dev/null and b/0.6_test/__pycache__/dbconnection.cpython-311.pyc differ diff --git a/0.6_test/__pycache__/dbtable.cpython-311.pyc b/0.6_test/__pycache__/dbtable.cpython-311.pyc new file mode 100644 index 0000000..1d2d43e Binary files /dev/null and b/0.6_test/__pycache__/dbtable.cpython-311.pyc differ diff --git a/0.6_test/__pycache__/project_config.cpython-311.pyc b/0.6_test/__pycache__/project_config.cpython-311.pyc new file mode 100644 index 0000000..8815881 Binary files /dev/null and b/0.6_test/__pycache__/project_config.cpython-311.pyc differ diff --git a/0.6_test/__pycache__/texts.cpython-311.pyc b/0.6_test/__pycache__/texts.cpython-311.pyc new file mode 100644 index 0000000..53fc081 Binary files /dev/null and b/0.6_test/__pycache__/texts.cpython-311.pyc differ diff --git a/0.6_test/config.yaml b/0.6_test/config.yaml new file mode 100644 index 0000000..26dda36 --- /dev/null +++ b/0.6_test/config.yaml @@ -0,0 +1,6 @@ +# Базовые параметры настройки конфигурации проекта +dbname: DBProd # В классе менять не надо +user: postgres # Замените на свой логин от БД в классе +password: Qwerty # Замените на свой пароль от БД в классе +host: localhost # Замените на 192.168.0.48 в классе +dbtableprefix: "public." # Замените на свой логин от БД \ No newline at end of file diff --git a/0.6_test/dbconnection.py b/0.6_test/dbconnection.py new file mode 100644 index 0000000..6fac33c --- /dev/null +++ b/0.6_test/dbconnection.py @@ -0,0 +1,34 @@ +# Установка соединения с базой данных +# (параметры передаются через класс конфиг). +import psycopg2 + +class DbConnection: + + def __init__(self, config): + self.dbname = config.dbname + self.user = config.user + self.password = config.password + self.host = config.host + self.prefix = config.dbtableprefix + self.conn = psycopg2.connect(dbname = self.dbname, + user = self.user, + password = self.password, + host = self.host) + + def __del__(self): + if self.conn: + self.conn.close() + + def test(self): + cur = self.conn.cursor() + cur.execute("DROP TABLE IF EXISTS test CASCADE") + cur.execute("CREATE TABLE test(test integer)") + cur.execute("INSERT INTO test(test) VALUES(1)") + self.conn.commit() + cur.execute("SELECT * FROM test") + result = cur.fetchall() + cur.execute("DROP TABLE test") + self.conn.commit() + return (result[0][0] == 1) + + diff --git a/0.6_test/dbtable.py b/0.6_test/dbtable.py new file mode 100644 index 0000000..5dc138a --- /dev/null +++ b/0.6_test/dbtable.py @@ -0,0 +1,117 @@ +# Базовые действия с таблицами + +from dbconnection import * + +''' +FIXME: +''' + +class DbTable: + dbconn = None + + def __init__(self): + return + + def table_name(self): + return self.dbconn.prefix + "table" + + def columns(self): + return {"test": ["integer", "PRIMARY KEY"]} + + def column_names(self): + return sorted(self.columns().keys(), key = lambda x: x) + + def primary_key(self): + return ['id'] + + def column_names_without_id(self): + res = sorted(self.columns().keys(), key = lambda x: x) + if 'id' in res: + res.remove('id') + return res + + def table_constraints(self): + return [] + + def create(self): + sql = "CREATE TABLE " + self.table_name() + "(" + arr = [k + " " + " ".join(v) for k, v in sorted(self.columns().items(), key = lambda x: x[0])] + sql += ", ".join(arr + self.table_constraints()) + sql += ")" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def drop(self): + sql = "DROP TABLE IF EXISTS " + self.table_name() + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def insert_one(self, vals): + for i in range(len(vals)): + if type(vals[i]) == str: + vals[i] = "'" + vals[i] + "'" + pass + else: + vals[i] = str(vals[i]) + values = ", ".join(vals) + query = f"""INSERT INTO {self.table_name()}({", ".join(self.column_names_without_id())}) VALUES({values})""" + cur = self.dbconn.conn.cursor() + # cur.execute(sql) + try: + cur.execute(query) + self.dbconn.conn.commit() + except psycopg2.errors.UniqueViolation: + self.dbconn.conn.rollback() + return + + def first(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def last(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join([x + " DESC" for x in self.primary_key()]) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def all(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + + def select_one(self, **kwargs): + conditions = [] + values = [] + + sorted_kwargs = sorted(kwargs.items(), key=lambda x: x[0]) + + for key, value in sorted_kwargs(): + conditions.append(f"{key}=%s") + values.append(value) + + sql = f"SELECT * FROM {self.table_name()} WHERE " + " AND ".join(conditions) + cur = self.dbconn.conn.cursor() + cur.execute(sql, tuple(values)) + result = cur.fetchone() + cur.close() + + if result: + return True + else: + return False + + + diff --git a/0.6_test/main.py b/0.6_test/main.py new file mode 100644 index 0000000..cc735d6 --- /dev/null +++ b/0.6_test/main.py @@ -0,0 +1,204 @@ +import sys +import texts +sys.path.append('tables') + +from project_config import * +from dbconnection import * + +from tables.dish_table import * +from tables.cath_table import * + +''' +TODO: +1) Реализовать ввод порядкового номера - done +2) Удалить проверки на "русскоязычный ввод" - done +3) Устранить SQLi с помощью санации атрибутов - done +4) UPDATE для отдельный таблиц/общий? + +FIXME: +''' + + +class Main: + + + config = ProjectConfig() + connection = DbConnection(config) + + def __init__(self): + DbTable.dbconn = self.connection + return + + def db_init(self): + cth = CathTable() + d = DishTable() + cth.create() + d.create() + return + + def db_insert_somethings(self): + cth = CathTable() + dsh = DishTable() + + cth.example_insert() + dsh.example_insert() + + def db_drop(self): + cth = CathTable() + d = DishTable() + d.drop() + cth.drop() + return + + def show_main_menu(self): + menu = texts.show_main_menu_txt + print(menu) + return + + def read_next_step(self): + return input("=> ").strip() + + def after_main_menu(self, next_step): + if next_step == "2": + self.db_drop() + self.db_init() + self.db_insert_somethings() + print("Таблицы созданы заново!") + return "0" + elif next_step != "1" and next_step != "9": + print("Выбрано неверное число! Повторите ввод!") + return "0" + else: + return next_step + + def show_cath(self): + self.cath_id = -1 + self.cath_arr = [] + menu = texts.show_cath_1txt + print(menu) + lst = CathTable().all() + + for i in lst: + self.cath_arr.append(str(i[0])) + + for i in range(len(self.cath_arr)): + print(str(i+1) + "\t" + self.cath_arr[i]) + + menu = texts.show_cath_2txt + print(menu) + return + + def after_show_cath(self, next_step): + """Выбор действий после вывода категорий + """ + while True: + if next_step == "4": + x = int(input('Введите номер удаляемой категории(0 - для отмены): ')) + if (x == 0): + return "1" + else: + CathTable().delete(self.cath_arr[x-1]) + return "1" + + elif next_step == "6": #Добавление блюда в категорию + DishTable().insert_dishone(self.cath_id) + next_step = "5" + + elif next_step == "7":#Удаление блюда из категории + x = int(input('Введите номер удаляемого блюда (0 - для отмены): ')) + if(x==0): + pass + else: + DishTable().delete(self.dish_arr[x-1][0]) + next_step = "5" + elif next_step == "5": + next_step = self.show_dish_in_cath() + elif next_step != "0" and next_step != "9" and next_step != "3": + print("Выбрано неверное число! Повторите ввод!") + return "1" + else: + return next_step + + def add_cath(self): + """ + Добавление новой категории в таблицу + """ + data = [] + data.append(input("Введите название (1 - отмена): ").strip()) + if data[0] == "1": + return + while((len(data[0].strip()) == 0)or(len(data[0].strip()) > 32)): + if (len(data[0].strip()) > 32): + data[0] = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() + if data[0] == "1": + return + else: + data[0] = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() + if data[0] == "1": + return + CathTable().insert_one(data) + return + + def show_dish_in_cath(self): + """Вывод всех блюд в выбранной пользователем категории + """ + self.dish_arr = [] + if self.cath_id == -1: + while True: + x = int(input('Выберите номер интересуемой категории (0 - отмена): ')) + if(x==0): + return + else: + self.cath_id = CathTable().find_by_name(self.cath_arr[x-1]) + self.cath_obj = self.cath_arr[x-1] + + print("Выбрана категория: " + self.cath_obj) + print("Блюда:") + print("№\tНазвание\tВремя приготовления\tКраткая инструкция\ + \n-------------------------------------------------------------------------------------") + lst = DishTable().all_by_cath_id(self.cath_id) + + for i in lst: + self.dish_arr.append([i[2], str(i[1]), str(i[4])]) + + for i in range(len(self.dish_arr)): + print(str(i+1) + "\t" + self.dish_arr[i][0] + "\t\t" + self.dish_arr[i][1] + "\t\t\t" + self.dish_arr[i][2]) + + menu = texts.show_dish_in_cath_txt + print(menu) + return self.read_next_step() + + def main_cycle(self): + """Основной цикл программы, регулирующий порядок действий + """ + current_menu = "0" + next_step = None + + while(current_menu != "9"): + + if current_menu == "0": + self.show_main_menu() + next_step = self.read_next_step() + current_menu = self.after_main_menu(next_step) + + elif current_menu == "1": + self.show_cath() + next_step = self.read_next_step() + current_menu = self.after_show_cath(next_step) + + elif current_menu == "2": + self.show_main_menu() + + elif current_menu == "3": + self.add_cath() + current_menu = "1" + + print("До свидания!") + return + + def test(self): + DbTable.dbconn.test() + +m = Main() +# m.test() +m.main_cycle() \ No newline at end of file diff --git a/0.6_test/project_config.py b/0.6_test/project_config.py new file mode 100644 index 0000000..2b451e5 --- /dev/null +++ b/0.6_test/project_config.py @@ -0,0 +1,21 @@ +# Загрузка настроек проекта (в данном случае только настроек соединения с БД) +# из файла config.yaml. +import yaml + +class ProjectConfig: + """Класс считывает базовые настройки из файла config.yaml""" + + def __init__(self): + with open('config.yaml') as f: + config = yaml.safe_load(f) + self.dbname = config['dbname'] + self.user = config['user'] + self.password = config['password'] + self.host = config['host'] + self.dbtableprefix = config['dbtableprefix'] + +# Этот метод запускается только, если запускать +# данный файл, а не подключать его. +if __name__ == "__main__": + x = ProjectConfig() + print(x.dbfilepath) diff --git a/0.6_test/tables/__pycache__/cath_table.cpython-311.pyc b/0.6_test/tables/__pycache__/cath_table.cpython-311.pyc new file mode 100644 index 0000000..377335f Binary files /dev/null and b/0.6_test/tables/__pycache__/cath_table.cpython-311.pyc differ diff --git a/0.6_test/tables/__pycache__/dish_table.cpython-311.pyc b/0.6_test/tables/__pycache__/dish_table.cpython-311.pyc new file mode 100644 index 0000000..1ee25bb Binary files /dev/null and b/0.6_test/tables/__pycache__/dish_table.cpython-311.pyc differ diff --git a/0.6_test/tables/cath_table.py b/0.6_test/tables/cath_table.py new file mode 100644 index 0000000..9545e22 --- /dev/null +++ b/0.6_test/tables/cath_table.py @@ -0,0 +1,45 @@ +# Таблица с категориями и действия с ними + +from dbtable import * + +class CathTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "cath" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "cath_name": ["varchar(32)", "NOT NULL"]} + + def table_constraints(self): + return ['CONSTRAINT "Name" UNIQUE (cath_name)'] + + def delete(self, val): + # sql = "DELETE FROM " + self.table_name() + # sql += " WHERE cath_name" + # sql += "=" + "'" + "".join(val) + "';" + param_sql = "DELETE FROM cath WHERE cath_name = %s;" + cur = self.dbconn.conn.cursor() + value = "".join(val) + cur.execute(param_sql, (value,)) + self.dbconn.conn.commit() + + def find_by_name(self, name): + cur = self.dbconn.conn.cursor() + param_query = "SELECT id FROM cath WHERE cath_name = %s;" + # sql_sel = "SELECT id FROM " + self.table_name() + # sql_sel += " WHERE cath_name = " + "'" + name + "'" + ";" + cur.execute(param_query, (name,)) + ret = cur.fetchone() + return list(ret)[0] + # sql = "SELECT * FROM " + self.table_name() + # sql += " ORDER BY " + # sql += ", ".join(self.primary_key()) + # sql += " LIMIT 1 OFFSET %(offset)s" + # cur.execute(sql, {"offset": num - 1}) + # print(cur) + + def example_insert(self): + self.insert_one(["Завтрак"]) + self.insert_one(["Обед"]) + self.insert_one(["Ужин"]) + return \ No newline at end of file diff --git a/0.6_test/tables/dish_table.py b/0.6_test/tables/dish_table.py new file mode 100644 index 0000000..f01817c --- /dev/null +++ b/0.6_test/tables/dish_table.py @@ -0,0 +1,99 @@ +# Таблица с блюдами и действия с ними + +from dbtable import * + +class DishTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "dish" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "cath_id": ["integer", "REFERENCES cath(id) ON DELETE CASCADE", "NOT NULL"], + "dish_name": ["varchar(32)", "NOT NULL"], + "cook_time": ["interval"], + "manual": ["text"]} + + def table_constraints(self): + return ['CONSTRAINT "Name Dish" UNIQUE (dish_name)'] + + + + def find_by_position(self, num): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + sql += " LIMIT 1 OFFSET %(offset)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {"offset": num - 1}) + return cur.fetchone() + + def all_by_cath_id(self, cath_id): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE cath_id = " + str(cath_id) + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + + def delete(self, val): + sql = "DELETE FROM dish" + sql += " WHERE dish_name" + sql += "=" + "'" + val + "';" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + + def check_by_name(self, value): + sql = f"SELECT * FROM {self.table_name()} WHERE dish_name='{value}'" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + if result: + return True + else: + return False + + def insert_dishone(self, cath_id): + + ins_name = input('Введите название добавляемого блюда (1 - для отмены): ') + + while (ins_name.strip() == '')or(len(ins_name.strip()) > 32)\ + or(DishTable().check_by_name(ins_name)): + + if(ins_name.strip() == ''): + ins_name = input("Пустая строка. Повторите ввод! Укажите название удаляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + elif(len(ins_name.strip()) > 32): + ins_name = input("Слишком длинная строка. Повторите ввод!\ + Укажите название удаляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + else: + print('Такое блюдо уже существует') + ins_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + ins_time = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + if ins_time == "0": + return "1" + ins_manual = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите краткую инструкцию приготовления блюда (1 - для отмены): ') + if ins_time == "0": + return "1" + + insert = [cath_id, ins_time, ins_name, ins_manual] + DishTable().insert_one(insert) + + + def example_insert(self): + self.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) + self.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) + self.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) + self.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) + return \ No newline at end of file diff --git a/0.6_test/tables/people_table.py b/0.6_test/tables/people_table.py new file mode 100644 index 0000000..d27e8ea --- /dev/null +++ b/0.6_test/tables/people_table.py @@ -0,0 +1,23 @@ +# Таблица персоны и особые действия с ней + +from dbtable import * + +class PeopleTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "people" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "last_name": ["varchar(32)", "NOT NULL"], + "first_name": ["varchar(32)", "NOT NULL"], + "second_name": ["varchar(32)"]} + + def find_by_position(self, num): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + sql += " LIMIT 1 OFFSET %(offset)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {"offset": num - 1}) + return cur.fetchone() + diff --git a/0.6_test/tables/phones_table.py b/0.6_test/tables/phones_table.py new file mode 100644 index 0000000..c6326f0 --- /dev/null +++ b/0.6_test/tables/phones_table.py @@ -0,0 +1,27 @@ +# Таблица Телефоны и особые действия с ней. + +from dbtable import * + +class PhonesTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "phones" + + def columns(self): + return {"person_id": ["integer", "REFERENCES people(id)"], + "phone": ["varchar(12)", "NOT NULL"]} + + def primary_key(self): + return ['person_id', 'phone'] + + def table_constraints(self): + return ["PRIMARY KEY(person_id, phone)"] + + def all_by_person_id(self, pid): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE person_id = %s" + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql, str(pid)) + return cur.fetchall() + diff --git a/0.6_test/texts.py b/0.6_test/texts.py new file mode 100644 index 0000000..da2f6df --- /dev/null +++ b/0.6_test/texts.py @@ -0,0 +1,20 @@ +show_main_menu_txt = """Привутствуем в меню, выберите действие: + 1 - просмотр категорий; + 2 - сброс и инициализация БД; + 9 - выход;""" +show_cath_1txt = """Просмотр списка категорий! +№\tНазвание\n-------------------------------------------------------------------------------------""" + +show_cath_2txt = """-------------------------------------------------------------------------------------\nДальнейшие операции: + 0 - возврат в главное меню; + 3 - добавление новой категории; + 4 - удаление категории; + 5 - просмотр блюд в категории; + 9 - выход.""" + +show_dish_in_cath_txt = """-------------------------------------------------------------------------------------\nДальнейшие операции: + 0 - возврат в главное меню; + 1 - возврат в просмотр категорий; + 6 - добавление нового блюда; + 7 - удаление блюда; + 9 - выход.""" \ No newline at end of file