feat: sap-cli skill v2.1.0 — self-contained distributable package

- assets/: sap-cli source (v2.1.0, 26 commands, 16 object types)
- references/: tool constraints + error handling (self-contained)
- scripts/setup.py: one-click install/config/verify
- SKILL.md: full command reference + dual-platform install guide
- VERSION: 2.1.0

Built from D:/Codespace/sap-cli via scripts/pack_skill.py
This commit is contained in:
2026-06-13 20:52:24 +08:00
commit 1e39b6da88
49 changed files with 7172 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
"""DDL query commands — show table fields, read table data."""
from __future__ import annotations
from sapcli.cli.output import print_error, print_info
def cmd_show_table(args, client) -> None:
"""查看 DDIC 表字段结构。"""
table_name = args.name.upper()
print_info(f"查询表 {table_name} 的字段结构...")
fields = client.get_table_fields(table_name)
if not fields:
print_error(f"{table_name} 无字段信息")
return
print()
print("=" * 72)
print(f"{table_name} — 字段结构")
print("=" * 72)
print(f" {'字段名':<20} {'类型':<6} {'长度':<6} {'Key':<5} {'描述'}")
print("-" * 72)
for f in fields:
print(f" {f['name']:<20} {f['type']:<6} {f['length']:<6} {f['key_attribute']:<5} {f['description']}")
print("-" * 72)
print(f"{len(fields)} 个字段")
print()
def cmd_read_table(args, client) -> None:
"""查询表数据(ADT freestyle SQL)。"""
table_name = args.name.upper()
max_rows = getattr(args, "max_rows", 200)
where = getattr(args, "where", None)
fields = getattr(args, "fields", None)
select = fields if fields else "*"
sql = f"SELECT {select} FROM {table_name}"
if where:
sql += f" WHERE {where}"
sql += f" UP TO {max_rows} ROWS"
print_info(f"执行 SQL: {sql}")
result = client.query_table_data(sql, max_rows=max_rows)
columns = result["columns"]
rows = result["rows"]
total = result["total_rows"]
if not rows:
print()
print_error(f"{table_name} 无数据({total} 行)")
print()
return
# 计算列宽
col_widths = []
for i, col in enumerate(columns):
max_w = len(col)
for row in rows:
if i < len(row):
max_w = max(max_w, min(len(str(row[i])), 40))
col_widths.append(max_w + 2)
# 限制总宽度
total_width = sum(col_widths) + len(columns) + 1
if total_width > 200:
# 截断过宽的列
scale = 200 / total_width
col_widths = [max(int(w * scale), 6) for w in col_widths]
sep = "+" + "+".join("-" * w for w in col_widths) + "+"
print()
print(sep)
# 表头
header = "|"
for i, col in enumerate(columns):
w = col_widths[i] if i < len(col_widths) else 10
header += f" {col:<{w-1}}|"
print(header)
print(sep)
# 数据行
for row in rows:
line = "|"
for i, val in enumerate(row):
w = col_widths[i] if i < len(col_widths) else 10
s = str(val)[:w-1]
line += f" {s:<{w-1}}|"
print(line)
print(sep)
exec_time = result.get("execution_time", "")
time_info = f" ({exec_time}ms)" if exec_time else ""
print(f" {len(rows)}{time_info}")
print()