classinfo.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package schema
  2. import (
  3. "strings"
  4. "git.wecise.com/wecise/odb-go/schema"
  5. "github.com/scylladb/go-set/strset"
  6. "github.com/wecisecode/util/cmap"
  7. )
  8. type FieldInfo struct {
  9. Fieldname string
  10. Fieldtype string
  11. Keyidx int // 主键顺序值,0为非主键
  12. Datakey []string // 对应数据中的键名
  13. }
  14. type ClassInfo struct {
  15. Classaliasname string
  16. Classfullname string
  17. Fieldslist []string
  18. Keyfields []string
  19. Fieldinfos map[string]*FieldInfo
  20. DatakeyFieldinfos map[string]*FieldInfo
  21. WithOptions [][2]string
  22. Insertmql string
  23. Createmql string
  24. Addtagmql string
  25. }
  26. var ClassInfos = cmap.NewSingle[string, *ClassInfo]()
  27. var ClassAliasNames = []string{}
  28. func ClassInfoHelper(oci *schema.ClassInfo) *ClassInfo {
  29. fis := []*FieldInfo{}
  30. for _, fi := range oci.Fieldinfos {
  31. if fi.Fieldname == "id" {
  32. fis = append(fis, &FieldInfo{
  33. Fieldname: "id",
  34. Fieldtype: "varchar",
  35. Keyidx: 0,
  36. Datakey: []string{"id"},
  37. })
  38. } else {
  39. fis = append(fis, &FieldInfo{
  40. Fieldname: fi.Fieldname,
  41. Fieldtype: fi.Fieldtype,
  42. Keyidx: fi.Keyidx,
  43. Datakey: fi.NameMapping("dispname"),
  44. })
  45. }
  46. }
  47. return NewClassinfo(oci.Aliasname, oci.Shortname, oci.Basealias, fis, oci.WithOptions...)
  48. }
  49. func NewClassinfo(classaliasname, classsimplename, baseclassaliasname string, fieldinfoslist []*FieldInfo, withoptions ...[2]string) (ci *ClassInfo) {
  50. fieldinfos := map[string]*FieldInfo{}
  51. datakey_fieldinfos := map[string]*FieldInfo{}
  52. fieldslist := []string{}
  53. fieldsset := strset.New()
  54. keyfields := []string{}
  55. createmql := `create class if not exists ` + classsimplename + `:` + baseclassaliasname + `(`
  56. classfullname := ""
  57. bci := ClassInfos.GetIFPresent(baseclassaliasname)
  58. if bci != nil {
  59. classfullname = bci.Classfullname + "/" + classsimplename
  60. for fn, fi := range bci.Fieldinfos {
  61. fieldinfos[fn] = fi
  62. for _, dk := range fi.Datakey {
  63. datakey_fieldinfos[dk] = fi
  64. }
  65. }
  66. fieldslist = append(fieldslist, bci.Fieldslist...)
  67. fieldsset.Add(bci.Fieldslist...)
  68. keyfields = append(keyfields, bci.Keyfields...)
  69. } else {
  70. if baseclassaliasname != "/" && baseclassaliasname != "" {
  71. panic("baseclassname not defined " + baseclassaliasname)
  72. }
  73. classfullname = "/" + classsimplename
  74. }
  75. defer func() {
  76. ClassAliasNames = append(ClassAliasNames, classaliasname)
  77. ClassInfos.Set(classaliasname, ci)
  78. ClassInfos.Set(classfullname, ci)
  79. }()
  80. keyfield_defines := []string{}
  81. if len(fieldinfoslist) > 0 {
  82. field_defines := []string{}
  83. for _, fi := range fieldinfoslist {
  84. field_define := fi.Fieldname + ` ` + fi.Fieldtype
  85. if !fieldsset.Has(fi.Fieldname) {
  86. fieldslist = append(fieldslist, fi.Fieldname)
  87. fieldsset.Add(fi.Fieldname)
  88. } else {
  89. for _, dk := range bci.Fieldinfos[fi.Fieldname].Datakey {
  90. if !strset.New(fi.Datakey...).Has(dk) {
  91. fi.Datakey = append(fi.Datakey, dk)
  92. }
  93. }
  94. }
  95. field_define += `"` + strings.Join(fi.Datakey, ",") + `"`
  96. field_defines = append(field_defines, field_define)
  97. if fi.Keyidx > 0 {
  98. for len(keyfield_defines) < fi.Keyidx {
  99. keyfield_defines = append(keyfield_defines, "")
  100. }
  101. keyfield_defines[fi.Keyidx-1] = fi.Fieldname
  102. }
  103. fieldinfos[fi.Fieldname] = fi
  104. for _, dk := range fi.Datakey {
  105. datakey_fieldinfos[dk] = fi
  106. }
  107. }
  108. createmql += strings.Join(field_defines, ",")
  109. }
  110. if len(keyfield_defines) > 0 {
  111. createmql += ", keys(" + strings.Join(keyfield_defines, ",") + ")"
  112. keyfields = append(keyfields, keyfield_defines...)
  113. }
  114. createmql += `)with alias='` + classaliasname + `'`
  115. for _, withoption := range withoptions {
  116. if withoption[0] == "alias" {
  117. continue
  118. }
  119. createmql += " and " + withoption[0] + "=" + withoption[1]
  120. if withoption[0] == "key" && withoption[1] == "manu" {
  121. if !fieldsset.Has("id") {
  122. fieldslist = append([]string{"id"}, fieldslist...)
  123. fieldsset.Add("id")
  124. }
  125. }
  126. }
  127. if !fieldsset.Has("contain") {
  128. fieldslist = append(fieldslist, "contain")
  129. fieldsset.Add("contain")
  130. }
  131. if !fieldsset.Has("depend") {
  132. fieldslist = append(fieldslist, "depend")
  133. fieldsset.Add("depend")
  134. }
  135. if !fieldsset.Has("topology") {
  136. fieldslist = append(fieldslist, "topology")
  137. fieldsset.Add("topology")
  138. }
  139. var insertmql string
  140. if len(fieldslist) > 0 {
  141. insertmql = `insert into ` + classfullname + "(" + strings.Join(fieldslist, ",") + ")values(" + strings.Repeat(",?", len(fieldslist))[1:] + ")"
  142. }
  143. addtagmql := `insert into /matrix/tagdir (name,path,tags,domain,creater) values(?,?,?,'graph','system')`
  144. ci = &ClassInfo{
  145. Classaliasname: classaliasname,
  146. Classfullname: classfullname,
  147. Fieldinfos: fieldinfos,
  148. WithOptions: withoptions,
  149. DatakeyFieldinfos: datakey_fieldinfos,
  150. Keyfields: keyfields,
  151. Fieldslist: fieldslist,
  152. Insertmql: insertmql,
  153. Createmql: createmql,
  154. Addtagmql: addtagmql,
  155. }
  156. return
  157. }