init
This commit is contained in:
38
internal/adapter/storages/postgres/db.go
Normal file
38
internal/adapter/storages/postgres/db.go
Normal file
@ -0,0 +1,38 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/aykhans/oh-my-chat/internal/adapter/config"
|
||||
postgresDriver "gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewDB(config *config.PostgresConfig) (*gorm.DB, error) {
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%s sslmode=%s TimeZone=%s",
|
||||
config.Host,
|
||||
config.User,
|
||||
config.Password,
|
||||
config.DBName,
|
||||
config.Port,
|
||||
"disable",
|
||||
"UTC",
|
||||
)
|
||||
|
||||
var db *gorm.DB
|
||||
var err error
|
||||
for range 3 {
|
||||
db, err = gorm.Open(postgresDriver.Open(dsn), &gorm.Config{})
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS "public"."users";
|
@ -0,0 +1,11 @@
|
||||
CREATE TABLE "public"."users" (
|
||||
"id" uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
"username" character varying(50) NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"password" character varying(72) NOT NULL,
|
||||
"created_at" timestamptz NOT NULL DEFAULT now(),
|
||||
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY ("id"),
|
||||
CONSTRAINT "uni_users_email" UNIQUE ("email"),
|
||||
CONSTRAINT "uni_users_username" UNIQUE ("username")
|
||||
);
|
24
internal/adapter/storages/postgres/models/user.go
Normal file
24
internal/adapter/storages/postgres/models/user.go
Normal file
@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
UserTableName = "users"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID uuid.UUID `gorm:"primarykey;unique;type:uuid;default:gen_random_uuid()"`
|
||||
Username string `gorm:"unique;not null;size:50"`
|
||||
Email string `gorm:"unique;not null"`
|
||||
Password string `gorm:"not null;size:72"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
func (u User) TableName() string {
|
||||
return UserTableName
|
||||
}
|
109
internal/adapter/storages/postgres/repository/user.go
Normal file
109
internal/adapter/storages/postgres/repository/user.go
Normal file
@ -0,0 +1,109 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/aykhans/oh-my-chat/internal/adapter/storages/postgres/models"
|
||||
"github.com/aykhans/oh-my-chat/internal/core/domain"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewUserRepository(db *gorm.DB) *UserRepository {
|
||||
return &UserRepository{db}
|
||||
}
|
||||
|
||||
func (userRepository *UserRepository) CreateUser(
|
||||
ctx context.Context,
|
||||
user *domain.User,
|
||||
) (*domain.User, error) {
|
||||
userModel := &models.User{
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Password: user.Password,
|
||||
}
|
||||
tx := userRepository.db.Create(userModel)
|
||||
if tx.Error != nil {
|
||||
return nil, tx.Error
|
||||
}
|
||||
|
||||
user.ID = userModel.ID
|
||||
user.Username = userModel.Username
|
||||
user.Email = userModel.Email
|
||||
user.Password = userModel.Password
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (userRepository *UserRepository) IsUsernameExists(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
) (bool, error) {
|
||||
var count int64
|
||||
tx := userRepository.db.
|
||||
Table(models.UserTableName).
|
||||
Where("username = ?", username).
|
||||
Count(&count)
|
||||
if tx.Error != nil {
|
||||
return false, tx.Error
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (userRepository *UserRepository) IsEmailExists(
|
||||
ctx context.Context,
|
||||
email string,
|
||||
) (bool, error) {
|
||||
var count int64
|
||||
tx := userRepository.db.
|
||||
Table(models.UserTableName).
|
||||
Where("email = ?", email).
|
||||
Count(&count)
|
||||
if tx.Error != nil {
|
||||
return false, tx.Error
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (userRepository *UserRepository) GetUserByEmail(
|
||||
ctx context.Context,
|
||||
email string,
|
||||
) (*domain.User, error) {
|
||||
user := &domain.User{}
|
||||
tx := userRepository.db.
|
||||
Table(models.UserTableName).
|
||||
Where("email = ?", email).
|
||||
First(user)
|
||||
if tx.Error != nil {
|
||||
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, domain.ErrDataNotFound
|
||||
}
|
||||
return nil, tx.Error
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (userRepository *UserRepository) GetUserByUsername(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
) (*domain.User, error) {
|
||||
user := &domain.User{}
|
||||
tx := userRepository.db.
|
||||
Table(models.UserTableName).
|
||||
Where("username = ?", username).
|
||||
First(user)
|
||||
if tx.Error != nil {
|
||||
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, domain.ErrDataNotFound
|
||||
}
|
||||
return nil, tx.Error
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
33
internal/adapter/storages/scylla/db.go
Normal file
33
internal/adapter/storages/scylla/db.go
Normal file
@ -0,0 +1,33 @@
|
||||
package scylla
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/aykhans/oh-my-chat/internal/adapter/config"
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
func NewDB(config *config.ScyllaConfig) (*gocql.Session, error) {
|
||||
cluster := gocql.NewCluster(config.Hosts...)
|
||||
cluster.Keyspace = config.Keyspace
|
||||
cluster.Consistency = gocql.LocalQuorum
|
||||
cluster.Authenticator = gocql.PasswordAuthenticator{
|
||||
Username: config.User,
|
||||
Password: config.Password,
|
||||
}
|
||||
cluster.PoolConfig.HostSelectionPolicy = gocql.TokenAwareHostPolicy(
|
||||
gocql.DCAwareRoundRobinPolicy(config.DataCenter),
|
||||
)
|
||||
|
||||
var session *gocql.Session
|
||||
var err error
|
||||
for range 20 {
|
||||
session, err = cluster.CreateSession()
|
||||
if err == nil {
|
||||
return session, nil
|
||||
}
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS messages;
|
@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
chat_id UUID, -- Partition key
|
||||
user_id UUID,
|
||||
content text, -- Clustering column
|
||||
type text, -- Clustering column
|
||||
created_at timestamp, -- Clustering column
|
||||
PRIMARY KEY (chat_id, created_at, content, type)
|
||||
) WITH CLUSTERING ORDER BY (created_at DESC);
|
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS user_chats;
|
@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS user_chats (
|
||||
user_id UUID, -- Partition key
|
||||
chat_id UUID, -- Clustering column
|
||||
blocked boolean,
|
||||
created_at timestamp,
|
||||
PRIMARY KEY (user_id, created_at, chat_id, blocked)
|
||||
);
|
23
internal/adapter/storages/scylla/repository/message.go
Normal file
23
internal/adapter/storages/scylla/repository/message.go
Normal file
@ -0,0 +1,23 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/aykhans/oh-my-chat/internal/core/domain"
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
type MessageRepository struct {
|
||||
db *gocql.Session
|
||||
}
|
||||
|
||||
func NewMessageRepository(db *gocql.Session) *MessageRepository {
|
||||
return &MessageRepository{db}
|
||||
}
|
||||
|
||||
func (messageRepository *MessageRepository) CreateMessage(
|
||||
ctx context.Context,
|
||||
message *domain.Message,
|
||||
) (*domain.Message, error) {
|
||||
return nil, nil
|
||||
}
|
Reference in New Issue
Block a user