use string builder in buildFlexiWhere
add string builder growth hints track favicon perf
This commit is contained in:
parent
68c6b2f50a
commit
c31ca03a0d
|
@ -56,6 +56,8 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AlertsGrowHint = len(`{"msgs":[],"count":,"tc":}`) + 1 + 7
|
||||||
|
|
||||||
// TODO: See if we can json.Marshal instead?
|
// TODO: See if we can json.Marshal instead?
|
||||||
func escapeTextInJson(in string) string {
|
func escapeTextInJson(in string) string {
|
||||||
in = strings.Replace(in, "\"", "\\\"", -1)
|
in = strings.Replace(in, "\"", "\\\"", -1)
|
||||||
|
@ -165,6 +167,8 @@ func buildAlertString(msg string, sub []string, path, avatar string, asid int) s
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AlertsGrowHint2 = len(`{"msg":"","sub":[],"path":"","avatar":"","id":}`) + 3 + 3 + 1 + 1 + 1
|
||||||
|
|
||||||
// TODO: Use a string builder?
|
// TODO: Use a string builder?
|
||||||
func buildAlertSb(sb *strings.Builder, msg string, sub []string, path, avatar string, asid int) {
|
func buildAlertSb(sb *strings.Builder, msg string, sub []string, path, avatar string, asid int) {
|
||||||
sb.WriteString(`{"msg":"`)
|
sb.WriteString(`{"msg":"`)
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
||||||
h := w.Header()
|
h := w.Header()
|
||||||
h.Set("Content-Encoding", "gzip")
|
h.Set("Content-Encoding", "gzip")
|
||||||
h.Set("Content-Type", "text/html; charset=utf-8")
|
h.Set("Content-Type", "text/html;charset=utf-8")
|
||||||
gzw := c.GzipResponseWriter{Writer: gzip.NewWriter(w), ResponseWriter: w}
|
gzw := c.GzipResponseWriter{Writer: gzip.NewWriter(w), ResponseWriter: w}
|
||||||
defer func() {
|
defer func() {
|
||||||
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
|
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
|
||||||
|
@ -2665,7 +2665,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
req.URL.Path = "/s/favicon.ico"
|
req.URL.Path = "/s/favicon.ico"
|
||||||
routes.StaticFile(w,req)
|
routes.StaticFile(w,req)
|
||||||
co.RouteViewCounter.Bump(171)
|
co.RouteViewCounter.Bump3(171, cn)
|
||||||
return nil
|
return nil
|
||||||
case "opensearch.xml":
|
case "opensearch.xml":
|
||||||
co.RouteViewCounter.Bump(170)
|
co.RouteViewCounter.Bump(170)
|
||||||
|
|
|
@ -276,7 +276,7 @@ func (a *MysqlAdapter) AddKey(name, table, cols string, key DBTableKey) (string,
|
||||||
}
|
}
|
||||||
|
|
||||||
var colstr string
|
var colstr string
|
||||||
for _, col := range strings.Split(cols,",") {
|
for _, col := range strings.Split(cols, ",") {
|
||||||
colstr += "`" + col + "`,"
|
colstr += "`" + col + "`,"
|
||||||
}
|
}
|
||||||
if len(colstr) > 1 {
|
if len(colstr) > 1 {
|
||||||
|
@ -651,41 +651,66 @@ func (a *MysqlAdapter) buildWhere(where string, sb *strings.Builder) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries
|
// The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries
|
||||||
|
const FlexiHint1 = len(` < UTC_TIMESTAMP() - interval ? `)
|
||||||
|
|
||||||
func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) {
|
func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) {
|
||||||
if len(where) == 0 && dateCutoff == nil {
|
if len(where) == 0 && dateCutoff == nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
q = " WHERE"
|
|
||||||
|
var sb strings.Builder
|
||||||
|
sb.WriteString(" WHERE")
|
||||||
if dateCutoff != nil {
|
if dateCutoff != nil {
|
||||||
|
sb.Grow(6 + FlexiHint1)
|
||||||
|
sb.WriteRune(' ')
|
||||||
|
sb.WriteString(dateCutoff.Column)
|
||||||
switch dateCutoff.Type {
|
switch dateCutoff.Type {
|
||||||
case 0:
|
case 0:
|
||||||
q += " " + dateCutoff.Column + " BETWEEN (UTC_TIMESTAMP() - interval " + strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + ") AND UTC_TIMESTAMP() AND"
|
sb.WriteString(" BETWEEN (UTC_TIMESTAMP() - interval ")
|
||||||
|
q += strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + ") AND UTC_TIMESTAMP()"
|
||||||
case 11:
|
case 11:
|
||||||
q += " " + dateCutoff.Column + " < UTC_TIMESTAMP() - interval ? " + dateCutoff.Unit + " AND"
|
sb.WriteString(" < UTC_TIMESTAMP() - interval ? ")
|
||||||
|
sb.WriteString(dateCutoff.Unit)
|
||||||
default:
|
default:
|
||||||
q += " " + dateCutoff.Column + " < UTC_TIMESTAMP() - interval " + strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + " AND"
|
sb.WriteString(" < UTC_TIMESTAMP() - interval ")
|
||||||
|
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
|
||||||
|
sb.WriteRune(' ')
|
||||||
|
sb.WriteString(dateCutoff.Unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dateCutoff != nil && len(where) != 0 {
|
||||||
|
sb.WriteString(" AND")
|
||||||
|
}
|
||||||
|
|
||||||
if len(where) != 0 {
|
if len(where) != 0 {
|
||||||
for _, loc := range processWhere(where) {
|
wh := processWhere(where)
|
||||||
|
sb.Grow((len(wh) * 8) - 5)
|
||||||
|
for i, loc := range wh {
|
||||||
|
if i != 0 {
|
||||||
|
sb.WriteString(" AND ")
|
||||||
|
}
|
||||||
for _, token := range loc.Expr {
|
for _, token := range loc.Expr {
|
||||||
switch token.Type {
|
switch token.Type {
|
||||||
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot, TokenLike:
|
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot, TokenLike:
|
||||||
q += " " + token.Contents
|
sb.WriteString(" ")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
case TokenColumn:
|
case TokenColumn:
|
||||||
q += " `" + token.Contents + "`"
|
sb.WriteString(" `")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteString("`")
|
||||||
case TokenString:
|
case TokenString:
|
||||||
q += " '" + token.Contents + "'"
|
sb.WriteString(" '")
|
||||||
|
sb.WriteString(token.Contents)
|
||||||
|
sb.WriteString("'")
|
||||||
default:
|
default:
|
||||||
return q, errors.New("This token doesn't exist o_o")
|
return sb.String(), errors.New("This token doesn't exist o_o")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q += " AND"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return q[0 : len(q)-4], nil
|
return sb.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {
|
func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {
|
||||||
|
|
|
@ -825,7 +825,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
||||||
h := w.Header()
|
h := w.Header()
|
||||||
h.Set("Content-Encoding", "gzip")
|
h.Set("Content-Encoding", "gzip")
|
||||||
h.Set("Content-Type", "text/html; charset=utf-8")
|
h.Set("Content-Type", "text/html;charset=utf-8")
|
||||||
gzw := c.GzipResponseWriter{Writer: gzip.NewWriter(w), ResponseWriter: w}
|
gzw := c.GzipResponseWriter{Writer: gzip.NewWriter(w), ResponseWriter: w}
|
||||||
defer func() {
|
defer func() {
|
||||||
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
|
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
|
||||||
|
@ -892,7 +892,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
req.URL.Path = "/s/favicon.ico"
|
req.URL.Path = "/s/favicon.ico"
|
||||||
routes.StaticFile(w,req)
|
routes.StaticFile(w,req)
|
||||||
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.Favicon"}})
|
co.RouteViewCounter.Bump3({{index .AllRouteMap "routes.Favicon"}}, cn)
|
||||||
return nil
|
return nil
|
||||||
case "opensearch.xml":
|
case "opensearch.xml":
|
||||||
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.OpenSearchXml"}})
|
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.OpenSearchXml"}})
|
||||||
|
|
|
@ -151,6 +151,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
sb.Grow(c.AlertsGrowHint + (len(alerts) * c.AlertsGrowHint2))
|
||||||
sb.WriteString(`{"msgs":[`)
|
sb.WriteString(`{"msgs":[`)
|
||||||
for i, alert := range alerts {
|
for i, alert := range alerts {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<meta property="og:type" content="website"/>
|
<meta property="og:type" content="website"/>
|
||||||
<meta property="og:site_name" content="{{.Header.Site.Name}}">
|
<meta property="og:site_name" content="{{.Header.Site.Name}}">
|
||||||
<meta property="og:title" content="{{.Title}} | {{.Header.Site.Name}}">
|
<meta property="og:title" content="{{.Title}} | {{.Header.Site.Name}}">
|
||||||
<meta name="twitter:title" content="{{.Title}} | {{.Header.Site.Name}}" />
|
<meta name="twitter:title" content="{{.Title}} | {{.Header.Site.Name}}"/>
|
||||||
{{if .OGDesc}}<meta property="og:description" content="{{.OGDesc}}"/>
|
{{if .OGDesc}}<meta property="og:description" content="{{.OGDesc}}"/>
|
||||||
<meta property="twitter:description" content="{{.OGDesc}}"/>{{end}}
|
<meta property="twitter:description" content="{{.OGDesc}}"/>{{end}}
|
||||||
{{if .GoogSiteVerify}}<meta name="google-site-verification" content="{{.GoogSiteVerify}}"/>{{end}}
|
{{if .GoogSiteVerify}}<meta name="google-site-verification" content="{{.GoogSiteVerify}}"/>{{end}}
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
{{/** TODO: Make this a separate template and load it via the theme docks, here for now so we can rapidly prototype the Nox theme **/}}
|
{{/** TODO: Make this a separate template and load it via the theme docks, here for now so we can rapidly prototype the Nox theme **/}}
|
||||||
{{if eq .Header.Theme.Name "nox"}}
|
{{if eq .Header.Theme.Name "nox"}}
|
||||||
<div class="user_box">
|
<div class="user_box">
|
||||||
<img src="{{.CurrentUser.MicroAvatar}}" />
|
<img src="{{.CurrentUser.MicroAvatar}}"/>
|
||||||
<div class="option_box">
|
<div class="option_box">
|
||||||
<a href="{{.CurrentUser.Link}}" class="username">{{.CurrentUser.Name}}</a>
|
<a href="{{.CurrentUser.Link}}" class="username">{{.CurrentUser.Name}}</a>
|
||||||
<span class="alerts">{{lang "alerts.no_alerts_short"}}</span>
|
<span class="alerts">{{lang "alerts.no_alerts_short"}}</span>
|
||||||
|
|
Loading…
Reference in New Issue