func (this *server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { defer func() { if e := recover(); e != nil { gox.LError("ServeHTTP", e) } }() gox.LCritical(fmt.Sprintf("%s %s %q", req.Method, req.Header.Get(gox.ContentTypeName), req.RequestURI)) path := req.RequestURI i := strings.Index(path, "?") if i > 0 { path = req.RequestURI[:i] } path = filterSlashPath(path) handlers, params := this.Match(req.Method, path) if len(handlers) == 0 { gox.LError("Not found", path, "[", req.RequestURI, "]") http.Error(rw, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } context := NewContext(rw, req, handlers, params, this.Header) context.Next() if context.Written() == false { context.Status(http.StatusNotFound) } }
func (d *database) insertComment(c *Comment) error { err := d.QueryRow("select floor from comments where item_id=? and item_type=? order by floor desc limit 1", c.ItemID, c.ItemType).Scan(&c.Floor) if err != sql.ErrNoRows && err != nil { gox.LError("insertComment", err) return err } c.Floor++ _, err = d.Exec("insert into comments ("+commentFields+") values(?,?,?,?,?,?,?,?,?,?,?,?,?)", c.ID, c.UserID, c.ItemID, c.ItemType, c.ToCommentID, gox.JSONMarshalStr(c.Content), c.CreatedAt, c.Status, c.Floor, gox.JSONMarshalStr(c.AtUserIDs), c.Location, c.Lat, c.Lng) if err != nil { gox.LError("insertComment", err) } return err }
func (d *database) GetCommentsCount(itemID gox.ID, itemType int) (count int, err error) { err = d.QueryRow("select count(*) from comments where item_id=? and item_type=?", itemID, itemType).Scan(&count) if err != nil { gox.LError("GetCommentsCount", err) } return }
func (d *database) GetNewCount(userID gox.ID) (num int, err error) { err = d.QueryRow("select COALESCE(sum(new_count),0) from notices where user_id=?", userID).Scan(&num) if err != nil { gox.LError(err) } return }
func (d *database) GetImages(albumID gox.ID, albumType int, page int, size int) (images []string, err error) { var rows *sql.Rows defer func() { if rows != nil { rows.Close() } if err != nil { gox.LError(err) } }() images = make([]string, 0, size) rows, err = d.Query("select content from albums where album_id=? and album_type=? and type=? order by created_at desc limit ?,?", albumID, albumType, gox.XTypeImage, size*page, size) if err != nil { return } for rows.Next() { var img string err = rows.Scan(&img) if err != nil { return } images = append(images, img) } return }
func (d *database) GetTopicActionsCount(topicID gox.ID, action int) (count int, err error) { err = d.QueryRow("select count(*) from topic_actions where topic_id=? and action=?", topicID, action).Scan(&count) if err != nil { gox.LError("GetTopicActionsCount", err) } return }
func (d *database) GetAll() (TopicList, error) { rows, err := d.Query("select " + topicFields + " from topics") if err != nil { gox.LError("GetAll", err) return nil, err } return parseTopics(rows) }
func (d *database) GetCommentedTopics(userID gox.ID, page int, size int) (TopicList, error) { rows, err := d.Query("select "+topicFields+` from topics where status=? and id in (select distinct topic_id from comments where user_id=?) order by id desc limit ?,?`, gox.StatusOK, userID, page*size, size) if err != nil { gox.LError("GetCommentedTopics", err) return nil, err } return parseTopics(rows) }
func (d *database) GetTopicsByAction(userID gox.ID, action int, page int, size int) (TopicList, error) { rows, err := d.Query("select "+topicFields+` from topics where status=? and id in (select topic_id from topic_actions where user_id=? and action=?) order by id desc limit ?,?`, gox.StatusOK, userID, action, page*size, size) if err != nil { gox.LError("GetFavoriteTopics", err) return nil, err } return parseTopics(rows) }
func (d *database) GetChannel(id gox.ID) (*Channel, error) { c := &Channel{} err := d.QueryRow("select "+channelFields+" from channels where status=0 and id=?", id).Scan(&c.ID, &c.Name, &c.Image, &c.Wiki) if err != nil { gox.LError("GetChannel", id, err) if err == sql.ErrNoRows { err = nil } return nil, err } return c, nil }
func (d *database) GetDeviceByToken(token string) (*gox.Device, error) { device := &gox.Device{} err := d.QueryRow("select"+deviceFields+" from devices where token=?", token).Scan(&device.Token, &device.UserID, &device.Badge, &device.CreatedAt) if err != nil { gox.LError(err, token) if err == sql.ErrNoRows { err = nil } } return device, err }
func (d *database) GetComment(commentID gox.ID) (*Comment, error) { c := &Comment{} var content, atUserIDs []byte err := d.QueryRow("select "+commentFields+" from comments where id=?", commentID).Scan(&c.ID, &c.UserID, &c.ItemID, &c.ItemType, &c.ToCommentID, &content, &c.CreatedAt, &c.Status, &c.Floor, &atUserIDs, &c.Location, &c.Lat, &c.Lng) if err != nil { gox.LError(err) return nil, err } gox.JSONUnmarshal(content, &c.Content) gox.JSONUnmarshal(atUserIDs, &c.AtUserIDs) return c, nil }
func (d *database) GetLastComment(itemID gox.ID, itemType int) (*Comment, error) { c := &Comment{} var content, atUserIDs []byte err := d.QueryRow("select "+commentFields+" from comments where item_id=? and item_type=? order by id desc limit 1", itemID, itemType).Scan(&c.ID, &c.UserID, &c.ItemID, &c.ItemType, &c.ToCommentID, &content, &c.CreatedAt, &c.Status, &c.Floor, &atUserIDs, &c.Location, &c.Lat, &c.Lng) if err != nil { gox.LError("GetLastComment", err) return nil, err } gox.JSONUnmarshal(content, &c.Content) gox.JSONUnmarshal(atUserIDs, &c.AtUserIDs) return c, nil }
func (d *database) GetTopic(topicID gox.ID) (*Topic, error) { t := &Topic{} var content, atUserIDs, types, tags []byte err := d.QueryRow("select "+topicFields+" from topics where id=?", topicID).Scan(&t.ID, &t.UserID, &t.ChannelID, &content, &t.CreatedAt, &t.CommentedAt, &t.Status, &types, &tags, &atUserIDs, &t.Location, &t.Lat, &t.Lng) if err != nil { gox.LError(err) return nil, err } gox.JSONUnmarshal(content, &t.Content) gox.JSONUnmarshal(atUserIDs, &t.AtUserIDs) gox.JSONUnmarshal(types, &t.Types) gox.JSONUnmarshal(tags, &t.Tags) return t, nil }
func (d *database) GetChannelTopics(channelID gox.ID, page int, size int, status int, order TopicListOrder) (TopicList, error) { var orderStr string if order == OrderByCommentedAt { orderStr = " order by commented_at desc" } else { orderStr = " order by id desc" } rows, err := d.Query("select "+topicFields+" from topics where status=? and channel_id=? "+orderStr+" limit ?,?", status, channelID, page*size, size) if err != nil { gox.LError("GetChannelTopics", err) return nil, err } return parseTopics(rows) }
func (d *database) GetUserTopics(userID gox.ID, sinceID gox.ID, size int, status int) (TopicList, error) { var rows *sql.Rows var err error if sinceID <= 0 { rows, err = d.Query("select "+topicFields+" from topics where status=? and user_id=? order by id desc limit ?", status, userID, size) } else { rows, err = d.Query("select "+topicFields+" from topics where status=? and user_id=? and id<? order by id desc limit ?", status, userID, sinceID, size) } if err != nil { gox.LError("GetCommentedTopics", err) return nil, err } return parseTopics(rows) }
func (d *database) GetUserComments(userID gox.ID, sinceID gox.ID, size int) (CommentList, error) { var rows *sql.Rows var err error if sinceID <= 0 { rows, err = d.Query("select "+commentFields+" from comments where user_id=? order by id desc limit ?", userID, size) } else { rows, err = d.Query("select "+commentFields+" from comments where user_id=? and id<? order by id desc limit ?", userID, sinceID, size) } if err != nil { gox.LError("GetUserComments", userID, sinceID, size, err) return nil, err } return d.parseComments(rows) }
func (d *database) GetLastCommentUserIDs(itemID gox.ID, itemType int, size int) (gox.IDList, error) { rows, err := d.Query("select distinct user_id from comments where item_id=? and item_type=? order by id desc limit ?", itemID, itemType, size) if err != nil { gox.LError("GetLastCommentUserIDs", err) return nil, err } defer rows.Close() ids := gox.IDList{} var uid gox.ID for rows.Next() { err = rows.Scan(&uid) if err != nil { return nil, err } ids = append(ids, uid) } return ids, nil }
func (d *database) parseComments(rows *sql.Rows) (CommentList, error) { defer rows.Close() comments := make(CommentList, 0, 30) for rows.Next() { c := &Comment{} var content, atUserIDs []byte err := rows.Scan(&c.ID, &c.UserID, &c.ItemID, &c.ItemType, &c.ToCommentID, &content, &c.CreatedAt, &c.Status, &c.Floor, &atUserIDs, &c.Location, &c.Lat, &c.Lng) if err != nil { gox.LError("parseComments", err) return comments[0:0], err } gox.JSONUnmarshal(content, &c.Content) gox.JSONUnmarshal(atUserIDs, &c.AtUserIDs) comments = append(comments, c) } return comments, nil }
func (d *database) GetComments(itemID gox.ID, itemType int, sinceID gox.ID, size int, desc bool) (CommentList, error) { var rows *sql.Rows var err error var descStr string if desc { descStr = " desc " } if sinceID <= 0 { rows, err = d.Query("select "+commentFields+" from comments where item_id=? and item_type=? order by id "+descStr+" limit ?", itemID, itemType, size) } else { rows, err = d.Query("select "+commentFields+" from comments where item_id=? and item_type=? and id<? order by id "+descStr+" limit ?", itemID, itemType, sinceID, size) } if err != nil { gox.LError("GetTargetComments", itemID, itemType, sinceID, size, desc, err) return nil, err } return d.parseComments(rows) }
func parseTopics(rows *sql.Rows) (TopicList, error) { defer rows.Close() topics := make(TopicList, 0, 50) for rows.Next() { t := &Topic{} var content, atUserIDs, types, tags []byte err := rows.Scan(&t.ID, &t.UserID, &t.ChannelID, &content, &t.CreatedAt, &t.CommentedAt, &t.Status, &types, &tags, &atUserIDs, &t.Location, &t.Lat, &t.Lng) if err != nil { gox.LError(err) return nil, err } gox.JSONUnmarshal(content, &t.Content) gox.JSONUnmarshal(atUserIDs, &t.AtUserIDs) gox.JSONUnmarshal(types, &t.Types) gox.JSONUnmarshal(tags, &t.Tags) topics = append(topics, t) } return topics, nil }
func (d *database) GetAreaTopics(area gox.Area, page int, size int, order TopicListOrder) (TopicList, error) { query := "select " + topicFields + " from topics where status=? and lat>=? and lat<=? " if area.MinLng > area.MaxLng { query += " and (lng>=? or lng<=?) " } else { query += " and lng>=? and lng<=? " } if order == OrderByCommentedAt { query += " order by commented_at desc" } else { query += " order by id desc" } query += " limit ?,?" rows, err := d.Query(query, gox.StatusOK, area.MinLat, area.MaxLat, area.MinLng, area.MaxLng, page*size, size) if err != nil { gox.LError("GetLocalTopics", err) return nil, err } return parseTopics(rows) }
func (d *database) GetNotices(userID gox.ID, sinceID gox.ID, size int) (notices []*Notice, err error) { var rows *sql.Rows defer func() { if rows != nil { rows.Close() } if err != nil { notices = nil gox.LError(err) } }() notices = make([]*Notice, 0, size) if sinceID <= 0 { rows, err = d.Query("select "+noticeFields+" from notices where user_id=? order by id desc limit ?", userID, size) } else { rows, err = d.Query("select "+noticeFields+" from notices where user_id=? and id<? order by id desc limit ?", userID, sinceID, size) } if err != nil { return } var uid gox.ID for rows.Next() { n := &Notice{} var content []byte err = rows.Scan(&n.ID, &uid, &n.Type, &n.ContentID, &content, &n.Title, &n.TotalCount, &n.NewCount, &n.UpdatedAt) if err != nil { return } gox.JSONUnmarshal(content, &n.Content) notices = append(notices, n) } return }