diff --git "a/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.json" "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.json" new file mode 100644 index 0000000000000000000000000000000000000000..57696bbe50661edcbf1ce39dc9752a6e5f9e1815 --- /dev/null +++ "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.json" @@ -0,0 +1,5 @@ +{ + "type": "code_options", + "author": "刘鑫", + "source": "children.md" +} \ No newline at end of file diff --git "a/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.md" "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.md" new file mode 100644 index 0000000000000000000000000000000000000000..5fbdf0a5aff11a14070634851b17e2efcd40a326 --- /dev/null +++ "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/children.md" @@ -0,0 +1,43 @@ +# 查找子节点 + +有一个表 node,有两列 + +```shell +# select item from node; +id | pid +------------------ +1 | 0 +2 | 1 +3 | 1 +4 | 3 +5 | 2 +... +``` + +其中id是自增主键,pid指向父节点的id。那么给定某一个id ,查找它的子节点的查询应该是: + +## 答案 + +```sql +select * from node where pid = ? +``` + +## 选项 + +### 缺少 where + +```sql +select * from node pid = ? +``` + +### 结构错误 + +```sql +from node select * where pid = ? +``` + +### select 不完整 + +```sql +select from node where pid = ? +``` diff --git "a/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/config.json" "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/config.json" index ac68d0fa279e2508820297897da8291c953044a3..7e34639f9ce0eee2a53eaac408fa7d27149f2a85 100644 --- "a/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/config.json" +++ "b/data/1.OceanBase\345\210\235\351\230\266/2.\345\237\272\346\234\254\346\223\215\344\275\234/7.\346\237\245\350\257\242\346\225\260\346\215\256/config.json" @@ -3,6 +3,7 @@ "node_id": "oceanbase-6f727423ee414b85b6ed90bebcdd88b8", "title": "查询数据", "export": [ - "hello.json" + "hello.json", + "children.json" ] } \ No newline at end of file diff --git "a/data/2.OceanBase\344\270\255\351\230\266/3.\350\241\250\346\237\245\350\257\242/config.json" "b/data/2.OceanBase\344\270\255\351\230\266/3.\350\241\250\346\237\245\350\257\242/config.json" index 18c4b035754222e9369a33a84fa7d79bb2803e72..a9d4a5386659461386878f8549d940c1ecb0006a 100644 --- "a/data/2.OceanBase\344\270\255\351\230\266/3.\350\241\250\346\237\245\350\257\242/config.json" +++ "b/data/2.OceanBase\344\270\255\351\230\266/3.\350\241\250\346\237\245\350\257\242/config.json" @@ -1,5 +1,6 @@ { "keywords": [], "node_id": "oceanbase-641f612acf59456187b9573a4398e20b", - "title": "表查询" + "title": "表查询", + "export": [] } \ No newline at end of file diff --git "a/data/3.OceanBase\351\253\230\351\230\266/3.\347\274\226\347\250\213\345\222\214\346\237\245\350\257\242/2.\350\277\236\346\216\245\346\237\245\350\257\242/config.json" "b/data/3.OceanBase\351\253\230\351\230\266/3.\347\274\226\347\250\213\345\222\214\346\237\245\350\257\242/2.\350\277\236\346\216\245\346\237\245\350\257\242/config.json" index 7a577bde19c12e56199acf29ad207215265ec329..05c5a4d070c0b41ea806e331d8965799512197ee 100644 --- "a/data/3.OceanBase\351\253\230\351\230\266/3.\347\274\226\347\250\213\345\222\214\346\237\245\350\257\242/2.\350\277\236\346\216\245\346\237\245\350\257\242/config.json" +++ "b/data/3.OceanBase\351\253\230\351\230\266/3.\347\274\226\347\250\213\345\222\214\346\237\245\350\257\242/2.\350\277\236\346\216\245\346\237\245\350\257\242/config.json" @@ -1,5 +1,6 @@ { "keywords": [], "node_id": "oceanbase-d28015752f834bffacc6dfb9ab64b8c2", - "title": "连接查询" + "title": "连接查询", + "export": [] } \ No newline at end of file diff --git a/src/tree.py b/src/tree.py index 0da9ebca340f6ab6f2c9e33f56a43c4ca563f68a..1b4e44ba4d434b7c2db2b5337fdf4c2634d2ec42 100644 --- a/src/tree.py +++ b/src/tree.py @@ -1,3 +1,4 @@ +import logging from genericpath import exists import json import os @@ -7,6 +8,9 @@ import re id_set = set() +logger = logging.getLogger(__name__) + + def load_json(p): with open(p, 'r') as f: return json.loads(f.read()) @@ -18,13 +22,22 @@ def dump_json(p, j, exist_ok=False, override=False): if not override: return else: - print(f"{p} already exist") + logger.error(f"{p} already exist") sys.exit(0) with open(p, 'w+') as f: f.write(json.dumps(j, indent=2, ensure_ascii=False)) +def ensure_config(path): + config_path = os.path.join(path, "config.json") + if not os.path.exists(config_path): + node = {"keywords": []} + dump_json(config_path, node, exist_ok=True, override=False) + return node + else: + return load_json(config_path) + def parse_no_name(d): p = r'(\d+)\.(.*)' m = re.search(p, d) @@ -37,6 +50,7 @@ def parse_no_name(d): return no, dir_name + def check_export(base, cfg): flag = False exports = [] @@ -70,7 +84,7 @@ def gen_tree(data_path): flag = False if (node.get('node_id') is None) or node.get('node_id') in id_set: - node['node_id'] = gen_node_id() + node['node_id'] = gen_node_id() flag = True id_set.add(node['node_id']) @@ -78,7 +92,7 @@ def gen_tree(data_path): if 'children' in node: for c in node["children"]: flag = flag or ensure_id_helper(list(c.values())[0]) - + return flag def ensure_node_id(cfg): @@ -97,7 +111,7 @@ def gen_tree(data_path): if 'children' in node: for c in node["children"]: flag = flag or ensure_title_helper(list(c.values())[0], None, list(c.keys())[0]) - + return flag def ensure_title(cfg, cfg_path): @@ -114,11 +128,11 @@ def gen_tree(data_path): return node, node_children # 根节点 + cfg = ensure_config(data_path) cfg_path = os.path.join(data_path, 'config.json') - cfg = load_json(cfg_path) if ensure_node_id(cfg): dump_json(cfg_path, cfg, exist_ok=True, override=True) - + if ensure_title(cfg, cfg_path): cfg["title"] = "C" dump_json(cfg_path, cfg, exist_ok=True, override=True) @@ -134,7 +148,7 @@ def gen_tree(data_path): print(level_no_dir) no, level_name = parse_no_name(level_no_name) level_path = os.path.join(level_no_dir, 'config.json') - level_cfg = load_json(level_path) + level_cfg = ensure_config(level_no_dir) if ensure_node_id(level_cfg) or check_export(level_no_dir, level_cfg): dump_json(level_path, level_cfg, exist_ok=True, override=True) if ensure_title(level_cfg, level_path): @@ -148,11 +162,11 @@ def gen_tree(data_path): for chapter_no_dir, chapter_no_name in list_dir(level_no_dir): no, chapter_name = parse_no_name(chapter_no_name) chapter_path = os.path.join(chapter_no_dir, 'config.json') - chapter_cfg = load_json(chapter_path) + chapter_cfg = ensure_config(chapter_no_dir) if ensure_node_id(chapter_cfg) or check_export(chapter_no_dir, chapter_cfg): dump_json(chapter_path, chapter_cfg, exist_ok=True, override=True) if ensure_title(chapter_cfg, chapter_path): - dump_json(chapter_path, chapter_cfg, exist_ok=True, override=True) + dump_json(chapter_path, chapter_cfg, exist_ok=True, override=True) chapter_node, chapter_node_children = make_node( chapter_name, chapter_cfg['node_id'], chapter_cfg['keywords']) @@ -162,7 +176,7 @@ def gen_tree(data_path): for section_no_dir, section_no_name in list_dir(chapter_no_dir): no, section_name = parse_no_name(section_no_name) sec_path = os.path.join(section_no_dir, 'config.json') - sec_cfg = load_json(sec_path) + sec_cfg = ensure_config(section_no_dir) flag = ensure_node_id(sec_cfg) or check_export(section_no_dir, sec_cfg) section_node, section_node_children = make_node( @@ -170,23 +184,23 @@ def gen_tree(data_path): chapter_node_children.append(section_node) # 确保习题分配了习题ID - + for export in sec_cfg.get("export", []): ecfg_path = os.path.join(section_no_dir, export) ecfg = load_json(ecfg_path) if (ecfg.get('exercise_id') is None) or (ecfg.get('exercise_id') in id_set): - ecfg['exercise_id'] = uuid.uuid4().hex + ecfg['exercise_id'] = uuid.uuid4().hex dump_json(ecfg_path, ecfg, exist_ok=True, override=True) - + id_set.add(ecfg['exercise_id']) if flag: dump_json(sec_path, sec_cfg, exist_ok=True, override=True) if ensure_title(sec_cfg, sec_path): - dump_json(sec_path, sec_cfg, exist_ok=True, override=True) + dump_json(sec_path, sec_cfg, exist_ok=True, override=True) - # 保存技能树骨架 + # 保存技能树骨架 tree_path = os.path.join(data_path, 'tree.json') dump_json(tree_path, root, exist_ok=True, override=True)