Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Alexander Andreev | 8c8c1f2617 | |
Alexander Andreev | 16e5ececf5 | |
Alexander Andreev | 141e1215a3 | |
Alexander Andreev | 5d56b56882 |
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2022,2023 Alexander "Arav" Andreev <me@arav.top>
|
||||
Copyright (c) 2022,2023 Alexander "Arav" Andreev <me@arav.su>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -95,10 +95,13 @@ func initSQLiteStatements(db *sql.DB) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SQLiteDatabase implements a Guestbook that works with a SQLite DB
|
||||
// under the hood.
|
||||
type SQLiteDatabase struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewSQLiteDB returns an instance of a SQLite Guestbook implementation.
|
||||
func NewSQLiteDB(filePath string) (Guestbook, error) {
|
||||
db, err := sql.Open("sqlite3", sqliteDSN(filePath))
|
||||
if err != nil {
|
||||
|
|
68
guestbook.go
68
guestbook.go
|
@ -2,17 +2,34 @@ package justguestbook
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const DateFormat = "2006-01-02 15:04:05"
|
||||
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 int64 `json:"-"`
|
||||
// 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 string `json:"message"`
|
||||
|
||||
// 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")
|
||||
|
@ -24,21 +41,42 @@ func NewReply(entryID int64, message string) (*Reply, error) {
|
|||
Message: message}, nil
|
||||
}
|
||||
|
||||
// Entry holds a guestbook entry.
|
||||
type Entry struct {
|
||||
ID int64 `json:"entry_id"`
|
||||
Created time.Time `json:"created"`
|
||||
Name string `json:"name"`
|
||||
Website string `json:"website,omitempty"`
|
||||
HideWebsite bool `json:"hide_website,omitempty"`
|
||||
Message string `json:"message"`
|
||||
Reply *Reply `json:"reply,omitempty"`
|
||||
// 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,
|
||||
|
@ -47,14 +85,24 @@ func NewEntry(name, message, website string, hideWebsite bool) (*Entry, error) {
|
|||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue