i18n.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package db
  15. import (
  16. "context"
  17. "yunion.io/x/pkg/errors"
  18. "yunion.io/x/onecloud/pkg/i18n"
  19. "yunion.io/x/onecloud/pkg/mcclient"
  20. )
  21. type IModelI18nBase interface {
  22. GetKeyValue() string
  23. Lookup(tag i18n.Tag) string
  24. }
  25. type IModelI18nEntry interface {
  26. IModelI18nBase
  27. GetGlobalId() string
  28. GetObjType() string
  29. GetObjId() string
  30. GetKeyName() string
  31. }
  32. type IModelI18nTable interface {
  33. GetI18nEntries() map[string]IModelI18nEntry
  34. }
  35. type SModelI18nEntry struct {
  36. model IModel
  37. i18nEntry IModelI18nBase
  38. modelKeyName string
  39. }
  40. func NewSModelI18nEntry(keyName string, model IModel, i18nEntry IModelI18nBase) *SModelI18nEntry {
  41. return &SModelI18nEntry{model: model, modelKeyName: keyName, i18nEntry: i18nEntry}
  42. }
  43. func (in *SModelI18nEntry) GetObjType() string {
  44. return in.model.Keyword()
  45. }
  46. func (in *SModelI18nEntry) GetObjId() string {
  47. return in.model.GetId()
  48. }
  49. func (in *SModelI18nEntry) GetKeyName() string {
  50. return in.modelKeyName
  51. }
  52. func (in *SModelI18nEntry) GetKeyValue() string {
  53. return in.i18nEntry.GetKeyValue()
  54. }
  55. func (in *SModelI18nEntry) Lookup(tag i18n.Tag) string {
  56. return in.i18nEntry.Lookup(tag)
  57. }
  58. func (in *SModelI18nEntry) GetGlobalId() string {
  59. return in.model.Keyword() + "::" + in.model.GetId() + "::" + in.modelKeyName
  60. }
  61. type SModelI18nTable struct {
  62. i18nEntires []IModelI18nEntry
  63. }
  64. func NewSModelI18nTable(i18nEntires []IModelI18nEntry) *SModelI18nTable {
  65. return &SModelI18nTable{i18nEntires: i18nEntires}
  66. }
  67. func (t *SModelI18nTable) GetI18nEntries() map[string]IModelI18nEntry {
  68. ret := make(map[string]IModelI18nEntry, 0)
  69. for i := range t.i18nEntires {
  70. entry := t.i18nEntires[i]
  71. ret[entry.GetKeyValue()] = entry
  72. }
  73. return ret
  74. }
  75. type SI18nManager struct {
  76. SModelBaseManager
  77. // SStandaloneAnonResourceBaseManager
  78. }
  79. type SI18n struct {
  80. SModelBase
  81. // SStandaloneAnonResourceBase
  82. // 资源类型
  83. // example: network
  84. ObjType string `width:"40" charset:"ascii" list:"user" get:"user" primary:"true"`
  85. // 资源ID
  86. // example: 87321a70-1ecb-422a-8b0c-c9aa632a46a7
  87. ObjId string `width:"88" charset:"ascii" list:"user" get:"user" primary:"true"`
  88. // 资源KEY
  89. // exmaple: name
  90. KeyName string `width:"64" charset:"utf8" list:"user" get:"user" primary:"true"`
  91. // 资源原始值
  92. // example: 技术部
  93. KeyValue string `charset:"utf8" list:"user" get:"user"`
  94. // KeyValue 对应中文翻译
  95. Cn string `charset:"utf8" list:"user" get:"user"`
  96. // KeyValue 对应英文翻译
  97. En string `charset:"utf8" list:"user" get:"user"`
  98. }
  99. var I18nManager *SI18nManager
  100. func init() {
  101. I18nManager = &SI18nManager{
  102. SModelBaseManager: NewModelBaseManager(
  103. SI18n{},
  104. "i18n2_tbl",
  105. "i18n",
  106. "i18ns",
  107. ),
  108. }
  109. I18nManager.SetVirtualObject(I18nManager)
  110. }
  111. func (manager *SI18nManager) GetModelI18N(ctx context.Context, model IModel) ([]SI18n, error) {
  112. ret := []SI18n{}
  113. q := manager.Query().Equals("obj_type", model.Keyword()).Equals("obj_id", model.GetId())
  114. err := FetchModelObjects(manager, q, &ret)
  115. if err != nil {
  116. return nil, errors.Wrap(err, "FetchModelObjects")
  117. }
  118. return ret, err
  119. }
  120. func (manager *SI18nManager) GetModelKeyI18N(ctx context.Context, model IModel, keyName string) ([]SI18n, error) {
  121. ret := []SI18n{}
  122. q := manager.Query().Equals("obj_type", model.Keyword()).Equals("obj_id", model.GetId()).Equals("key_name", keyName)
  123. err := FetchModelObjects(manager, q, &ret)
  124. if err != nil {
  125. return nil, errors.Wrap(err, "FetchModelObjects")
  126. }
  127. return ret, err
  128. }
  129. func (manager *SI18nManager) getExternalI18nItems(ctx context.Context, table IModelI18nTable) []IModelI18nEntry {
  130. ret := make([]IModelI18nEntry, 0)
  131. items := table.GetI18nEntries()
  132. for k, _ := range items {
  133. ret = append(ret, items[k])
  134. }
  135. return ret
  136. }
  137. func (manager *SI18nManager) SyncI18ns(ctx context.Context, userCred mcclient.TokenCredential, model IModel, table IModelI18nTable) error {
  138. //// No need to lock SI18nManager, the resources has been lock in the upper layer - QIU Jian, 20210405
  139. extItems := manager.getExternalI18nItems(ctx, table)
  140. for i := range extItems {
  141. _, err := manager.newFromI18n(ctx, userCred, extItems[i])
  142. if err != nil {
  143. return errors.Wrap(err, "newFromI18n")
  144. }
  145. }
  146. return nil
  147. }
  148. func (manager *SI18nManager) newFromI18n(ctx context.Context, userCred mcclient.TokenCredential, entry IModelI18nEntry) (*SI18n, error) {
  149. in := SI18n{}
  150. in.SetModelManager(manager, &in)
  151. in.ObjId = entry.GetObjId()
  152. in.ObjType = entry.GetObjType()
  153. in.KeyName = entry.GetKeyName()
  154. in.KeyValue = entry.GetKeyValue()
  155. in.Cn = entry.Lookup(i18n.I18N_TAG_CHINESE)
  156. in.En = entry.Lookup(i18n.I18N_TAG_ENGLISH)
  157. err := manager.TableSpec().InsertOrUpdate(ctx, &in)
  158. if err != nil {
  159. return nil, errors.Wrapf(err, "newFromI18n.Insert")
  160. }
  161. return &in, nil
  162. }
  163. func (in SI18n) GetExternalId() string {
  164. return in.ObjType + "::" + in.ObjId + "::" + in.KeyName
  165. }
  166. func (in *SI18n) Lookup(ctx context.Context) string {
  167. entry := i18n.NewTableEntry().CN(in.Cn).EN(in.En)
  168. if v, ok := entry.Lookup(ctx); ok {
  169. return v
  170. }
  171. return in.KeyValue
  172. }