Moved the create statement into the TopicStore.
Refactored the template generator. Began improving Cosora again.
This commit is contained in:
parent
569b424ac8
commit
e2c48c58ba
|
@ -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 {
|
||||
|
|
|
@ -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
12
main.go
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),'',''")
|
||||
|
|
113
rev_templates.go
113
rev_templates.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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/"))
|
||||
|
|
423
templates.go
423
templates.go
|
@ -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,60 +238,8 @@ 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:
|
||||
if dev.TemplateDebug {
|
||||
fmt.Println("Range Node!")
|
||||
fmt.Println(node.Pipe)
|
||||
}
|
||||
|
||||
var outVal reflect.Value
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
if dev.TemplateDebug {
|
||||
fmt.Println("Range Bit:", cmd)
|
||||
}
|
||||
out, outVal = c.compileReflectswitch(varholder, holdreflect, templateName, cmd)
|
||||
}
|
||||
|
||||
if dev.TemplateDebug {
|
||||
fmt.Println("Returned:", out)
|
||||
fmt.Println("Range Kind Switch!")
|
||||
}
|
||||
|
||||
switch outVal.Kind() {
|
||||
case reflect.Map:
|
||||
var item reflect.Value
|
||||
for _, key := range outVal.MapKeys() {
|
||||
item = outVal.MapIndex(key)
|
||||
}
|
||||
if dev.DebugMode {
|
||||
fmt.Println("Range item:", item)
|
||||
}
|
||||
if !item.IsValid() {
|
||||
panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?")
|
||||
}
|
||||
|
||||
if node.ElseList != nil {
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n} else {\n" + c.compileSwitch("item", item, templateName, node.ElseList) + "}\n"
|
||||
} else {
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}"
|
||||
}
|
||||
case reflect.Slice:
|
||||
if outVal.Len() == 0 {
|
||||
panic("The sample data needs at-least one or more elements for the slices. We're looking into removing this requirement at some point!")
|
||||
}
|
||||
item := outVal.Index(0)
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}"
|
||||
case reflect.Invalid:
|
||||
return ""
|
||||
}
|
||||
|
||||
if node.ElseList != nil {
|
||||
out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
|
||||
} else {
|
||||
out += "\n"
|
||||
}
|
||||
return out
|
||||
return c.compileRangeNode(varholder, holdreflect, templateName, node)
|
||||
case *parse.TemplateNode:
|
||||
return c.compileSubtemplate(varholder, holdreflect, node)
|
||||
case *parse.TextNode:
|
||||
|
@ -305,7 +251,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
|
|||
return ""
|
||||
}
|
||||
|
||||
//return "w.Write([]byte(`" + string(node.Text) + "`))\n"
|
||||
fragmentName := templateName + "_" + strconv.Itoa(c.FragmentCursor[templateName])
|
||||
_, ok := c.Fragments[fragmentName]
|
||||
if !ok {
|
||||
|
@ -315,9 +260,61 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
|
|||
c.FragmentCursor[templateName] = c.FragmentCursor[templateName] + 1
|
||||
return "w.Write(" + fragmentName + ")\n"
|
||||
default:
|
||||
panic("Unknown Node in main switch")
|
||||
return c.unknownNode(node)
|
||||
}
|
||||
return ""
|
||||
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)
|
||||
}
|
||||
|
||||
var outVal reflect.Value
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
if dev.TemplateDebug {
|
||||
fmt.Println("Range Bit:", cmd)
|
||||
}
|
||||
out, outVal = c.compileReflectswitch(varholder, holdreflect, templateName, cmd)
|
||||
}
|
||||
if dev.TemplateDebug {
|
||||
fmt.Println("Returned:", out)
|
||||
fmt.Println("Range Kind Switch!")
|
||||
}
|
||||
|
||||
switch outVal.Kind() {
|
||||
case reflect.Map:
|
||||
var item reflect.Value
|
||||
for _, key := range outVal.MapKeys() {
|
||||
item = outVal.MapIndex(key)
|
||||
}
|
||||
if dev.DebugMode {
|
||||
fmt.Println("Range item:", item)
|
||||
}
|
||||
if !item.IsValid() {
|
||||
panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?")
|
||||
}
|
||||
|
||||
if node.ElseList != nil {
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n} else {\n" + c.compileSwitch("item", item, templateName, node.ElseList) + "}\n"
|
||||
} else {
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}"
|
||||
}
|
||||
case reflect.Slice:
|
||||
if outVal.Len() == 0 {
|
||||
panic("The sample data needs at-least one or more elements for the slices. We're looking into removing this requirement at some point!")
|
||||
}
|
||||
item := outVal.Index(0)
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}"
|
||||
case reflect.Invalid:
|
||||
return ""
|
||||
}
|
||||
|
||||
if node.ElseList != nil {
|
||||
out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}"
|
||||
}
|
||||
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?")
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue