utils.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. package utils
  2. import (
  3. "bytes"
  4. "compress/gzip"
  5. "errors"
  6. "fmt"
  7. "go/format"
  8. "html/template"
  9. "net/url"
  10. "os"
  11. "path/filepath"
  12. "strings"
  13. "time"
  14. "unicode"
  15. "unsafe"
  16. )
  17. var DSNError = errors.New("dsn string error")
  18. func FirstCharacter(name string) string {
  19. return strings.ToLower(name)[:1]
  20. }
  21. func CamelizeStr(s string, upperCase bool) string {
  22. if len(s) == 0 {
  23. return s
  24. }
  25. s = replaceInvalidChars(s)
  26. var result string
  27. words := strings.Split(s, "_")
  28. for i, word := range words {
  29. //if upper := strings.ToUpper(word); commonInitialisms[upper] {
  30. // result += upper
  31. // continue
  32. //}
  33. if i > 0 || upperCase {
  34. result += camelizeWord(word)
  35. } else {
  36. result += word
  37. }
  38. }
  39. return result
  40. }
  41. func camelizeWord(word string) string {
  42. runes := []rune(word)
  43. for i, r := range runes {
  44. if i == 0 {
  45. runes[i] = unicode.ToUpper(r)
  46. } else {
  47. runes[i] = r
  48. //runes[i] = unicode.ToLower(r)
  49. }
  50. }
  51. return string(runes)
  52. }
  53. func replaceInvalidChars(str string) string {
  54. str = strings.ReplaceAll(str, "-", "_")
  55. str = strings.ReplaceAll(str, " ", "_")
  56. return strings.ReplaceAll(str, ".", "_")
  57. }
  58. // https://github.com/golang/lint/blob/206c0f020eba0f7fbcfbc467a5eb808037df2ed6/lint.go#L731
  59. var commonInitialisms = map[string]bool{
  60. "ACL": true,
  61. "API": true,
  62. "ASCII": true,
  63. "CPU": true,
  64. "CSS": true,
  65. "DNS": true,
  66. "EOF": true,
  67. "ETA": true,
  68. "GPU": true,
  69. "GUID": true,
  70. "HTML": true,
  71. "HTTP": true,
  72. "HTTPS": true,
  73. "ID": true,
  74. "IP": true,
  75. "JSON": true,
  76. "LHS": true,
  77. "OS": true,
  78. "QPS": true,
  79. "RAM": true,
  80. "RHS": true,
  81. "RPC": true,
  82. "SLA": true,
  83. "SMTP": true,
  84. "SQL": true,
  85. "SSH": true,
  86. "TCP": true,
  87. "TLS": true,
  88. "TTL": true,
  89. "UDP": true,
  90. "UI": true,
  91. "UID": true,
  92. "UUID": true,
  93. "URI": true,
  94. "URL": true,
  95. "UTF8": true,
  96. "VM": true,
  97. "XML": true,
  98. "XMPP": true,
  99. "XSRF": true,
  100. "XSS": true,
  101. "OAuth": true,
  102. }
  103. func GetDbNameFromDSN(dsn string) (string, error) {
  104. if len(strings.Split(dsn, " ")) > 1 {
  105. return getDbNameFromDsn(dsn)
  106. }
  107. index := strings.LastIndex(dsn, "/")
  108. if index <= 0 {
  109. return getDbNameFromDsn(dsn)
  110. }
  111. str := dsn[index:]
  112. urlStr, err := url.Parse(str)
  113. if err != nil {
  114. return "", err
  115. }
  116. return strings.Trim(urlStr.Path, "/"), nil
  117. }
  118. // host=127.0.0.1 dbname=test sslmode=disable Timezone=Asia/Shanghai
  119. const dbNamePrefix = "dbname="
  120. func getDbNameFromDsn(dsn string) (string, error) {
  121. strArray := strings.Split(dsn, " ")
  122. for _, item := range strArray {
  123. if strings.HasPrefix(item, dbNamePrefix) {
  124. return strings.TrimPrefix(item, dbNamePrefix), nil
  125. }
  126. }
  127. return "", DSNError
  128. }
  129. func SaveFile(dirPath, fileName string, text []byte) error {
  130. file, err := os.Create(filepath.Join(dirPath, fileName))
  131. if err != nil {
  132. return err
  133. }
  134. defer file.Close()
  135. p, err := format.Source(text)
  136. if err != nil {
  137. return err
  138. }
  139. _, err = file.Write(p)
  140. return err
  141. }
  142. func MkdirPathIfNotExist(dirPath string) error {
  143. if _, err := os.Stat(dirPath); os.IsNotExist(err) {
  144. return os.MkdirAll(dirPath, os.ModePerm)
  145. }
  146. return nil
  147. }
  148. func CleanUpGenFiles(dir string) error {
  149. exist, err := FileExists(dir)
  150. if err != nil {
  151. return err
  152. }
  153. if exist {
  154. return os.RemoveAll(dir)
  155. }
  156. return nil
  157. }
  158. // FileExists reports whether the named file or directory exists.
  159. func FileExists(name string) (bool, error) {
  160. if _, err := os.Stat(name); err != nil {
  161. if os.IsNotExist(err) {
  162. return false, err
  163. }
  164. }
  165. return true, nil
  166. }
  167. func ZipBytes(data []byte) []byte {
  168. var out bytes.Buffer
  169. w := gzip.NewWriter(&out)
  170. defer w.Close()
  171. w.Write(data)
  172. w.Flush()
  173. return out.Bytes()
  174. }
  175. func UnzipBytes(data []byte) []byte {
  176. var in bytes.Buffer
  177. in.Write(data)
  178. r, _ := gzip.NewReader(&in)
  179. var out bytes.Buffer
  180. defer r.Close()
  181. out.ReadFrom(r)
  182. return out.Bytes()
  183. }
  184. func Str2bytes(s string) []byte {
  185. x := (*[2]uintptr)(unsafe.Pointer(&s))
  186. h := [3]uintptr{x[0], x[1], x[1]}
  187. return *(*[]byte)(unsafe.Pointer(&h))
  188. }
  189. func Bytes2str(b []byte) string {
  190. return *(*string)(unsafe.Pointer(&b))
  191. }
  192. func If(condition bool, trueVal, falseVal interface{}) interface{} {
  193. if condition {
  194. return trueVal
  195. }
  196. return falseVal
  197. }
  198. func NewResult(rType string, rName string, apigen func(templateData interface{}, params map[string]interface{}) ([]byte, error), templateData interface{}, isCompress bool) *GenerateResult {
  199. gr := GenerateResult{}
  200. gr.Type = rType
  201. gr.Name = rName
  202. genBytes, err := apigen(templateData, nil)
  203. if err != nil {
  204. fmt.Println(err.Error())
  205. return nil
  206. }
  207. //fmt.Println(string(genBytes))
  208. if isCompress {
  209. gr.Content = ZipBytes(genBytes)
  210. } else {
  211. gr.Content = genBytes
  212. }
  213. return &gr
  214. }
  215. func GenTemplate(templateText string, templateData interface{}, params map[string]interface{}) ([]byte, error) {
  216. t, err := template.New("template").Funcs(template.FuncMap{
  217. "CamelizeStr": CamelizeStr,
  218. "FirstCharacter": FirstCharacter,
  219. "Replace": func(old, new, src string) string {
  220. return strings.ReplaceAll(src, old, new)
  221. },
  222. "Add": func(a, b int) int {
  223. return a + b
  224. },
  225. "Now": func() string {
  226. return time.Now().Format(time.RFC3339)
  227. },
  228. "Xorm": func(col XmlColumn) string {
  229. str := fmt.Sprintf(`xorm:"%s %s %s %s %s %s" `,
  230. "'"+col.Name+"'",
  231. col.DbType,
  232. If(col.IsPK, "pk", ""),
  233. If(col.AutoIncrement, "autoincr", ""),
  234. If(col.IsNull, "null", "notnull"),
  235. If(col.IsUnique, "unique", If(col.IsIndex, "index", "")))
  236. return str
  237. },
  238. "XormTime": func(time string) interface{} {
  239. return If(time == "local_time", "sysmodel.LocalTime", time)
  240. },
  241. "Backquote": func() string {
  242. return "`"
  243. },
  244. // 定义函数unescaped
  245. "Unescaped": func(x string) interface{} {
  246. return template.HTML(x)
  247. },
  248. "TrimPrefix": strings.TrimPrefix,
  249. "TrimSuffix": strings.TrimSuffix,
  250. "Contains": strings.Contains,
  251. "ParamsContainDT": func(params []XmlColumn) bool {
  252. isContain := false
  253. for _, v := range params {
  254. if strings.ToLower(v.DbType) =="datetime" {
  255. isContain = true
  256. break
  257. }
  258. }
  259. return isContain
  260. },
  261. "AllParams": func(params []XmlApiParam) string {
  262. str := ""
  263. for i, v := range params {
  264. if i > 0 {
  265. str += ", "
  266. }
  267. str += v.Name
  268. }
  269. return str
  270. },
  271. "SqlAllColumns": func(cols []XmlColumn, isValues bool) string {
  272. str := ""
  273. for i, v := range cols {
  274. if i > 0 {
  275. str += ", "
  276. }
  277. if isValues {
  278. str += "?" + v.Name
  279. } else {
  280. str += "`" + v.Name + "`"
  281. }
  282. }
  283. return str
  284. },
  285. "SqlNoPKUpdate": func(cols []XmlColumn) string {
  286. str := ""
  287. for _, v := range cols {
  288. if !v.IsPK {
  289. str += "`" + v.Name + "` = ?" + v.Name
  290. str += ", "
  291. }
  292. }
  293. out := strings.TrimSuffix(str, ", ")
  294. return out
  295. },
  296. "SqlPKWhere": func(cols []XmlColumn) string {
  297. str := ""
  298. for _, v := range cols {
  299. if v.IsPK {
  300. str += "`" + v.Name + "` = ?" + v.Name
  301. str += " AND "
  302. }
  303. }
  304. out := strings.TrimSuffix(str, " AND ")
  305. return out
  306. },
  307. "Param": func(name string) interface{} {
  308. if v, ok := params[name]; ok {
  309. return v
  310. }
  311. return ""
  312. },
  313. }).Parse(templateText)
  314. if err != nil {
  315. fmt.Println(err.Error())
  316. return nil, err
  317. }
  318. var buf bytes.Buffer
  319. if err := t.Execute(&buf, templateData); err != nil {
  320. fmt.Println(err.Error())
  321. return nil, err
  322. }
  323. return buf.Bytes(), nil
  324. }