Compare commits

..

No commits in common. "9736564aab1535bcff57e2fe9003c383f3db180a" and "087457393583400b7442b9de7bde6cf674b650a5" have entirely different histories.

8 changed files with 56 additions and 96 deletions

1
.gitignore vendored
View File

@ -3,4 +3,3 @@ config.toml
debug_cmd.lst
venv
log.log
*.bak

View File

@ -1,11 +0,0 @@
FROM python:3.12.4
WORKDIR /myjsondb
RUN python3 -m pip install aiomysql fastapi cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY ./src /myjsondb/src
COPY ./main.py /myjsondb
COPY ./config.toml.template /myjsondb
RUN mkdir /myjsondb/config
CMD python3 main.py

View File

@ -4,6 +4,7 @@ runmode = "webapi"
host = "127.0.0.1"
port = 3032
[[limit]]
enable = true
speed = 5
wait100ms = 6000
wait1s = 8000

View File

@ -1,14 +0,0 @@
runmode = "webapi"
[webapi]
host = "127.0.0.1"
port = 3032
[db]
host = "127.0.0.1"
port = 3306
user = "myjsondb"
passwd = "<your passwd>"
dbname = "myjsondb"
minsize = 100
maxsize = 100

View File

View File

@ -1,18 +1,9 @@
import tomllib
import os
import shutil
import sys
if (not os.path.exists("config/config.toml")):
shutil.copyfile("./config.toml.template", "./config/config.toml")
print("Init config. Please config mysql server info.")
sys.exit(0)
with open("config/config.toml", 'rb') as file:
with open("config.toml", 'rb') as file:
configs: dict = tomllib.load(file)
RUN_MODE: str = str(os.environ.get("MYJSONDB_RUNMODE", None)
or configs.get("runmode", "webapi"))
RUN_MODE: bool = configs.get("runmode", "webapi")
LOGPATH: str = configs.get("log", {}).get("path", "log.log")
LOGLEVEL: str = configs.get("log", {}).get("level", "info")
@ -20,34 +11,27 @@ if (LOGLEVEL not in ["debug", "info", "warning", "err"]):
LOGLEVEL = "info"
OUTPUT_COLORFUL: bool = configs.get("log", {}).get("color", True)
DB_SERVER: str = str(os.environ.get("MYJSONDB_DB_HOST", None)
or configs.get("db", {}).get("host", "127.0.0.1"))
DB_PORT: int = int(os.environ.get("MYJSONDB_DB_PORT", None)
or configs.get("db", {}).get("port", 3306))
DB_USER: str = str(os.environ.get("MYJSONDB_DB_USER", None)
or configs.get("db", {}).get("user", "root"))
DB_PASSWD: str = str(os.environ.get("MYJSONDB_DB_PASSWD", None)
or configs.get("db", {}).get("passwd", "<no password>"))
DB_NAME: str = str(os.environ.get("MYJSONDB_DB_DBNAME", None)
or configs.get("db", {}).get("dbname", "myjsonDB"))
DB_MINSIZE: int = int(os.environ.get("MYJSONDB_DB_MINSIZE", None)
or configs.get("db", {}).get("minsize", 5))
DB_MAXSIZE: int = int(os.environ.get("MYJSONDB_DB_MAXSIZE", None)
or configs.get("db", {}).get("maxsize", 10))
DB_SERVER: str = configs.get("db", {}).get("host", "127.0.0.1")
DB_PORT: int = configs.get("db", {}).get("port", 3306)
DB_USER: str = configs.get("db", {}).get("user", "root")
DB_PASSWD: str = configs.get("db", {}).get("passwd", "<no password>")
DB_NAME: str = configs.get("db", {}).get("dbname", "myjsonDB")
DB_MINSIZE: str = configs.get("db", {}).get("minsize", 10)
DB_MAXSIZE: str = configs.get("db", {}).get("maxsize", 50)
USE_EMACE_MOD: bool = configs.get("console", {}).get("emacsmode", True)
SIGTERM_CMD: bool = configs.get("console", {}).get("softstop", True)
API_HOST: str = str(os.environ.get("MYJSONDB_API_HOST", None)
or configs.get("webapi", {}).get("host", "0.0.0.0"))
API_PORT: int = int(os.environ.get("MYJSONDB_API_PORT", None)
or configs.get("webapi", {}).get("port", 3032))
API_HOST: str = configs.get("webapi", {}).get("host", "127.0.0.1")
API_PORT: int = configs.get("webapi", {}).get("port", 3032)
LIM_ENABLE: bool = configs.get("webapi", {}).get(
"limit", {}).get("enable", True)
LIM_SPEED: int = configs.get("webapi", {}).get(
"limit", {}).get("speed", 5)
LIM_WAIT100MS: int = configs.get("webapi", {}).get(
"limit", {}).get("wait1ms", 10000)
"limit", {}).get("wait1ms", 100)
LIM_WAIT1S: int = configs.get("webapi", {}).get(
"limit", {}).get("wait1s", 20000)
"limit", {}).get("wait1s", 200)
LIM_WAIT10S: int = configs.get("webapi", {}).get(
"limit", {}).get("wait10s", 50000)
"limit", {}).get("wait10s", 300)

View File

@ -370,35 +370,35 @@ async def create_key(dbname: str, name: str, key: str | int | tuple, vl: Any) ->
if (vl is None):
await log.warn("Value is None")
return (6, "Value is None", 1)
return (6, "Value is None")
res = re.search(r'[0-9A-Za-z_]{2,20}', dbname)
if res is None or res.group() != dbname:
await log.warn("Database name error: "+str(dbname))
return (1, "Database name error: "+str(dbname), 1)
return (1, "Database name error: "+str(dbname))
res = re.search(r'[0-9A-Za-z_]{2,20}', name)
if res is None or res.group() != name:
await log.warn("Create key table name error: "+str(name))
return (2, "Create key table name error: "+str(name), 1)
return (2, "Create key table name error: "+str(name))
checks = await check_table(dbname, name)
if checks == None:
return (3, "Other error", 1)
return (3, "Other error")
elif checks == False:
await log.warn("Unknown table: "+str(name))
return (4, "Unknown table: "+str(name), 1)
return (4, "Unknown table: "+str(name))
async def callback():
return (0, None, 1)
return (0, None)
async def err_callback(err_info):
if (".PRIMARY" in err_info):
await log.warn("Duplicate key: "+str(key))
return (5, "Duplicate key: "+str(key), 1)
return (5, "Duplicate key: "+str(key))
else:
await log.warn("Other error on create key: "+str(err_info))
return (5, "Other error on create key: "+str(err_info), 1)
return (5, "Other error on create key: "+str(err_info))
return await sqllink.execute_cmd(connects,
command=f"""
INSERT INTO `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}`(
@ -541,7 +541,7 @@ async def remove_key(dbname: str, name: str, key: str | int | tuple) -> Any | No
async def change_key(dbname: str, name: str, key: str | int | tuple, vl: Any) -> Any | None:
"""
## Create or change a key.
## Change a key.
@return: True(created) | False(not create) | None(error)
"""
await log.info("Change key in '"+str(name)+"."+str(dbname)+"'")
@ -549,33 +549,34 @@ async def change_key(dbname: str, name: str, key: str | int | tuple, vl: Any) ->
res = re.search(r'[0-9A-Za-z_]{2,20}', dbname)
if res is None or res.group() != dbname:
await log.warn("Database name error: "+str(dbname))
return (1, "Database name error: "+str(dbname), 0)
return (1, "Database name error: "+str(dbname))
res = re.search(r'[0-9A-Za-z_]{2,20}', name)
if res is None or res.group() != name:
await log.warn("Change key table name error: "+str(name))
return (2, "Change key table name error: "+str(name), 0)
return (2, "Change key table name error: "+str(name))
checks = await check_key(dbname, name, key)
if checks == None:
await log.warn("Other error")
return (3, "Other error", 0)
return (3, "Other error")
elif checks == False:
return await create_key(dbname, name, key, vl)
else:
async def callback():
return (0, None, 0)
await log.warn("Unknown key: "+str(name))
return (4, "Unknown key: "+str(name))
async def err_callback(err_info):
await log.warn("Other error on change key: "+str(err_info))
return (5, "Other error on change key: "+str(err_info), 0)
return await sqllink.execute_cmd(connects,
command=f"""
UPDATE `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}` SET `value`=%s WHERE `key`=%s;""",
args=(pickle.dumps(vl), str(key)),
commit=True,
callback=callback,
err_callback=err_callback)
async def callback():
return (0, None)
async def err_callback(err_info):
await log.warn("Other error on change key: "+str(err_info))
return (5, "Other error on change key: "+str(err_info))
return await sqllink.execute_cmd(connects,
command=f"""
UPDATE `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}` SET `value`=%s WHERE `key`=%s;""",
args=(pickle.dumps(vl), str(key)),
commit=True,
callback=callback,
err_callback=err_callback)
async def list_key(dbname: str, name: str) -> Tuple[tuple[str, Any]] | None:

View File

@ -56,7 +56,7 @@ async def list_table(database_name: str):
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}", status_code=200)
async def check_table(database_name: str, table_name: str):
async def check_database(database_name: str, table_name: str):
await reqlim.get_req()
ret = await core.check_table(database_name, table_name)
if (ret is not None):
@ -91,8 +91,8 @@ async def list_key(database_name: str, table_name: str):
return {"status": 400, "errormsg": "Unknown Error"}
@app.head("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
async def check_key(database_name: str, table_name: str, key_name: int | str):
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}/check", status_code=200)
async def create_key(database_name: str, table_name: str, key_name: int | str):
await reqlim.get_req()
ret = await core.check_key(database_name, table_name, key_name)
if (ret is not None):
@ -101,14 +101,14 @@ async def check_key(database_name: str, table_name: str, key_name: int | str):
@app.post("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
async def create_or_change_key(database_name: str, table_name: str, key_name: int | str, data: KeyItem): # will remove
async def create_key(database_name: str, table_name: str, key_name: int | str, data: KeyItem):
await reqlim.get_req()
if (data.data is None):
return {"status": 400, "errormsg": "No data"}
ret = await core.change_key(database_name, table_name, key_name, data.data)
ret = await core.create_key(database_name, table_name, key_name, data.data)
if (ret[0] == 0):
return {"status": 200, "create": bool(ret[2])}
return {"status": 400+ret[0], "errormsg": ret[1], "create": bool(ret[2])}
return {"status": 200}
return {"status": 400+ret[0], "errormsg": ret[1]}
@app.delete("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
@ -121,18 +121,18 @@ async def delete_key(database_name: str, table_name: str, key_name: int | str):
@app.patch("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
async def update_key(database_name: str, table_name: str, key_name: int | str, data: KeyItem):
async def create_key(database_name: str, table_name: str, key_name: int | str, data: KeyItem):
await reqlim.get_req()
if (data.data is None):
return {"status": 400, "errormsg": "No data"}
ret = await core.change_key(database_name, table_name, key_name, data.data)
if (ret[0] == 0):
return {"status": 200, "create": bool(ret[2])}
return {"status": 400+ret[0], "errormsg": ret[1], "create": bool(ret[2])}
return {"status": 200}
return {"status": 400+ret[0], "errormsg": ret[1]}
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
async def get_key(database_name: str, table_name: str, key_name: int | str):
async def create_key(database_name: str, table_name: str, key_name: int | str):
await reqlim.get_req()
ret = await core.get_key(database_name, table_name, key_name)
if (ret is not None):