216 lines
5.3 KiB
Python
216 lines
5.3 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk, messagebox
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
DB = ROOT / "address_book.db"
|
|
|
|
root = tk.Tk()
|
|
root.title("Address Book")
|
|
root.geometry("620x620")
|
|
root.resizable(False, False)
|
|
|
|
def connect():
|
|
return sqlite3.connect(DB)
|
|
|
|
def clear_entries():
|
|
f_name.delete(0, tk.END)
|
|
s_name.delete(0, tk.END)
|
|
mob.delete(0, tk.END)
|
|
email.delete(0, tk.END)
|
|
|
|
def submit():
|
|
values = (
|
|
f_name.get().strip(),
|
|
s_name.get().strip(),
|
|
mob.get().strip(),
|
|
email.get().strip(),
|
|
)
|
|
|
|
if not all(values):
|
|
messagebox.showwarning("Missing data", "Please fill in all four fields.")
|
|
return
|
|
|
|
conn = connect()
|
|
c = conn.cursor()
|
|
c.execute(
|
|
"""
|
|
INSERT INTO address_book (f_name, s_name, mob, email)
|
|
VALUES (?, ?, ?, ?)
|
|
""",
|
|
values,
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
clear_entries()
|
|
search()
|
|
|
|
def search():
|
|
conn = connect()
|
|
c = conn.cursor()
|
|
c.execute("""
|
|
SELECT f_name, s_name, mob, email, oid
|
|
FROM address_book
|
|
ORDER BY oid
|
|
""")
|
|
records = c.fetchall()
|
|
conn.close()
|
|
|
|
output.delete("1.0", tk.END)
|
|
|
|
if not records:
|
|
output.insert(tk.END, "No records found.")
|
|
return
|
|
|
|
for record in records:
|
|
output.insert(
|
|
tk.END,
|
|
f"OID: {record[4]} | "
|
|
f"{record[0]} {record[1]} | "
|
|
f"Mobile: {record[2]} | "
|
|
f"Email: {record[3]}\n"
|
|
)
|
|
|
|
def delete_rec():
|
|
oid = id_no.get().strip()
|
|
|
|
if not oid.isdigit():
|
|
messagebox.showwarning("Invalid OID", "Enter a valid numeric OID.")
|
|
return
|
|
|
|
conn = connect()
|
|
c = conn.cursor()
|
|
c.execute("DELETE FROM address_book WHERE oid = ?", (int(oid),))
|
|
deleted = c.rowcount
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
id_no.delete(0, tk.END)
|
|
|
|
if deleted:
|
|
messagebox.showinfo("Deleted", f"Record {oid} was deleted.")
|
|
else:
|
|
messagebox.showwarning("Not found", f"No record with OID {oid} exists.")
|
|
|
|
search()
|
|
|
|
def update_rec():
|
|
oid = id_no.get().strip()
|
|
column = update_column.get()
|
|
value = update_value.get().strip()
|
|
|
|
allowed_columns = {
|
|
"First Name": "f_name",
|
|
"Surname": "s_name",
|
|
"Mobile": "mob",
|
|
"Email": "email",
|
|
}
|
|
|
|
if not oid.isdigit():
|
|
messagebox.showwarning("Invalid OID", "Enter a valid numeric OID.")
|
|
return
|
|
|
|
if not value:
|
|
messagebox.showwarning("Missing value", "Enter the new value.")
|
|
return
|
|
|
|
# The column name cannot be passed as a normal SQL parameter,
|
|
# so only a value from this fixed whitelist is allowed.
|
|
db_column = allowed_columns[column]
|
|
|
|
conn = connect()
|
|
c = conn.cursor()
|
|
|
|
sql = "UPDATE address_book SET {} = ? WHERE oid = ?".format(db_column)
|
|
c.execute(sql, (value, int(oid)))
|
|
updated = c.rowcount
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
if updated:
|
|
messagebox.showinfo(
|
|
"Updated",
|
|
f"Record {oid} was updated successfully."
|
|
)
|
|
id_no.delete(0, tk.END)
|
|
update_value.delete(0, tk.END)
|
|
search()
|
|
else:
|
|
messagebox.showwarning(
|
|
"Not found",
|
|
f"No record with OID {oid} exists."
|
|
)
|
|
|
|
# Create database/table if it does not already exist.
|
|
conn = connect()
|
|
c = conn.cursor()
|
|
c.execute("""
|
|
CREATE TABLE IF NOT EXISTS address_book (
|
|
f_name TEXT,
|
|
s_name TEXT,
|
|
mob TEXT,
|
|
email TEXT
|
|
)
|
|
""")
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
# ---------- GUI ----------
|
|
tk.Label(root, text="First Name").grid(row=0, column=0, sticky="e", padx=8, pady=6)
|
|
f_name = tk.Entry(root, width=35)
|
|
f_name.grid(row=0, column=1, padx=8, pady=6)
|
|
|
|
tk.Label(root, text="Surname").grid(row=1, column=0, sticky="e", padx=8, pady=6)
|
|
s_name = tk.Entry(root, width=35)
|
|
s_name.grid(row=1, column=1, padx=8, pady=6)
|
|
|
|
tk.Label(root, text="Mobile").grid(row=2, column=0, sticky="e", padx=8, pady=6)
|
|
mob = tk.Entry(root, width=35)
|
|
mob.grid(row=2, column=1, padx=8, pady=6)
|
|
|
|
tk.Label(root, text="Email").grid(row=3, column=0, sticky="e", padx=8, pady=6)
|
|
email = tk.Entry(root, width=35)
|
|
email.grid(row=3, column=1, padx=8, pady=6)
|
|
|
|
tk.Button(root, text="Save", command=submit, width=14).grid(
|
|
row=4, column=0, padx=8, pady=10
|
|
)
|
|
tk.Button(root, text="Display all", command=search, width=14).grid(
|
|
row=4, column=1, sticky="w", padx=8, pady=10
|
|
)
|
|
|
|
tk.Label(root, text="Enter OID").grid(row=5, column=0, sticky="e", padx=8, pady=6)
|
|
id_no = tk.Entry(root, width=35)
|
|
id_no.grid(row=5, column=1, padx=8, pady=6)
|
|
|
|
tk.Button(root, text="Delete", command=delete_rec, width=14).grid(
|
|
row=6, column=0, padx=8, pady=8
|
|
)
|
|
|
|
tk.Label(root, text="Update field").grid(row=7, column=0, sticky="e", padx=8, pady=6)
|
|
update_column = ttk.Combobox(
|
|
root,
|
|
values=("First Name", "Surname", "Mobile", "Email"),
|
|
state="readonly",
|
|
width=32,
|
|
)
|
|
update_column.current(0)
|
|
update_column.grid(row=7, column=1, padx=8, pady=6)
|
|
|
|
tk.Label(root, text="New value").grid(row=8, column=0, sticky="e", padx=8, pady=6)
|
|
update_value = tk.Entry(root, width=35)
|
|
update_value.grid(row=8, column=1, padx=8, pady=6)
|
|
|
|
tk.Button(root, text="Update", command=update_rec, width=14).grid(
|
|
row=9, column=0, columnspan=2, pady=8
|
|
)
|
|
|
|
output = tk.Text(root, width=72, height=13, wrap="word")
|
|
output.grid(row=10, column=0, columnspan=2, padx=10, pady=12)
|
|
|
|
search()
|
|
root.mainloop()
|