wrapper.go 6.4 KB

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