py-dbms-cli 2.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py-dbms-cli
3
- Version: 2.0
4
- Summary: A modern, secure, aesthetic and your ultimate DBMS client supporting MySQL and more.
3
+ Version: 2.1.0
4
+ Summary: A modern, secure, aesthetic and your ultimate DBMS client. Implemented as a CLI (Command-Line Interface) tool and written 100% in Python
5
5
  Author-email: Anish Sethi <sethi.dynasty123@gmail.com>
6
6
  License: Copyright 2025 Anish Sethi
7
7
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py-dbms-cli
3
- Version: 2.0
4
- Summary: A modern, secure, aesthetic and your ultimate DBMS client supporting MySQL and more.
3
+ Version: 2.1.0
4
+ Summary: A modern, secure, aesthetic and your ultimate DBMS client. Implemented as a CLI (Command-Line Interface) tool and written 100% in Python
5
5
  Author-email: Anish Sethi <sethi.dynasty123@gmail.com>
6
6
  License: Copyright 2025 Anish Sethi
7
7
 
@@ -1,10 +1,12 @@
1
1
  #Global functions and variables used across all/major files
2
2
 
3
3
  from .dependencies import Console, time, sys, os
4
+ from .config import load_config
4
5
 
5
6
  console=Console()
7
+ config = load_config()
6
8
 
7
- def Print(message, color_key="WHITE", style="", type=True):
9
+ def Print(message: str, color_key="WHITE", style="", type=True) -> None:
8
10
  COLOR_MAP = {
9
11
  "CYAN": "bright_cyan",
10
12
  "YELLOW": "bright_yellow",
@@ -22,7 +24,7 @@ def Print(message, color_key="WHITE", style="", type=True):
22
24
  console.print(char, style=f"{style} {color}", end="")
23
25
  time.sleep(delay)
24
26
 
25
- def pydbms_dir():
27
+ def pydbms_dir() -> str:
26
28
  if sys.platform.startswith("win"):
27
29
  base = os.getenv("APPDATA")
28
30
  elif sys.platform == "darwin":
@@ -34,5 +36,5 @@ def pydbms_dir():
34
36
  os.makedirs(path, exist_ok=True)
35
37
  return path
36
38
 
37
- def pydbms_path(*parts):
39
+ def pydbms_path(*parts) -> str:
38
40
  return os.path.join(pydbms_dir(), *parts)
@@ -0,0 +1,92 @@
1
+ #config options for pydbms
2
+ #NOTE: If config.json file generated by the program is deleted or currpoted, it will restore to defaults.
3
+
4
+ from .Global import pydbms_path
5
+ from .dependencies import json, os, copy
6
+
7
+ DEFAULT_CONFIG = {
8
+ "config_version": 1,
9
+ "ui": {
10
+ "show_banner": True,
11
+ },
12
+ "mysql": {
13
+ "host": "localhost",
14
+ "port": 3306,
15
+ "user": "root",
16
+ "database": None,
17
+ }
18
+ }
19
+
20
+ def create_config() -> None:
21
+ path = pydbms_path("config.json")
22
+
23
+ if not os.path.exists(path):
24
+ with open(path, "w") as f:
25
+ json.dump(DEFAULT_CONFIG, f, indent=4)
26
+
27
+ def validate_config_types() -> None:
28
+ cfg = load_config()
29
+ changed=False
30
+
31
+ # validate ui.show_banner
32
+ if not isinstance(cfg.get("ui", {}).get("show_banner"), bool):
33
+ cfg.setdefault("ui", {})["show_banner"] = DEFAULT_CONFIG["ui"]["show_banner"]
34
+ changed=True
35
+
36
+ # validate mysql.port
37
+ if not isinstance(cfg.get("mysql", {}).get("port"), int):
38
+ cfg.setdefault("mysql", {})["port"] = DEFAULT_CONFIG["mysql"]["port"]
39
+ changed=True
40
+
41
+ if changed:
42
+ save_config(cfg)
43
+
44
+ return cfg
45
+
46
+ def load_config() -> dict:
47
+ path = pydbms_path("config.json")
48
+
49
+ try:
50
+ with open(path, "r") as f:
51
+ return json.load(f)
52
+ except (FileNotFoundError, json.JSONDecodeError):
53
+ create_config()
54
+ return copy.deepcopy(DEFAULT_CONFIG)
55
+
56
+ def save_config(config: dict) -> None:
57
+ path = pydbms_path("config.json")
58
+
59
+ with open(path, "w") as f:
60
+ json.dump(config, f, indent=4)
61
+
62
+ def parse_query_config(path: str) -> tuple[str, str] | None:
63
+ if "." not in path:
64
+ return None
65
+ section, key = path.split(".", 1)
66
+ return section, key
67
+
68
+ def coerce_value_config(value: str) -> bool | int | float | None | object:
69
+ v = value.lower()
70
+
71
+ if v in {"true", "yes", "on"}:
72
+ return True
73
+ if v in {"false", "no", "off"}:
74
+ return False
75
+ if v.isdigit():
76
+ return int(v)
77
+
78
+ try:
79
+ return float(v)
80
+ except ValueError:
81
+ pass
82
+
83
+ if v == "null" or v == "none":
84
+ return None
85
+
86
+ return value
87
+
88
+ def get_default_value_config(section: str, key: str) -> bool | int | float | None:
89
+ try:
90
+ return DEFAULT_CONFIG[section][key]
91
+ except KeyError:
92
+ return None
@@ -2,16 +2,16 @@
2
2
  PY DBMS — DB client CLI
3
3
  Copyright (C) 2025 Anish Sethi
4
4
  Licensed under - BSD-3-Clause License
5
- Version - 2.0
6
- Release - Experimental
5
+ Version - 2.1.0
6
+ Release - Stable
7
7
  '''
8
8
 
9
- from .Global import Print, console
10
- from .dependencies import pyfiglet, Text, Table, Align, Rule, Panel, mysql, sys, os
9
+ from .Global import Print, console, config
10
+ from .dependencies import pyfiglet, Text, Table, Align, Rule, Panel, mysql, sys
11
11
  from .pydbms_mysql import execute, execute_change, execute_select, connect, get_query_mysql
12
- from .config import load_config
12
+ from .config import parse_query_config, coerce_value_config, save_config, get_default_value_config, validate_config_types
13
13
 
14
- def print_banner():
14
+ def print_banner() -> None:
15
15
  ascii_art = pyfiglet.figlet_format("PY DBMS", font="slant").rstrip()
16
16
 
17
17
  logo = Text(ascii_art, style="bold color(57)")
@@ -22,7 +22,7 @@ def print_banner():
22
22
  stats_table.add_column("3", justify="center", ratio=1)
23
23
 
24
24
  stats_table.add_row(
25
- "[bold cyan]v2.0[/]\n [bold white]Version[/]",
25
+ "[bold cyan]v2.1.0[/]\n[bold white]Version[/]",
26
26
  "[bold yellow]MySQL[/]\n[bold white]Currently Supported[/]",
27
27
  "[bold green]Online since 2025[/]\n[bold white]Status[/]"
28
28
  )
@@ -56,8 +56,17 @@ def print_banner():
56
56
  )
57
57
  )
58
58
  print('\n\n')
59
+
60
+ def build_section_table(section: dict) -> Table:
61
+ table = Table(show_header=False, box=None)
62
+ table.add_column("", style="white", no_wrap=True)
63
+ table.add_column("", style="dim white")
64
+ for key, value in section.items():
65
+ table.add_row(key, str(value))
59
66
 
60
- def meta(cmd, cur):
67
+ return table
68
+
69
+ def meta(cmd: str, cur: object) -> None:
61
70
  cmd = cmd.strip()
62
71
 
63
72
  # .help
@@ -71,6 +80,9 @@ def meta(cmd, cur):
71
80
  help_table.add_row(".schema <table>", "Show CREATE TABLE statement for table <table>")
72
81
  help_table.add_row(".clear", "Clear the terminal screen")
73
82
  help_table.add_row(".version", "Show pydbms build information")
83
+ help_table.add_row(".config", "Show config settings for pydbms")
84
+ help_table.add_row(".config set <section>.<key> <value>", "Set config to a new value")
85
+ help_table.add_row(".config reset <section>.<key>", "Reset config to a default value")
74
86
  help_table.add_row(".exit", "Exit pydbms")
75
87
  console.print(help_table)
76
88
  console.print()
@@ -126,8 +138,8 @@ def meta(cmd, cur):
126
138
  info.add_column("", style="dim white")
127
139
 
128
140
  info.add_row("Name", "[link=https://github.com/Anish-Sethi-12122/py-dbms-cli]pydbms Terminal[/link]")
129
- info.add_row("Version", "v2.0")
130
- info.add_row("Build", "Experimental Release")
141
+ info.add_row("Version", "v2.1.0")
142
+ info.add_row("Build", "Stable Release")
131
143
  info.add_row("Python", f"[link=https://www.python.org/]{sys.version.split()[0]}[/link]")
132
144
  info.add_row("Author", "[link=https://www.linkedin.com/in/anish-sethi-dtu-cse/]Anish Sethi[/link]")
133
145
  info.add_row("Institution", "B.Tech Computer Science and Engineering @ Delhi Technological University")
@@ -143,6 +155,92 @@ def meta(cmd, cur):
143
155
  )
144
156
  console.print()
145
157
  console.print("Run `pip install -U py-dbms-cli` in terminal to check for updates.",style="dim white")
158
+ console.print()
159
+ return
160
+
161
+ # .config
162
+ if cmd == ".config":
163
+ outer = Table(show_header=False, box=None)
164
+ outer.add_column("", style="bold white", no_wrap=True)
165
+ outer.add_column("", style="white")
166
+
167
+ # UI section
168
+ ui_cfg = config.get("ui", {})
169
+ outer.add_row("UI", build_section_table(ui_cfg))
170
+
171
+ outer.add_row("", "")
172
+
173
+ # MySQL section
174
+ mysql_cfg = config.get("mysql", {})
175
+ outer.add_row("MySQL",build_section_table(mysql_cfg))
176
+
177
+ console.print(
178
+ Panel(
179
+ outer,
180
+ title="[bold white]PYSQL Terminal — config settings[/]",
181
+ border_style="bright_magenta",
182
+ padding=(1, 2),
183
+ )
184
+ )
185
+
186
+ console.print()
187
+ return
188
+
189
+ # .config set
190
+ if cmd.startswith(".config set"):
191
+ parts = cmd.split(maxsplit=3)
192
+
193
+ if len(parts) != 4:
194
+ Print("Usage: .config set <section>.<key> <value>", "YELLOW")
195
+ return
196
+
197
+ _, _, path, raw_value = parts
198
+
199
+ parsed = parse_query_config(path)
200
+
201
+ if not parsed:
202
+ Print("Invalid input format. Use <section>.<key>", "RED")
203
+ return
204
+
205
+ section, key = parsed
206
+
207
+ if section not in config or key not in config[section]:
208
+ Print(f"Unknown config key: {path}", "RED")
209
+ return
210
+
211
+ value = coerce_value_config(raw_value)
212
+ config[section][key] = value
213
+ save_config(config)
214
+
215
+ Print(f"Updated {path} → {value}", "GREEN")
216
+ return
217
+
218
+ # .config reset or .config -d or .config --default
219
+ if cmd.startswith(".config reset"):
220
+ parts = cmd.split(maxsplit=2)
221
+
222
+ if len(parts) != 3:
223
+ Print("Usage: .config reset <section>.<key>", "YELLOW")
224
+ return
225
+
226
+ path = parts[2]
227
+ parsed = parse_query_config(path)
228
+
229
+ if not parsed:
230
+ Print("Invalid config key format. Use <section>.<key>", "RED")
231
+ return
232
+
233
+ section, key = parsed
234
+ default = get_default_value_config(section, key)
235
+
236
+ if default is None:
237
+ Print(f"No default value for {path}.", "RED")
238
+ return
239
+
240
+ config[section][key] = default
241
+ save_config(config)
242
+
243
+ Print(f"Reset {path} → {default}", "GREEN")
146
244
  return
147
245
 
148
246
  # .exit
@@ -150,11 +248,12 @@ def meta(cmd, cur):
150
248
  Print("Session Terminated.", "RED", "bold")
151
249
  sys.exit()
152
250
 
153
- print(f"Unknown command: {cmd}\nCheck your manual that corresponds to helper commands.")
154
-
251
+ Print(f"Unknown command: {cmd}\nRefer to `.help` for list of commands", "YELLOW")
252
+
155
253
  def main():
156
- config = load_config()
157
- if config.get("show_banner", True):
254
+ global config
255
+ config = validate_config_types()
256
+ if config["ui"].get("show_banner", True):
158
257
  print_banner()
159
258
 
160
259
  con, cur = connect()
@@ -15,4 +15,5 @@ from rich.align import Align
15
15
  from rich.rule import Rule
16
16
  import re
17
17
  import os
18
- import json
18
+ import json
19
+ import copy
@@ -1,12 +1,12 @@
1
1
  #Instance MySQL
2
2
 
3
3
  from .dependencies import mysql, pwinput, sys, time, sqlparse, Panel, Table, re, box
4
- from .Global import Print, console
4
+ from .Global import Print, console, config
5
5
 
6
- def connect():
6
+ def connect() -> tuple[object,object] | int:
7
7
  try:
8
- host="localhost"
9
- user="root"
8
+ host=config["mysql"].get("host", "localhost")
9
+ user=config["mysql"].get("user", "root")
10
10
  Print(f"pydbms> Enter host name for MySQL (default value -> {host}):", "YELLOW")
11
11
  host=input()
12
12
  if not host:
@@ -30,7 +30,7 @@ def connect():
30
30
  sys.exit()
31
31
  return -1
32
32
 
33
- def print_warnings(cur):
33
+ def print_warnings(cur: object) -> bool:
34
34
  warnings = cur.fetchwarnings()
35
35
  if warnings:
36
36
  for level, warning_code, warning_msg in warnings:
@@ -39,7 +39,7 @@ def print_warnings(cur):
39
39
  return True
40
40
  return False
41
41
 
42
- def execute_select(query,cur):
42
+ def execute_select(query: str,cur: object) -> None:
43
43
  start = time.time()
44
44
  cur.execute(query)
45
45
  end = time.time()
@@ -85,7 +85,7 @@ def execute_select(query,cur):
85
85
  Print(msg, "YELLOW" if has_warning else "GREEN")
86
86
  console.print()
87
87
 
88
- def execute_change(query,con,cur):
88
+ def execute_change(query: str,con: object,cur: object) -> None:
89
89
  cur.execute(query)
90
90
  affected_row_num=cur.rowcount
91
91
  con.commit()
@@ -100,7 +100,7 @@ def execute_change(query,con,cur):
100
100
  Print(msg, "YELLOW" if has_warning else "GREEN")
101
101
  console.print()
102
102
 
103
- def execute(query,cur):
103
+ def execute(query: str,cur: object) -> None:
104
104
  cur.execute(query)
105
105
 
106
106
  has_warning=print_warnings(cur)
@@ -113,7 +113,7 @@ def execute(query,cur):
113
113
  Print(msg, "YELLOW" if has_warning else "GREEN")
114
114
  console.print()
115
115
 
116
- def get_query_mysql():
116
+ def get_query_mysql() -> object:
117
117
  try:
118
118
  buffer = ""
119
119
  while True:
@@ -132,7 +132,7 @@ def get_query_mysql():
132
132
  console.print()
133
133
  return query
134
134
 
135
- def get_query_title(query):
135
+ def get_query_title(query: str) -> str:
136
136
  q = query.strip().lower()
137
137
 
138
138
  # === Simple SELECT ===
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "py-dbms-cli"
7
- version = "2.0"
8
- description = "A modern, secure, aesthetic and your ultimate DBMS client supporting MySQL and more."
7
+ version = "2.1.0"
8
+ description = "A modern, secure, aesthetic and your ultimate DBMS client. Implemented as a CLI (Command-Line Interface) tool and written 100% in Python"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
11
11
  authors = [
@@ -1,31 +0,0 @@
1
- #config options for pydbms
2
-
3
- from .Global import pydbms_path
4
- from .dependencies import json, os
5
-
6
- DEFAULT_CONFIG = {
7
- "show_banner": True
8
- }
9
-
10
- def create_config():
11
- path = pydbms_path("config.json")
12
-
13
- if not os.path.exists(path):
14
- with open(path, "w") as f:
15
- json.dump(DEFAULT_CONFIG, f, indent=4)
16
-
17
- def load_config():
18
- path = pydbms_path("config.json")
19
-
20
- try:
21
- with open(path, "r") as f:
22
- return json.load(f)
23
- except (FileNotFoundError, json.JSONDecodeError):
24
- create_config()
25
- return DEFAULT_CONFIG.copy()
26
-
27
- def save_config(config):
28
- path = pydbms_path("config.json")
29
-
30
- with open(path, "w") as f:
31
- json.dump(config, f, indent=4)
File without changes
File without changes
File without changes
File without changes
File without changes