Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e08b20698 | |||
| c8382200a0 | |||
| b951ba027e | |||
| a0719dc72d |
@@ -209,6 +209,17 @@ var TptProject = Proj{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
columns := that.MakeCodeRouter[hotimeName].TableConfig.GetMap(tableName).GetSlice("columns")
|
||||||
|
for k := range columns {
|
||||||
|
if columns.GetMap(k).GetString("name") == "state" {
|
||||||
|
stateVal := inData["state"]
|
||||||
|
if stateVal == nil || ObjToStr(stateVal) == "" {
|
||||||
|
inData["state"] = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
re := that.Db.Insert(tableName, inData)
|
re := that.Db.Insert(tableName, inData)
|
||||||
|
|
||||||
if re == 0 {
|
if re == 0 {
|
||||||
@@ -604,9 +615,13 @@ var TptProject = Proj{
|
|||||||
if download == 1 {
|
if download == 1 {
|
||||||
|
|
||||||
tableNameLabel := that.MakeCodeRouter[hotimeName].TableConfig.GetMap(tableName).GetString("label")
|
tableNameLabel := that.MakeCodeRouter[hotimeName].TableConfig.GetMap(tableName).GetString("label")
|
||||||
|
sheetName := tableNameLabel
|
||||||
|
if sheetName == "" || len(sheetName) > 31 {
|
||||||
|
sheetName = tableName
|
||||||
|
}
|
||||||
f := excelize.NewFile()
|
f := excelize.NewFile()
|
||||||
// 创建一个工作表
|
// 创建一个工作表
|
||||||
f.NewSheet(tableNameLabel)
|
f.NewSheet(sheetName)
|
||||||
|
|
||||||
f.DeleteSheet("Sheet1")
|
f.DeleteSheet("Sheet1")
|
||||||
columns := that.MakeCodeRouter[hotimeName].TableConfig.GetMap(tableName).GetSlice("columns")
|
columns := that.MakeCodeRouter[hotimeName].TableConfig.GetMap(tableName).GetSlice("columns")
|
||||||
@@ -622,21 +637,21 @@ var TptProject = Proj{
|
|||||||
//单行
|
//单行
|
||||||
for k1, v1 := range reData {
|
for k1, v1 := range reData {
|
||||||
if k1 == 0 {
|
if k1 == 0 {
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+"1", v.GetString("label"))
|
f.SetCellValue(sheetName, convertToTitle(n)+"1", v.GetString("label"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.GetString("link") != "" {
|
if v.GetString("link") != "" {
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+ObjToStr(k1+2), v1.GetString(v.GetString("link")+"_"+v.GetString("name")+"_"+v.GetString("value")))
|
f.SetCellValue(sheetName, convertToTitle(n)+ObjToStr(k1+2), v1.GetString(v.GetString("link")+"_"+v.GetString("name")+"_"+v.GetString("value")))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.GetString("name") == "table" {
|
if v.GetString("name") == "table" {
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+ObjToStr(k1+2), v1.GetString("table_"+v.GetString("name")+"_name"))
|
f.SetCellValue(sheetName, convertToTitle(n)+ObjToStr(k1+2), v1.GetString("table_"+v.GetString("name")+"_name"))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.GetString("name") == "table_id" {
|
if v.GetString("name") == "table_id" {
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+ObjToStr(k1+2), v1.GetString("table_"+v.GetString("name")+"_name"))
|
f.SetCellValue(sheetName, convertToTitle(n)+ObjToStr(k1+2), v1.GetString("table_"+v.GetString("name")+"_name"))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +662,7 @@ var TptProject = Proj{
|
|||||||
for ok, _ := range options {
|
for ok, _ := range options {
|
||||||
ov := options.GetMap(ok)
|
ov := options.GetMap(ok)
|
||||||
if ov.GetString("value") == v1.GetString(v.GetString("name")) {
|
if ov.GetString("value") == v1.GetString(v.GetString("name")) {
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+ObjToStr(k1+2), ov.GetString("name"))
|
f.SetCellValue(sheetName, convertToTitle(n)+ObjToStr(k1+2), ov.GetString("name"))
|
||||||
isEnd = true
|
isEnd = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -659,7 +674,7 @@ var TptProject = Proj{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f.SetCellValue(tableNameLabel, convertToTitle(n)+ObjToStr(k1+2), v1.GetString(v.GetString("name")))
|
f.SetCellValue(sheetName, convertToTitle(n)+ObjToStr(k1+2), v1.GetString(v.GetString("name")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filePath := that.Config.GetString("filePath")
|
filePath := that.Config.GetString("filePath")
|
||||||
@@ -668,7 +683,7 @@ var TptProject = Proj{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//path := time.Now().Format(filePath)
|
//path := time.Now().Format(filePath)
|
||||||
e := os.MkdirAll(that.Config.GetString("tpt")+filePath, os.ModeDir)
|
e := os.MkdirAll(that.Config.GetString("tpt")+filePath, 0755)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
that.Display(3, e)
|
that.Display(3, e)
|
||||||
return
|
return
|
||||||
@@ -677,7 +692,7 @@ var TptProject = Proj{
|
|||||||
|
|
||||||
// 根据指定路径保存文件
|
// 根据指定路径保存文件
|
||||||
if err := f.SaveAs(that.Config.GetString("tpt") + filePath); err != nil {
|
if err := f.SaveAs(that.Config.GetString("tpt") + filePath); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Printf("SaveAs failed: %v\n", err)
|
||||||
that.Display(4, "输出异常")
|
that.Display(4, "输出异常")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -875,7 +890,7 @@ var TptProject = Proj{
|
|||||||
}
|
}
|
||||||
|
|
||||||
path := time.Now().Format(filePath)
|
path := time.Now().Format(filePath)
|
||||||
e := os.MkdirAll(that.Config.GetString("tpt")+path, os.ModeDir)
|
e := os.MkdirAll(that.Config.GetString("tpt")+path, 0755)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
that.Display(3, e)
|
that.Display(3, e)
|
||||||
return
|
return
|
||||||
|
|||||||
+29
-5
@@ -175,7 +175,9 @@ func (that *MakeCode) Db2JSON(db *db.HoTimeDB, config Map) {
|
|||||||
tableInfo = db.Query("pragma table_info([" + v.GetString("name") + "]);")
|
tableInfo = db.Query("pragma table_info([" + v.GetString("name") + "]);")
|
||||||
}
|
}
|
||||||
if db.Type == "dm" || db.Type == "dameng" {
|
if db.Type == "dm" || db.Type == "dameng" {
|
||||||
tableInfo = db.Query(`SELECT c.COLUMN_NAME AS "name", c.DATA_TYPE AS "type", m.COMMENTS AS "label", c.NULLABLE AS "must", c.DATA_DEFAULT AS "dflt_value" FROM ALL_TAB_COLUMNS c LEFT JOIN USER_COL_COMMENTS m ON c.TABLE_NAME=m.TABLE_NAME AND c.COLUMN_NAME=m.COLUMN_NAME WHERE c.TABLE_NAME='` + v.GetString("name") + `' AND c.OWNER='` + db.DBName + `' ORDER BY c.COLUMN_ID`)
|
// 必须用 ALL_COL_COMMENTS 并按 OWNER 对齐:USER_COL_COMMENTS 无 schema,
|
||||||
|
// 在 SYSDBA 下常混入同名表空注释或读不到业务库(如 login_config)列备注。
|
||||||
|
tableInfo = db.Query(`SELECT c.COLUMN_NAME AS "name", c.DATA_TYPE AS "type", m.COMMENTS AS "label", c.NULLABLE AS "must", c.DATA_DEFAULT AS "dflt_value" FROM ALL_TAB_COLUMNS c LEFT JOIN ALL_COL_COMMENTS m ON c.OWNER=m.OWNER AND c.TABLE_NAME=m.TABLE_NAME AND c.COLUMN_NAME=m.COLUMN_NAME WHERE c.TABLE_NAME='` + v.GetString("name") + `' AND c.OWNER='` + db.DBName + `' ORDER BY c.COLUMN_ID`)
|
||||||
}
|
}
|
||||||
|
|
||||||
idSlice = append(idSlice, tableInfo)
|
idSlice = append(idSlice, tableInfo)
|
||||||
@@ -303,11 +305,33 @@ func (that *MakeCode) Db2JSON(db *db.HoTimeDB, config Map) {
|
|||||||
options := Slice{}
|
options := Slice{}
|
||||||
comments := strings.Split(info.GetString("label"), ":")
|
comments := strings.Split(info.GetString("label"), ":")
|
||||||
if len(comments) >= 2 {
|
if len(comments) >= 2 {
|
||||||
optionComment := strings.Split(comments[1], ",")
|
// 截掉空格后附加说明 / {} 提示,避免污染 options 解析
|
||||||
|
optPart := comments[1]
|
||||||
|
if idx := strings.Index(optPart, " "); idx > -1 {
|
||||||
|
optPart = optPart[:idx]
|
||||||
|
}
|
||||||
|
for _, pair := range [][2]string{{"{", "}"}, {"(", ")"}, {"(", ")"}} {
|
||||||
|
if start := strings.Index(optPart, pair[0]); start != -1 {
|
||||||
|
optPart = optPart[:start]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
optionComment := strings.Split(optPart, ",")
|
||||||
for _, v := range optionComment {
|
for _, v := range optionComment {
|
||||||
optionSlice := strings.Split(v, "-")
|
v = strings.TrimSpace(v)
|
||||||
if len(optionSlice) >= 2 {
|
if v == "" {
|
||||||
options = append(options, Map{"name": optionSlice[1], "value": optionSlice[0]})
|
continue
|
||||||
|
}
|
||||||
|
// 兼容规范「值-名称」与存量「值=名称」
|
||||||
|
sep := -1
|
||||||
|
for i, r := range v {
|
||||||
|
if r == '-' || r == '=' {
|
||||||
|
sep = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sep > 0 && sep < len(v)-1 {
|
||||||
|
options = append(options, Map{"name": strings.TrimSpace(v[sep+1:]), "value": strings.TrimSpace(v[:sep])})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -34,17 +34,19 @@ HoTime 框架内置 Seq 日志推送支持。通过在 `config.json` 填写 `seq
|
|||||||
|
|
||||||
框架在 `handler` 入口派生请求级 Logger,并浅拷贝 `Db` 将其 `Log` 指向同一 Logger,因此 **SQL 日志自动带会话字段**。字段会出现在同条日志的控制台/文件/Seq 出口上。
|
框架在 `handler` 入口派生请求级 Logger,并浅拷贝 `Db` 将其 `Log` 指向同一 Logger,因此 **SQL 日志自动带会话字段**。字段会出现在同条日志的控制台/文件/Seq 出口上。
|
||||||
|
|
||||||
业务在 `SetConnectListener` 鉴权通过后绑定(xbc `main.go`):
|
业务在 `SetConnectListener` 中按需绑定自定义字段(建议放在鉴权/守卫之前,这样未登录被拒的 Warning 也能带上维度字段):
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// app 鉴权通过后
|
appIns.SetConnectListener(func(context *Context) bool {
|
||||||
context.LogBind("user_id", context.Session("user_id").ToCeilInt64())
|
if v := context.Session("user_id").ToCeilInt64(); v > 0 {
|
||||||
|
context.LogBind("user_id", v)
|
||||||
// admin 鉴权通过后(或 session 已有 admin_id)
|
}
|
||||||
context.LogBind("admin_id", context.Session("admin_id").ToCeilInt64())
|
// 其他 session / 请求参数字段同理:有值再绑
|
||||||
|
return false
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
`LogBind` 后,本请求后续业务日志与 SQL 日志都会带上该字段。
|
`LogBind` 后,本请求后续业务日志与 SQL 日志都会带上该字段。session 在 context 内有缓存,多次 `Session()` 只查一次库。字段名与取值由业务自行约定。
|
||||||
|
|
||||||
**不带会话字段的边界:**
|
**不带会话字段的边界:**
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// isInfrastructureFile 的入参是 shortenPath 后的短路径(最后两段)
|
||||||
|
func TestIsInfrastructureFile(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
file string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
// hotime 框架的 session/context 属中间层,应跳过
|
||||||
|
{"hotime@v1.7.302/session.go", true},
|
||||||
|
{"hotimev1.5/session.go", true},
|
||||||
|
{"hotime@v1.7.302/context.go", true},
|
||||||
|
// 框架基础设施目录
|
||||||
|
{"db/db.go", true},
|
||||||
|
{"cache/cache_db.go", true},
|
||||||
|
{"zerolog/log.go", true},
|
||||||
|
// hotime 根包其余文件不跳过(application.go、code.go 的日志是框架自身行为)
|
||||||
|
{"hotime@v1.7.302/application.go", false},
|
||||||
|
{"hotime@v1.7.302/code.go", false},
|
||||||
|
// 业务侧同名文件不受影响(路径不含 hotime)
|
||||||
|
{"wx/session.go", false},
|
||||||
|
{"app/user.go", false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
if got := isInfrastructureFile(c.file); got != c.want {
|
||||||
|
t.Errorf("isInfrastructureFile(%q) = %v, want %v", c.file, got, c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -890,6 +890,11 @@ func isInfrastructureFile(file string) bool {
|
|||||||
if strings.HasSuffix(file, "/context.go") || strings.HasSuffix(file, "\\context.go") {
|
if strings.HasSuffix(file, "/context.go") || strings.HasSuffix(file, "\\context.go") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// session.go 是 session 存取中间层,永远不是业务发起点;
|
||||||
|
// 跳过后 session 读写触发的 SQL 日志 caller 直接落业务帧(而非 session.go:29 <- 业务帧)
|
||||||
|
if strings.HasSuffix(file, "/session.go") || strings.HasSuffix(file, "\\session.go") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user