Created
April 23, 2020 15:06
-
-
Save taksenov/91806584b070c3e3fc7c01d310fc4418 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package posts | |
import ( | |
"context" | |
"fmt" | |
"math" | |
"net/http" | |
"reflect" | |
"time" | |
"redditcloneapp/pkg/user" | |
"go.mongodb.org/mongo-driver/bson" | |
"go.mongodb.org/mongo-driver/bson/primitive" | |
"go.mongodb.org/mongo-driver/mongo" | |
"go.mongodb.org/mongo-driver/mongo/options" | |
) | |
// Author автор поста или комментария | |
type Author struct { | |
ID string `json:"id" bson:"id"` | |
Username string `json:"username" bson:"username"` | |
} | |
// PostVote голоса отданные посту | |
type PostVote struct { | |
User string `json:"user" bson:"user"` | |
Vote int32 `json:"vote" bson:"vote"` | |
} | |
// PostComment комментарий | |
type PostComment struct { | |
ID string `json:"id" bson:"id"` | |
Created string `json:"created" bson:"created"` | |
Author *Author `json:"author" bson:"author"` | |
Body string `json:"body" bson:"body"` | |
} | |
// Post пост | |
type Post struct { | |
ID primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` | |
Score int32 `json:"score" bson:"score"` | |
Views int32 `json:"views" bson:"views"` | |
Type string `json:"type" bson:"type"` | |
Title string `json:"title" bson:"title"` | |
Text string `json:"text,omitempty" bson:"text,omitempty"` | |
URL string `json:"url" bson:"url"` | |
Category string `json:"category" bson:"category"` | |
Created string `json:"created" bson:"created"` | |
UpvotePercentage int32 `json:"upvotePercentage" bson:"upvotePercentage"` | |
Author *Author `json:"author" bson:"author"` | |
Votes []*PostVote `json:"votes" bson:"votes"` | |
Comments []*PostComment `json:"comments" bson:"comments"` | |
} | |
// User структура для данных пользователя | |
type User struct { | |
ID primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` | |
UserName string `json:"username" bson:"username"` | |
Password string `json:"password" bson:"password"` | |
Admin bool `json:"admin" bson:"admin"` | |
} | |
// ResPost результаты, когда для поста не нужно возвращать сам пост | |
type ResPost struct { | |
Message string | |
} | |
// PostFormPayload форма создания поста | |
type PostFormPayload struct { | |
Category string | |
Type string | |
Title string | |
Text string | |
URL string | |
} | |
// PostsRepo репозиторий для работы с пользователями системы | |
type PostsRepo struct { | |
DB *mongo.Database | |
Posts *mongo.Collection | |
} | |
// NewPostsRepo инициализация репозитория Posts | |
func NewPostsRepo(db *mongo.Database) *PostsRepo { | |
postsCollection := db.Collection("posts") | |
return &PostsRepo{ | |
Posts: postsCollection, | |
} | |
} | |
// ========================== | |
type DatabaseHelper interface { | |
Collection(name string) CollectionHelper | |
} | |
type CollectionHelper interface { | |
CustomFindOne(context.Context, interface{}) SingleResultHelper | |
} | |
type SingleResultHelper interface { | |
CustomDecode(v interface{}) error | |
} | |
type mongoCollection struct { | |
coll *mongo.Collection | |
} | |
type mongoSingleResult struct { | |
sr *mongo.SingleResult | |
} | |
func (mc *mongoCollection) CustomFindOne(ctx context.Context, filter interface{}) SingleResultHelper { | |
singleResult := mc.coll.FindOne(ctx, filter) | |
return &mongoSingleResult{sr: singleResult} | |
} | |
func (sr *mongoSingleResult) CustomDecode(v interface{}) error { | |
return sr.sr.Decode(v) | |
} | |
// ========================== | |
// AddPost добавить в пост в БД | |
func (repo *PostsRepo) AddPost(formData PostFormPayload, userData *user.LocalUser) (*Post, error) { | |
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) | |
// IDEA: Т.к. фронтенд не умеет работать с ISODate, | |
// поэтому дата формируется в виде строки "2009-11-10T23:00:00Z" | |
timeNow, err := time.Now().MarshalText() | |
if err != nil { | |
return nil, err | |
} | |
timeNowForDB := string(timeNow) | |
// Структура нового поста | |
create := bson.D{ | |
primitive.E{Key: "score", Value: 0}, | |
primitive.E{Key: "views", Value: 0}, | |
primitive.E{Key: "type", Value: formData.Type}, | |
primitive.E{Key: "title", Value: formData.Title}, | |
primitive.E{Key: "text", Value: formData.Text}, | |
primitive.E{Key: "url", Value: formData.URL}, | |
primitive.E{Key: "category", Value: formData.Category}, | |
primitive.E{Key: "created", Value: timeNowForDB}, | |
primitive.E{Key: "upvotePercentage", Value: 0}, | |
primitive.E{ | |
Key: "author", | |
Value: bson.D{ | |
primitive.E{Key: "username", Value: userData.UserName}, | |
primitive.E{Key: "id", Value: userData.ID.Hex()}, | |
}, | |
}, | |
primitive.E{Key: "votes", Value: []*PostVote{}}, | |
primitive.E{Key: "comments", Value: []*PostComment{}}, | |
} | |
// Добавить пост в БД | |
postDB, err := repo.Posts.InsertOne(ctx, create) | |
if err != nil { | |
return nil, err | |
} | |
// Получить созданный пост из БД и вернуть "наверх" | |
createdDocument := &Post{} | |
customColl := mongoCollection{ | |
coll: repo.Posts, | |
} | |
err = customColl.CustomFindOne(ctx, bson.M{"_id": postDB.InsertedID}).CustomDecode(&createdDocument) | |
// err = repo.Posts.FindOne(ctx, bson.M{"_id": postDB.InsertedID}).Decode(&createdDocument) | |
if err != nil { | |
fmt.Printf("DB ERR= %#v \n", err) | |
return nil, err | |
} | |
fmt.Printf("DB DOCUMENT= %#v \n", createdDocument) | |
return createdDocument, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment