wrapper.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package wrapper
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "html/template"
  7. "net/http"
  8. "os"
  9. "strconv"
  10. "time"
  11. "golang-fave/consts"
  12. "golang-fave/engine/mysqlpool"
  13. "golang-fave/engine/sqlw"
  14. "golang-fave/logger"
  15. "golang-fave/utils"
  16. "github.com/vladimirok5959/golang-server-sessions/session"
  17. )
  18. type Tx = sqlw.Tx
  19. var ErrNoRows = sqlw.ErrNoRows
  20. type Wrapper struct {
  21. l *logger.Logger
  22. W http.ResponseWriter
  23. R *http.Request
  24. S *session.Session
  25. Host string
  26. Port string
  27. CurrHost string
  28. DConfig string
  29. DHtdocs string
  30. DLogs string
  31. DTemplate string
  32. DTmp string
  33. IsBackend bool
  34. ConfMysqlExists bool
  35. UrlArgs []string
  36. CurrModule string
  37. CurrSubModule string
  38. MSPool *mysqlpool.MySqlPool
  39. Config *Config
  40. DB *sqlw.DB
  41. User *utils.MySql_user
  42. }
  43. func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, chost, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string, mp *mysqlpool.MySqlPool) *Wrapper {
  44. conf := configNew()
  45. _ = conf.configRead(dirConfig + string(os.PathSeparator) + "config.json")
  46. return &Wrapper{
  47. l: l,
  48. W: w,
  49. R: r,
  50. S: s,
  51. Host: host,
  52. Port: port,
  53. CurrHost: chost,
  54. DConfig: dirConfig,
  55. DHtdocs: dirHtdocs,
  56. DLogs: dirLogs,
  57. DTemplate: dirTemplate,
  58. DTmp: dirTmp,
  59. UrlArgs: []string{},
  60. CurrModule: "",
  61. CurrSubModule: "",
  62. MSPool: mp,
  63. Config: conf,
  64. }
  65. }
  66. func (this *Wrapper) LogAccess(msg string, vars ...interface{}) {
  67. this.l.Log(msg, this.R, false, vars...)
  68. }
  69. func (this *Wrapper) LogError(msg string, vars ...interface{}) {
  70. this.l.Log(msg, this.R, true, vars...)
  71. }
  72. func (this *Wrapper) dbReconnect() error {
  73. if !utils.IsMySqlConfigExists(this.DConfig + string(os.PathSeparator) + "mysql.json") {
  74. return errors.New("can't read database configuration file")
  75. }
  76. mc, err := utils.MySqlConfigRead(this.DConfig + string(os.PathSeparator) + "mysql.json")
  77. if err != nil {
  78. return err
  79. }
  80. this.DB, err = sqlw.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
  81. if err != nil {
  82. return err
  83. }
  84. this.MSPool.Set(this.CurrHost, this.DB)
  85. return nil
  86. }
  87. func (this *Wrapper) UseDatabase() error {
  88. this.DB = this.MSPool.Get(this.CurrHost)
  89. if this.DB == nil {
  90. if err := this.dbReconnect(); err != nil {
  91. return err
  92. }
  93. }
  94. if err := this.DB.Ping(); err != nil {
  95. this.DB.Close()
  96. if err := this.dbReconnect(); err != nil {
  97. return err
  98. }
  99. if err := this.DB.Ping(); err != nil {
  100. this.DB.Close()
  101. return err
  102. }
  103. }
  104. // Max 30 minutes and max 2 connection per host
  105. this.DB.SetConnMaxLifetime(time.Minute * 30)
  106. this.DB.SetMaxIdleConns(2)
  107. this.DB.SetMaxOpenConns(2)
  108. return nil
  109. }
  110. func (this *Wrapper) LoadSessionUser() bool {
  111. if this.S.GetInt("UserId", 0) <= 0 {
  112. return false
  113. }
  114. if this.DB == nil {
  115. return false
  116. }
  117. user := &utils.MySql_user{}
  118. err := this.DB.QueryRow(`
  119. SELECT
  120. id,
  121. first_name,
  122. last_name,
  123. email,
  124. password,
  125. admin,
  126. active
  127. FROM
  128. users
  129. WHERE
  130. id = ?
  131. LIMIT 1;`,
  132. this.S.GetInt("UserId", 0),
  133. ).Scan(
  134. &user.A_id,
  135. &user.A_first_name,
  136. &user.A_last_name,
  137. &user.A_email,
  138. &user.A_password,
  139. &user.A_admin,
  140. &user.A_active,
  141. )
  142. if err != nil {
  143. return false
  144. }
  145. if user.A_id != this.S.GetInt("UserId", 0) {
  146. return false
  147. }
  148. this.User = user
  149. return true
  150. }
  151. func (this *Wrapper) Write(data string) {
  152. this.W.Write([]byte(data))
  153. }
  154. func (this *Wrapper) MsgSuccess(msg string) {
  155. this.Write(fmt.Sprintf(
  156. `fave.ShowMsgSuccess('Success!', '%s', false);`,
  157. utils.JavaScriptVarValue(msg)))
  158. }
  159. func (this *Wrapper) MsgError(msg string) {
  160. this.Write(fmt.Sprintf(
  161. `fave.ShowMsgError('Error!', '%s', true);`,
  162. utils.JavaScriptVarValue(msg)))
  163. }
  164. func (this *Wrapper) RenderToString(tcont []byte, data interface{}) string {
  165. tmpl, err := template.New("template").Parse(string(tcont))
  166. if err != nil {
  167. return err.Error()
  168. }
  169. var tpl bytes.Buffer
  170. if err := tmpl.Execute(&tpl, data); err != nil {
  171. return err.Error()
  172. }
  173. return tpl.String()
  174. }
  175. func (this *Wrapper) RenderFrontEnd(tname string, data interface{}, status int) {
  176. tmplFuncs := template.FuncMap{
  177. "plus": func(a, b int) int {
  178. return a + b
  179. },
  180. "minus": func(a, b int) int {
  181. return a - b
  182. },
  183. "multiply": func(a, b int) int {
  184. return a * b
  185. },
  186. "divide": func(a, b int) int {
  187. return a / b
  188. },
  189. "repeat": func(a string, n int) template.HTML {
  190. out := ""
  191. for i := 1; i <= n; i++ {
  192. out += a
  193. }
  194. return template.HTML(out)
  195. },
  196. }
  197. tmpl, err := template.New(tname+".html").Funcs(tmplFuncs).ParseFiles(
  198. this.DTemplate+string(os.PathSeparator)+tname+".html",
  199. this.DTemplate+string(os.PathSeparator)+"header.html",
  200. this.DTemplate+string(os.PathSeparator)+"sidebar-left.html",
  201. this.DTemplate+string(os.PathSeparator)+"sidebar-right.html",
  202. this.DTemplate+string(os.PathSeparator)+"footer.html",
  203. )
  204. if err != nil {
  205. utils.SystemErrorPageTemplate(this.W, err)
  206. return
  207. }
  208. var tpl bytes.Buffer
  209. err = tmpl.Execute(&tpl, consts.TmplData{
  210. System: utils.GetTmplSystemData(),
  211. Data: data,
  212. })
  213. if err != nil {
  214. utils.SystemErrorPageTemplate(this.W, err)
  215. return
  216. }
  217. this.W.WriteHeader(status)
  218. this.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  219. this.W.Header().Set("Content-Type", "text/html; charset=utf-8")
  220. this.W.Write(tpl.Bytes())
  221. }
  222. func (this *Wrapper) RenderBackEnd(tcont []byte, data interface{}) {
  223. tmpl, err := template.New("template").Parse(string(tcont))
  224. if err != nil {
  225. utils.SystemErrorPageEngine(this.W, err)
  226. return
  227. }
  228. this.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  229. this.W.Header().Set("Content-Type", "text/html; charset=utf-8")
  230. var tpl bytes.Buffer
  231. err = tmpl.Execute(this.W, consts.TmplData{
  232. System: utils.GetTmplSystemData(),
  233. Data: data,
  234. })
  235. if err != nil {
  236. utils.SystemErrorPageEngine(this.W, err)
  237. return
  238. }
  239. this.W.Write(tpl.Bytes())
  240. }
  241. func (this *Wrapper) GetCurrentPage(max int) int {
  242. curr := 1
  243. page := this.R.URL.Query().Get("p")
  244. if page != "" {
  245. if i, err := strconv.Atoi(page); err == nil {
  246. if i < 1 {
  247. curr = 1
  248. } else if i > max {
  249. curr = max
  250. } else {
  251. curr = i
  252. }
  253. }
  254. }
  255. return curr
  256. }
  257. func (this *Wrapper) ConfigSave() error {
  258. return this.Config.configWrite(this.DConfig + string(os.PathSeparator) + "config.json")
  259. }