Compare commits
No commits in common. "9736564aab1535bcff57e2fe9003c383f3db180a" and "087457393583400b7442b9de7bde6cf674b650a5" have entirely different histories.
9736564aab
...
0874573935
|
@ -3,4 +3,3 @@ config.toml
|
||||||
debug_cmd.lst
|
debug_cmd.lst
|
||||||
venv
|
venv
|
||||||
log.log
|
log.log
|
||||||
*.bak
|
|
||||||
|
|
11
Dockerfile
11
Dockerfile
|
@ -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
|
|
|
@ -4,6 +4,7 @@ runmode = "webapi"
|
||||||
host = "127.0.0.1"
|
host = "127.0.0.1"
|
||||||
port = 3032
|
port = 3032
|
||||||
[[limit]]
|
[[limit]]
|
||||||
|
enable = true
|
||||||
speed = 5
|
speed = 5
|
||||||
wait100ms = 6000
|
wait100ms = 6000
|
||||||
wait1s = 8000
|
wait1s = 8000
|
|
@ -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
|
|
|
@ -1,18 +1,9 @@
|
||||||
import tomllib
|
import tomllib
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if (not os.path.exists("config/config.toml")):
|
with open("config.toml", 'rb') as file:
|
||||||
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:
|
|
||||||
configs: dict = tomllib.load(file)
|
configs: dict = tomllib.load(file)
|
||||||
|
|
||||||
RUN_MODE: str = str(os.environ.get("MYJSONDB_RUNMODE", None)
|
RUN_MODE: bool = configs.get("runmode", "webapi")
|
||||||
or configs.get("runmode", "webapi"))
|
|
||||||
|
|
||||||
LOGPATH: str = configs.get("log", {}).get("path", "log.log")
|
LOGPATH: str = configs.get("log", {}).get("path", "log.log")
|
||||||
LOGLEVEL: str = configs.get("log", {}).get("level", "info")
|
LOGLEVEL: str = configs.get("log", {}).get("level", "info")
|
||||||
|
@ -20,34 +11,27 @@ if (LOGLEVEL not in ["debug", "info", "warning", "err"]):
|
||||||
LOGLEVEL = "info"
|
LOGLEVEL = "info"
|
||||||
OUTPUT_COLORFUL: bool = configs.get("log", {}).get("color", True)
|
OUTPUT_COLORFUL: bool = configs.get("log", {}).get("color", True)
|
||||||
|
|
||||||
DB_SERVER: str = str(os.environ.get("MYJSONDB_DB_HOST", None)
|
DB_SERVER: str = configs.get("db", {}).get("host", "127.0.0.1")
|
||||||
or configs.get("db", {}).get("host", "127.0.0.1"))
|
DB_PORT: int = configs.get("db", {}).get("port", 3306)
|
||||||
DB_PORT: int = int(os.environ.get("MYJSONDB_DB_PORT", None)
|
DB_USER: str = configs.get("db", {}).get("user", "root")
|
||||||
or configs.get("db", {}).get("port", 3306))
|
DB_PASSWD: str = configs.get("db", {}).get("passwd", "<no password>")
|
||||||
DB_USER: str = str(os.environ.get("MYJSONDB_DB_USER", None)
|
DB_NAME: str = configs.get("db", {}).get("dbname", "myjsonDB")
|
||||||
or configs.get("db", {}).get("user", "root"))
|
DB_MINSIZE: str = configs.get("db", {}).get("minsize", 10)
|
||||||
DB_PASSWD: str = str(os.environ.get("MYJSONDB_DB_PASSWD", None)
|
DB_MAXSIZE: str = configs.get("db", {}).get("maxsize", 50)
|
||||||
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))
|
|
||||||
|
|
||||||
USE_EMACE_MOD: bool = configs.get("console", {}).get("emacsmode", True)
|
USE_EMACE_MOD: bool = configs.get("console", {}).get("emacsmode", True)
|
||||||
SIGTERM_CMD: bool = configs.get("console", {}).get("softstop", True)
|
SIGTERM_CMD: bool = configs.get("console", {}).get("softstop", True)
|
||||||
|
|
||||||
API_HOST: str = str(os.environ.get("MYJSONDB_API_HOST", None)
|
API_HOST: str = configs.get("webapi", {}).get("host", "127.0.0.1")
|
||||||
or configs.get("webapi", {}).get("host", "0.0.0.0"))
|
API_PORT: int = configs.get("webapi", {}).get("port", 3032)
|
||||||
API_PORT: int = int(os.environ.get("MYJSONDB_API_PORT", None)
|
|
||||||
or configs.get("webapi", {}).get("port", 3032))
|
|
||||||
|
|
||||||
|
LIM_ENABLE: bool = configs.get("webapi", {}).get(
|
||||||
|
"limit", {}).get("enable", True)
|
||||||
LIM_SPEED: int = configs.get("webapi", {}).get(
|
LIM_SPEED: int = configs.get("webapi", {}).get(
|
||||||
"limit", {}).get("speed", 5)
|
"limit", {}).get("speed", 5)
|
||||||
LIM_WAIT100MS: int = configs.get("webapi", {}).get(
|
LIM_WAIT100MS: int = configs.get("webapi", {}).get(
|
||||||
"limit", {}).get("wait1ms", 10000)
|
"limit", {}).get("wait1ms", 100)
|
||||||
LIM_WAIT1S: int = configs.get("webapi", {}).get(
|
LIM_WAIT1S: int = configs.get("webapi", {}).get(
|
||||||
"limit", {}).get("wait1s", 20000)
|
"limit", {}).get("wait1s", 200)
|
||||||
LIM_WAIT10S: int = configs.get("webapi", {}).get(
|
LIM_WAIT10S: int = configs.get("webapi", {}).get(
|
||||||
"limit", {}).get("wait10s", 50000)
|
"limit", {}).get("wait10s", 300)
|
||||||
|
|
53
src/core.py
53
src/core.py
|
@ -370,35 +370,35 @@ async def create_key(dbname: str, name: str, key: str | int | tuple, vl: Any) ->
|
||||||
|
|
||||||
if (vl is None):
|
if (vl is None):
|
||||||
await log.warn("Value 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)
|
res = re.search(r'[0-9A-Za-z_]{2,20}', dbname)
|
||||||
if res is None or res.group() != dbname:
|
if res is None or res.group() != dbname:
|
||||||
await log.warn("Database name error: "+str(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)
|
res = re.search(r'[0-9A-Za-z_]{2,20}', name)
|
||||||
if res is None or res.group() != name:
|
if res is None or res.group() != name:
|
||||||
await log.warn("Create key table name error: "+str(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)
|
checks = await check_table(dbname, name)
|
||||||
if checks == None:
|
if checks == None:
|
||||||
return (3, "Other error", 1)
|
return (3, "Other error")
|
||||||
elif checks == False:
|
elif checks == False:
|
||||||
await log.warn("Unknown table: "+str(name))
|
await log.warn("Unknown table: "+str(name))
|
||||||
return (4, "Unknown table: "+str(name), 1)
|
return (4, "Unknown table: "+str(name))
|
||||||
|
|
||||||
async def callback():
|
async def callback():
|
||||||
return (0, None, 1)
|
return (0, None)
|
||||||
|
|
||||||
async def err_callback(err_info):
|
async def err_callback(err_info):
|
||||||
if (".PRIMARY" in err_info):
|
if (".PRIMARY" in err_info):
|
||||||
await log.warn("Duplicate key: "+str(key))
|
await log.warn("Duplicate key: "+str(key))
|
||||||
return (5, "Duplicate key: "+str(key), 1)
|
return (5, "Duplicate key: "+str(key))
|
||||||
else:
|
else:
|
||||||
await log.warn("Other error on create key: "+str(err_info))
|
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,
|
return await sqllink.execute_cmd(connects,
|
||||||
command=f"""
|
command=f"""
|
||||||
INSERT INTO `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}`(
|
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:
|
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)
|
@return: True(created) | False(not create) | None(error)
|
||||||
"""
|
"""
|
||||||
await log.info("Change key in '"+str(name)+"."+str(dbname)+"'")
|
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)
|
res = re.search(r'[0-9A-Za-z_]{2,20}', dbname)
|
||||||
if res is None or res.group() != dbname:
|
if res is None or res.group() != dbname:
|
||||||
await log.warn("Database name error: "+str(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)
|
res = re.search(r'[0-9A-Za-z_]{2,20}', name)
|
||||||
if res is None or res.group() != name:
|
if res is None or res.group() != name:
|
||||||
await log.warn("Change key table name error: "+str(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)
|
checks = await check_key(dbname, name, key)
|
||||||
if checks == None:
|
if checks == None:
|
||||||
await log.warn("Other error")
|
await log.warn("Other error")
|
||||||
return (3, "Other error", 0)
|
return (3, "Other error")
|
||||||
elif checks == False:
|
elif checks == False:
|
||||||
return await create_key(dbname, name, key, vl)
|
await log.warn("Unknown key: "+str(name))
|
||||||
else:
|
return (4, "Unknown key: "+str(name))
|
||||||
async def callback():
|
|
||||||
return (0, None, 0)
|
|
||||||
|
|
||||||
async def err_callback(err_info):
|
async def callback():
|
||||||
await log.warn("Other error on change key: "+str(err_info))
|
return (0, None)
|
||||||
return (5, "Other error on change key: "+str(err_info), 0)
|
|
||||||
return await sqllink.execute_cmd(connects,
|
async def err_callback(err_info):
|
||||||
command=f"""
|
await log.warn("Other error on change key: "+str(err_info))
|
||||||
UPDATE `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}` SET `value`=%s WHERE `key`=%s;""",
|
return (5, "Other error on change key: "+str(err_info))
|
||||||
args=(pickle.dumps(vl), str(key)),
|
return await sqllink.execute_cmd(connects,
|
||||||
commit=True,
|
command=f"""
|
||||||
callback=callback,
|
UPDATE `user_{dbname.replace("_", "__")}_{name.replace("_", "__")}` SET `value`=%s WHERE `key`=%s;""",
|
||||||
err_callback=err_callback)
|
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:
|
async def list_key(dbname: str, name: str) -> Tuple[tuple[str, Any]] | None:
|
||||||
|
|
|
@ -56,7 +56,7 @@ async def list_table(database_name: str):
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}", status_code=200)
|
@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()
|
await reqlim.get_req()
|
||||||
ret = await core.check_table(database_name, table_name)
|
ret = await core.check_table(database_name, table_name)
|
||||||
if (ret is not None):
|
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"}
|
return {"status": 400, "errormsg": "Unknown Error"}
|
||||||
|
|
||||||
|
|
||||||
@app.head("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
|
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}/check", status_code=200)
|
||||||
async def check_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()
|
await reqlim.get_req()
|
||||||
ret = await core.check_key(database_name, table_name, key_name)
|
ret = await core.check_key(database_name, table_name, key_name)
|
||||||
if (ret is not None):
|
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)
|
@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()
|
await reqlim.get_req()
|
||||||
if (data.data is None):
|
if (data.data is None):
|
||||||
return {"status": 400, "errormsg": "No data"}
|
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):
|
if (ret[0] == 0):
|
||||||
return {"status": 200, "create": bool(ret[2])}
|
return {"status": 200}
|
||||||
return {"status": 400+ret[0], "errormsg": ret[1], "create": bool(ret[2])}
|
return {"status": 400+ret[0], "errormsg": ret[1]}
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
|
@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)
|
@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()
|
await reqlim.get_req()
|
||||||
if (data.data is None):
|
if (data.data is None):
|
||||||
return {"status": 400, "errormsg": "No data"}
|
return {"status": 400, "errormsg": "No data"}
|
||||||
ret = await core.change_key(database_name, table_name, key_name, data.data)
|
ret = await core.change_key(database_name, table_name, key_name, data.data)
|
||||||
if (ret[0] == 0):
|
if (ret[0] == 0):
|
||||||
return {"status": 200, "create": bool(ret[2])}
|
return {"status": 200}
|
||||||
return {"status": 400+ret[0], "errormsg": ret[1], "create": bool(ret[2])}
|
return {"status": 400+ret[0], "errormsg": ret[1]}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/"+version+"/database/{database_name}/table/{table_name}/key/{key_name}", status_code=200)
|
@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()
|
await reqlim.get_req()
|
||||||
ret = await core.get_key(database_name, table_name, key_name)
|
ret = await core.get_key(database_name, table_name, key_name)
|
||||||
if (ret is not None):
|
if (ret is not None):
|
||||||
|
|
Loading…
Reference in New Issue