classinfo.go 4.4 KB

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