package justguestbook import ( "errors" "fmt" "time" ) const ( // DateFormat is a format of the date and time used in a guestbook. DateFormat = "2006-01-02 15:04:05" // entryWebsiteMaxLength is a maximum length for a Website field of an Entry. entryWebsiteMaxLength = 255 ) // Reply holds a reply for a guestbook's entry. type Reply struct { // ID of a guestbook's entry is used when update of a reply is performed. // // Not present in JSON because a reply comes within its corresponding entry. ID int64 `json:"-"` // Created holds a date and time when a reply was created. Created time.Time `json:"created,omitempty"` // Message holds a reply's message. Message string `json:"message"` } // NewReply creates a new reply and, before that, verifies that a passed message // is not empty. func NewReply(entryID int64, message string) (*Reply, error) { if message == "" { return nil, errors.New("empty message field") } return &Reply{ ID: entryID, Created: time.Now().UTC(), Message: message}, nil } // Entry holds a guestbook entry. type Entry struct { // ID of an entry. ID int64 `json:"entry_id"` // Created holds the date and time when an entry was created. Created time.Time `json:"created"` // Name holds a nick-/name of a guest who posted an entry. Name string `json:"name"` // Website of a guest. Can be empty. Website string `json:"website,omitempty"` // HideWebsite tells wether to hide or show guest's website. HideWebsite bool `json:"hide_website,omitempty"` // Message that a guest wrote. Message string `json:"message"` // Reply holds a reply for this entry. Reply *Reply `json:"reply,omitempty"` } // NewEntry creates a new Entry and, before that, verifies if the name and message // aren't empty and the website field do not exceed the limit. func NewEntry(name, message, website string, hideWebsite bool) (*Entry, error) { if name == "" || message == "" { return nil, errors.New("name and message field are required") } if len(website) > entryWebsiteMaxLength { return nil, errors.New(fmt.Sprint("website field's max length is", entryWebsiteMaxLength, "but", len(website), "was given")) } return &Entry{ Created: time.Now().UTC(), Name: name, Website: website, HideWebsite: hideWebsite, Message: message}, nil } // Guestbook is an interface that should be implemented by a DB. type Guestbook interface { // Entries returns a slice of guestbook entries. Entries(page, pageSize int64) ([]*Entry, error) // Count returns how much entries are in a DB. Count() (int64, error) // NewEntry inserts a given Entry into a DB. NewEntry(entry *Entry) error // EditEntry modifies the fields of an existing entry. EditEntry(entry *Entry) error // DeleteEntry removes an Entry with a given ID. DeleteEntry(entryID int64) error // NewReply inserts a given Reply into a DB. NewReply(reply *Reply) error // EditReply modifies a message field of a given Reply. EditReply(reply *Reply) error // DeleteReply removes a Reply with a given ID of an Entry. DeleteReply(entryID int64) error // Close closes a DB. Close() error }