Moved the create statement into the TopicStore.

Refactored the template generator.
Began improving Cosora again.
This commit is contained in:
Azareal 2017-11-07 22:38:15 +00:00
parent 569b424ac8
commit e2c48c58ba
13 changed files with 282 additions and 327 deletions

View File

@ -45,7 +45,6 @@ type Stmts struct {
getForumTopics *sql.Stmt
getProfileReplies *sql.Stmt
getWatchers *sql.Stmt
createTopic *sql.Stmt
createReport *sql.Stmt
createActionReply *sql.Stmt
createLike *sql.Stmt
@ -388,13 +387,6 @@ func _gen_mssql() (err error) {
return err
}
log.Print("Preparing createTopic statement.")
stmts.createTopic, err = db.Prepare("INSERT INTO [topics] ([parentID],[title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[ipaddress],[words],[createdBy]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,?)")
if err != nil {
log.Print("Bad Query: ","INSERT INTO [topics] ([parentID],[title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[ipaddress],[words],[createdBy]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,?)")
return err
}
log.Print("Preparing createReport statement.")
stmts.createReport, err = db.Prepare("INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[lastReplyBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,1,'report')")
if err != nil {

View File

@ -47,7 +47,6 @@ type Stmts struct {
getForumTopics *sql.Stmt
getProfileReplies *sql.Stmt
getWatchers *sql.Stmt
createTopic *sql.Stmt
createReport *sql.Stmt
createActionReply *sql.Stmt
createLike *sql.Stmt
@ -353,12 +352,6 @@ func _gen_mysql() (err error) {
return err
}
log.Print("Preparing createTopic statement.")
stmts.createTopic, err = db.Prepare("INSERT INTO `topics`(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?)")
if err != nil {
return err
}
log.Print("Preparing createReport statement.")
stmts.createReport, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`lastReplyBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report')")
if err != nil {

12
main.go
View File

@ -94,6 +94,18 @@ func main() {
}
}()*/
// WIP: Mango Test
/*res, err := ioutil.ReadFile("./templates/topic.html")
if err != nil {
log.Fatal(err)
}
tagIndices, err := mangoParse(string(res))
if err != nil {
log.Fatal(err)
}
log.Printf("tagIndices: %+v\n", tagIndices)
log.Fatal("")*/
// TODO: Have a file for each run with the time/date the server started as the file name?
// TODO: Log panics with recover()
f, err := os.OpenFile("./operations.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)

View File

@ -778,7 +778,7 @@ func TestProfileReplyStore(t *testing.T) {
recordMustNotExist(t, err, "PRID #0 shouldn't exist")
_, err = prstore.Get(1)
recordMustNotExist(t, err, "PRID #0 shouldn't exist")
recordMustNotExist(t, err, "PRID #1 shouldn't exist")
var profileID = 1
prid, err := prstore.Create(profileID, "Haha", 1, "::1")

View File

@ -657,7 +657,6 @@ func routeBanSubmit(w http.ResponseWriter, r *http.Request, user User) RouteErro
if uid == user.ID {
return LocalError("Why are you trying to ban yourself? Stop that.", w, r, user)
}
if targetUser.IsBanned {
return LocalError("The user you're trying to unban is already banned.", w, r, user)
}

View File

@ -163,13 +163,7 @@ func (build *accBuilder) SimpleInsertSelectTx(tx *sql.Tx, ins DB_Insert, sel DB_
func (build *accBuilder) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) {
res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)
if err != nil {
build.recordError(err)
return nil
}
stmt, err = tx.Prepare(res)
build.recordError(err)
return stmt
return build.prepareTx(tx, res, err)
}
func (build *accBuilder) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) {

View File

@ -63,7 +63,6 @@ func (build *builder) SimpleCount(table string, where string, limit string) (stm
if err != nil {
return stmt, err
}
//log.Print("res",res)
return build.conn.Prepare(res)
}
@ -72,7 +71,6 @@ func (build *builder) SimpleLeftJoin(table1 string, table2 string, columns strin
if err != nil {
return stmt, err
}
//log.Print("res",res)
return build.conn.Prepare(res)
}
@ -81,7 +79,6 @@ func (build *builder) SimpleInnerJoin(table1 string, table2 string, columns stri
if err != nil {
return stmt, err
}
//log.Print("res",res)
return build.conn.Prepare(res)
}

View File

@ -314,8 +314,6 @@ func writeInnerJoins(adapter qgen.DB_Adapter) (err error) {
}
func writeInserts(adapter qgen.DB_Adapter) error {
adapter.SimpleInsert("createTopic", "topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?")
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'")
adapter.SimpleInsert("createActionReply", "replies", "tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''")

View File

@ -1,69 +1,48 @@
//+build experiment
//+lbuild experiment
// ! EXPERIMENTAL
package main
import (
"errors"
"log"
"regexp"
"text/template/parse"
)
var tagFinder *regexp.Regexp
var limeFuncMap = map[string]interface{}{
"and": "&&",
"not": "!",
"or": "||",
"eq": true,
"ge": true,
"gt": true,
"le": true,
"lt": true,
"ne": true,
"add": true,
"subtract": true,
"multiply": true,
"divide": true,
type Mango struct {
tagFinder *regexp.Regexp
}
func init() {
tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`)
func (m *Mango) Init() {
m.tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`)
}
func mangoParse(tmpl string) error {
tree := parse.New(name, funcMap)
var treeSet = make(map[string]*parse.Tree)
tree, err = tree.Parse(content, "{{", "}}", treeSet, limeFuncMap)
if err != nil {
return err
}
treeLength := len(tree.Root.Nodes)
log.Print("treeLength", treeLength)
return nil
}
func icecreamSoup(tmpl string) error {
if config.MinifyTemplates {
tmpl = minify(tmpl)
}
tagIndices := tagFinder.FindAllStringIndex(tmpl, -1)
if tagIndices != nil && len(tagIndices) > 0 {
func (m *Mango) Parse(tmpl string) (out string, err error) {
tagIndices := m.tagFinder.FindAllStringIndex(tmpl, -1)
if len(tagIndices) > 0 {
if tagIndices[0][0] == 0 {
return errors.New("We don't support tags in the outermost layer yet")
return "", errors.New("We don't support tags in the outermost layer yet")
}
var lastTag = 0
var lastID = 0
for _, tagIndex := range tagIndices {
var nestingLayer = 0
for i := tagIndex[0]; i > 0; i-- {
switch tmpl[i] {
case '>':
i, closeTag, err := tasteTagToLeft(tmpl, i)
ii, closeTag, err := m.tasteTagToLeft(tmpl, i)
if err != nil {
return err
return "", err
}
if closeTag {
nestingLayer++
} else {
_, tagID := m.parseTag(tmpl, ii, i)
if tagID == "" {
out += tmpl[lastTag:ii] + m.injectID(ii, i)
lastID++
} else {
out += tmpl[lastTag:i]
}
}
case '<':
@ -71,9 +50,55 @@ func icecreamSoup(tmpl string) error {
}
}
}
return "", nil
}
func tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) {
func (m *Mango) injectID(start int, end int) string {
return ""
}
func (m *Mango) parseTag(tmpl string, start int, end int) (tagType string, tagID string) {
var i = start
for ; i < end; i++ {
if tmpl[i] == ' ' {
break
}
}
tagType = tmpl[start:i]
i = start
for ; i < (end - 4); i++ {
if tmpl[i] == ' ' && tmpl[i+1] == 'i' && tmpl[i+2] == 'd' && tmpl[i+3] == '=' {
tagID = m.extractAttributeContents(tmpl, i+4, end)
}
}
return tagType, tagID
}
func (m *Mango) extractAttributeContents(tmpl string, i int, end int) (contents string) {
var start = i
var quoteChar byte = 0 // nolint
if m.isHTMLQuoteChar(tmpl[i]) {
i++
quoteChar = tmpl[i]
}
i += 3
for ; i < end; i++ {
if quoteChar != 0 {
if tmpl[i] == quoteChar {
break
}
} else if tmpl[i] == ' ' {
break
}
}
return tmpl[start:i]
}
func (m *Mango) isHTMLQuoteChar(char byte) bool {
return char == '\'' || char == '"'
}
func (m *Mango) tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) {
var foundLeftBrace = false
for ; index > 0; index-- {
// What if the / isn't adjacent to the < but has a space instead? Is that even valid?
@ -85,7 +110,7 @@ func tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err er
}
}
if !foundLeftBrace {
return errors.New("The left portion of the tag is missing")
return index, closeTag, errors.New("The left portion of the tag is missing")
}
return index, closeTag, nil
}

View File

@ -60,6 +60,7 @@ func Route(fname string, path string, args ...string) *RouteImpl {
return &RouteImpl{fname, path, args, []Runnable{}}
}
// TODO: How should we handle headerLite and headerVar?
func routes() {
//addRoute("default_route","","")
addRoute(Route("routeAPI", "/api/"))

View File

@ -144,12 +144,12 @@ func (c *CTemplateSet) compileTemplate(name string, dir string, expects string,
w.Write([]byte(`, " + ", -1)
fout = strings.Replace(fout, "` + `", "", -1)
//spstr := "`([:space:]*)`"
//whitespace_writes := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`)
//fout = whitespace_writes.ReplaceAllString(fout,"")
//whitespaceWrites := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`)
//fout = whitespaceWrites.ReplaceAllString(fout,"")
if dev.DebugMode {
for index, count := range c.stats {
fmt.Println(index + ": " + strconv.Itoa(count))
fmt.Println(index+": ", strconv.Itoa(count))
}
fmt.Println(" ")
}
@ -158,6 +158,7 @@ w.Write([]byte(`, " + ", -1)
fmt.Println("Output!")
fmt.Println(fout)
}
//log.Fatal("remove the log.Fatal line")
return fout, nil
}
@ -168,9 +169,8 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle
treeLength := len(tree.Root.Nodes)
for index, node := range tree.Root.Nodes {
if dev.TemplateDebug {
fmt.Println("Node: ", node.String())
fmt.Println("Node:", node.String())
}
c.previousNode = c.currentNode
c.currentNode = node.Type()
if treeLength != (index + 1) {
@ -181,7 +181,7 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle
return out
}
func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node interface{}) (out string) {
func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node parse.Node) (out string) {
if dev.TemplateDebug {
fmt.Println("in compileSwitch")
}
@ -196,7 +196,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
for _, cmd := range node.Pipe.Cmds {
out += c.compileSubswitch(varholder, holdreflect, templateName, cmd)
}
return out
case *parse.IfNode:
if dev.TemplateDebug {
fmt.Println("If Node:")
@ -218,7 +217,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
if dev.TemplateDebug {
fmt.Println("If Node Expression:", expr)
}
c.previousNode = c.currentNode
c.currentNode = parse.NodeList
c.nextNode = -1
@ -240,8 +238,34 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
for _, subnode := range node.Nodes {
out += c.compileSwitch(varholder, holdreflect, templateName, subnode)
}
return out
case *parse.RangeNode:
return c.compileRangeNode(varholder, holdreflect, templateName, node)
case *parse.TemplateNode:
return c.compileSubtemplate(varholder, holdreflect, node)
case *parse.TextNode:
c.previousNode = c.currentNode
c.currentNode = node.Type()
c.nextNode = 0
tmpText := bytes.TrimSpace(node.Text)
if len(tmpText) == 0 {
return ""
}
fragmentName := templateName + "_" + strconv.Itoa(c.FragmentCursor[templateName])
_, ok := c.Fragments[fragmentName]
if !ok {
c.Fragments[fragmentName] = len(node.Text)
c.FragOut += "var " + fragmentName + " = []byte(`" + string(node.Text) + "`)\n"
}
c.FragmentCursor[templateName] = c.FragmentCursor[templateName] + 1
return "w.Write(" + fragmentName + ")\n"
default:
return c.unknownNode(node)
}
return out
}
func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Value, templateName string, node *parse.RangeNode) (out string) {
if dev.TemplateDebug {
fmt.Println("Range Node!")
fmt.Println(node.Pipe)
@ -254,7 +278,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
}
out, outVal = c.compileReflectswitch(varholder, holdreflect, templateName, cmd)
}
if dev.TemplateDebug {
fmt.Println("Returned:", out)
fmt.Println("Range Kind Switch!")
@ -289,35 +312,9 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
}
if node.ElseList != nil {
out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
} else {
out += "\n"
out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}"
}
return out
case *parse.TemplateNode:
return c.compileSubtemplate(varholder, holdreflect, node)
case *parse.TextNode:
c.previousNode = c.currentNode
c.currentNode = node.Type()
c.nextNode = 0
tmpText := bytes.TrimSpace(node.Text)
if len(tmpText) == 0 {
return ""
}
//return "w.Write([]byte(`" + string(node.Text) + "`))\n"
fragmentName := templateName + "_" + strconv.Itoa(c.FragmentCursor[templateName])
_, ok := c.Fragments[fragmentName]
if !ok {
c.Fragments[fragmentName] = len(node.Text)
c.FragOut += "var " + fragmentName + " = []byte(`" + string(node.Text) + "`)\n"
}
c.FragmentCursor[templateName] = c.FragmentCursor[templateName] + 1
return "w.Write(" + fragmentName + ")\n"
default:
panic("Unknown Node in main switch")
}
return ""
return out + "\n"
}
func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) {
@ -353,7 +350,6 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
for cur.Kind() == reflect.Ptr {
cur = cur.Elem()
}
if dev.TemplateDebug {
fmt.Println("Data Kind:", cur.Kind().String())
fmt.Println("Field Bit:", id)
@ -364,7 +360,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
if dev.DebugMode {
fmt.Println("Debug Data:")
fmt.Println("Holdreflect:", holdreflect)
fmt.Println("Holdreflect.Kind()", holdreflect.Kind())
fmt.Println("Holdreflect.Kind():", holdreflect.Kind())
if !dev.TemplateDebug {
fmt.Println("cur.Kind():", cur.Kind().String())
}
@ -425,15 +421,13 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
}
return c.compileVarsub(c.compileIdentswitch(varholder, holdreflect, templateName, node))
default:
fmt.Println("Unknown Kind:", reflect.ValueOf(firstWord).Elem().Kind())
fmt.Println("Unknown Type:", reflect.ValueOf(firstWord).Elem().Type().Name())
panic("I don't know what node this is")
return c.unknownNode(node)
}
}
func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) {
if dev.TemplateDebug {
fmt.Println("in compile_varswitch")
fmt.Println("in compileVarswitch")
}
firstWord := node.Args[0]
switch n := firstWord.(type) {
@ -466,7 +460,6 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va
fmt.Println("Variable Node Identifier:", n.Ident)
}
out, _ = c.compileIfVarsub(n.String(), varholder, templateName, holdreflect)
return out
case *parse.NilNode:
panic("Nil is not a command x.x")
case *parse.PipeNode:
@ -480,12 +473,16 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va
if dev.TemplateDebug {
fmt.Println("Out:", out)
}
return out
default:
fmt.Println("Unknown Kind:", reflect.ValueOf(firstWord).Elem().Kind())
fmt.Println("Unknown Type:", reflect.ValueOf(firstWord).Elem().Type().Name())
panic("I don't know what node this is! Grr...")
return c.unknownNode(firstWord)
}
return out
}
func (c *CTemplateSet) unknownNode(node parse.Node) (out string) {
fmt.Println("Unknown Kind:", reflect.ValueOf(node).Elem().Kind())
fmt.Println("Unknown Type:", reflect.ValueOf(node).Elem().Type().Name())
panic("I don't know what node this is! Grr...")
return ""
}
@ -497,6 +494,78 @@ func (c *CTemplateSet) compileIdentswitchN(varholder string, holdreflect reflect
return out
}
func (c *CTemplateSet) compareFunc(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, compare string) (out string) {
if dev.TemplateDebug {
fmt.Println("symbol: ", compare)
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
return c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " " + compare + " " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
}
func (c *CTemplateSet) simpleMath(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (out string, val reflect.Value) {
leftParam, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
rightParam, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
// TODO: What does this do?
numSample := 1
val = reflect.ValueOf(numSample)
}
if dev.TemplateDebug {
fmt.Println("symbol: " + symbol)
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
return leftParam + " " + symbol + " " + rightParam, val
}
func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (pos2 int, out string) {
if dev.TemplateDebug {
fmt.Println("Building " + symbol + " function")
}
if pos == 0 {
fmt.Println("pos:", pos)
panic(symbol + " is missing a left operand")
}
if len(node.Args) <= pos {
fmt.Println("post pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
panic(symbol + " is missing a right operand")
}
left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect)
_, funcExists := c.funcMap[node.Args[pos+1].String()]
var right string
if !funcExists {
right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
}
out = left + " " + symbol + " " + right
//log.Print("left: ", left)
//log.Print("right: ", right)
if dev.TemplateDebug {
fmt.Println("Left operand:", node.Args[pos-1])
fmt.Println("Right operand:", node.Args[pos+1])
}
if !funcExists {
pos++
}
if dev.TemplateDebug {
fmt.Println("pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
}
return pos, out
}
func (c *CTemplateSet) compileIdentswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, val reflect.Value) {
if dev.TemplateDebug {
fmt.Println("in compileIdentswitch")
@ -514,200 +583,50 @@ ArgLoop:
case "not":
out += "!"
case "or":
if dev.TemplateDebug {
fmt.Println("Building or function")
}
if pos == 0 {
fmt.Println("pos:", pos)
panic("or is missing a left operand")
}
if len(node.Args) <= pos {
fmt.Println("post pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
panic("or is missing a right operand")
}
left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect)
_, funcExists := c.funcMap[node.Args[pos+1].String()]
var right string
if !funcExists {
right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
}
out += left + " || " + right
if dev.TemplateDebug {
fmt.Println("Left operand:", node.Args[pos-1])
fmt.Println("Right operand:", node.Args[pos+1])
}
if !funcExists {
pos++
}
if dev.TemplateDebug {
fmt.Println("pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
}
var rout string
pos, rout = c.compareJoin(varholder, holdreflect, templateName, pos, node, "||") // TODO: Test this
out += rout
case "and":
if dev.TemplateDebug {
fmt.Println("Building and function")
}
if pos == 0 {
fmt.Println("pos:", pos)
panic("and is missing a left operand")
}
if len(node.Args) <= pos {
fmt.Println("post pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
panic("and is missing a right operand")
}
left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect)
_, funcExists := c.funcMap[node.Args[pos+1].String()]
var right string
if !funcExists {
right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
}
out += left + " && " + right
if dev.TemplateDebug {
fmt.Println("Left operand:", node.Args[pos-1])
fmt.Println("Right operand:", node.Args[pos+1])
}
if !funcExists {
pos++
}
if dev.TemplateDebug {
fmt.Println("pos:", pos)
fmt.Println("len(node.Args):", len(node.Args))
}
case "le":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " <= " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
var rout string
pos, rout = c.compareJoin(varholder, holdreflect, templateName, pos, node, "&&") // TODO: Test this
out += rout
case "le": // TODO: Can we condense these comparison cases down into one?
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "<=")
break ArgLoop
case "lt":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " < " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "<")
break ArgLoop
case "gt":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " > " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, ">")
break ArgLoop
case "ge":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " >= " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, ">=")
break ArgLoop
case "eq":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " == " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "==")
break ArgLoop
case "ne":
out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " != " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if dev.TemplateDebug {
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "!=")
break ArgLoop
case "add":
param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " + " + param2
if dev.TemplateDebug {
fmt.Println("add")
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "+")
out += rout
val = rval
break ArgLoop
case "subtract":
param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " - " + param2
if dev.TemplateDebug {
fmt.Println("subtract")
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "-")
out += rout
val = rval
break ArgLoop
case "divide":
param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " / " + param2
if dev.TemplateDebug {
fmt.Println("divide")
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "/")
out += rout
val = rval
break ArgLoop
case "multiply":
param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect)
param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " * " + param2
if dev.TemplateDebug {
fmt.Println("multiply")
fmt.Println("node.Args[pos + 1]", node.Args[pos+1])
fmt.Println("node.Args[pos + 2]", node.Args[pos+2])
}
rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "*")
out += rout
val = rval
break ArgLoop
default:
if dev.TemplateDebug {
@ -726,6 +645,7 @@ ArgLoop:
//for _, outval := range outbuf {
// out += outval
//}
//log.Print("outbit: ", out)
return out, val
}
@ -747,7 +667,7 @@ func (c *CTemplateSet) compileReflectswitch(varholder string, holdreflect reflec
case *parse.ChainNode:
if dev.TemplateDebug {
fmt.Println("Chain Node:", n.Node)
fmt.Println("node.Args", node.Args)
fmt.Println("node.Args:", node.Args)
}
return "", outVal
case *parse.DotNode:
@ -835,7 +755,6 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat
} else {
out += "." + bit
}
if !cur.IsValid() {
panic(out + "^\n" + "Invalid value. Maybe, it doesn't exist?")
}

View File

@ -699,6 +699,27 @@ select, input, textarea {
margin-right: 10px;
}
#profile_container, #profile_left_pane {
display: flex;
}
#profile_left_lane {
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
}
#profile_left_pane {
flex-direction: column;
}
#profile_left_pane .avatarRow {
padding: 24px;
}
#profile_left_pane .avatar {
border-radius: 80px;
}
#profile_right_lane .colstack_item {
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
}
@media(max-width: 670px) {
.topic_inner_right {
display: none;

View File

@ -58,6 +58,7 @@ type MemoryTopicStore struct {
get *sql.Stmt
exists *sql.Stmt
topicCount *sql.Stmt
create *sql.Stmt
sync.RWMutex
}
@ -70,6 +71,7 @@ func NewMemoryTopicStore(capacity int) (*MemoryTopicStore, error) {
get: acc.SimpleSelect("topics", "title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", ""),
exists: acc.SimpleSelect("topics", "tid", "tid = ?", "", ""),
topicCount: acc.SimpleCount("topics", "", ""),
create: acc.SimpleInsert("topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?"),
}, acc.FirstError()
}
@ -146,7 +148,7 @@ func (mts *MemoryTopicStore) Create(fid int, topicName string, content string, u
wcount := wordCount(content)
// TODO: Move this statement into the topic store
res, err := stmts.createTopic.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
res, err := mts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
if err != nil {
return 0, err
}
@ -253,6 +255,7 @@ type SQLTopicStore struct {
get *sql.Stmt
exists *sql.Stmt
topicCount *sql.Stmt
create *sql.Stmt
}
func NewSQLTopicStore() (*SQLTopicStore, error) {
@ -261,6 +264,7 @@ func NewSQLTopicStore() (*SQLTopicStore, error) {
get: acc.SimpleSelect("topics", "title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", ""),
exists: acc.SimpleSelect("topics", "tid", "tid = ?", "", ""),
topicCount: acc.SimpleCount("topics", "", ""),
create: acc.SimpleInsert("topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?"),
}, acc.FirstError()
}
@ -297,7 +301,7 @@ func (sts *SQLTopicStore) Create(fid int, topicName string, content string, uid
wcount := wordCount(content)
// TODO: Move this statement into the topic store
res, err := stmts.createTopic.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
res, err := sts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
if err != nil {
return 0, err
}