improve sql queries and tables
This commit is contained in:
parent
162e7e2f50
commit
3d1fe25dcb
@ -2,13 +2,11 @@ package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ActionTokenTarget int
|
||||
type ActionTokenTarget string
|
||||
|
||||
const (
|
||||
_ ActionTokenTarget = iota
|
||||
ActionTokenTargetForgotPassword
|
||||
ActionTokenTargetLogin2FA
|
||||
ActionTokenVerifyEmail
|
||||
ActionTokenTargetRestorePassword ActionTokenTarget = "restore"
|
||||
ActionTokenTargetVerifyEmail ActionTokenTarget = "verify"
|
||||
)
|
||||
|
||||
type ActionTokenDTO struct {
|
||||
|
||||
@ -11,9 +11,9 @@ import (
|
||||
)
|
||||
|
||||
type ShortlinkDTO struct {
|
||||
Id string
|
||||
Url string
|
||||
Expiration time.Time
|
||||
Id string
|
||||
Url string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
type ShortlinkRepo interface {
|
||||
@ -35,8 +35,8 @@ func (u *shortlinkRepo) AddShortlink(ctx context.Context, dto ShortlinkDTO) erro
|
||||
_, span := u.tracer.Start(ctx, "postgres::AddShortlink")
|
||||
defer span.End()
|
||||
|
||||
query := `insert into shortlinks (id, url, expiration) values ($1, $2, $3);`
|
||||
_, err := u.db.ExecContext(ctx, query, dto.Id, dto.Url, dto.Expiration)
|
||||
query := `insert into shortlinks (url, expires_at) values ($1, $2);`
|
||||
_, err := u.db.ExecContext(ctx, query, dto.Url, dto.ExpiresAt)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -44,14 +44,14 @@ func (u *shortlinkRepo) GetShortlink(ctx context.Context, id string) (*Shortlink
|
||||
_, span := u.tracer.Start(ctx, "postgres::GetShortlink")
|
||||
defer span.End()
|
||||
|
||||
query := `select url, expiration from shortlinks where id = $1;`
|
||||
query := `select url, expires_at from shortlinks where id = $1;`
|
||||
row := u.db.QueryRowContext(ctx, query, id)
|
||||
if err := row.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dto := &ShortlinkDTO{Id: id}
|
||||
err := row.Scan(&dto.Url, &dto.Expiration)
|
||||
err := row.Scan(&dto.Url, &dto.ExpiresAt)
|
||||
if err == nil {
|
||||
return dto, nil
|
||||
}
|
||||
|
||||
@ -10,16 +10,10 @@ import (
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// type userDAO struct {
|
||||
// Id string `json:"id"`
|
||||
// Login string `json:"login"`
|
||||
// Secret string `json:"secret"`
|
||||
// Name string `json:"name"`
|
||||
// }
|
||||
|
||||
type UserRepo interface {
|
||||
CreateUser(ctx context.Context, dto models.UserDTO) (*models.UserDTO, error)
|
||||
UpdateUser(ctx context.Context, userId string, dto models.UserUpdateDTO) error
|
||||
DeactivateUser(ctx context.Context, userId string) error
|
||||
SetUserEmailVerified(ctx context.Context, userId string) error
|
||||
GetUserById(ctx context.Context, id string) (*models.UserDTO, error)
|
||||
GetUserByEmail(ctx context.Context, login string) (*models.UserDTO, error)
|
||||
@ -67,6 +61,19 @@ func (u *userRepo) UpdateUser(ctx context.Context, userId string, dto models.Use
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *userRepo) DeactivateUser(ctx context.Context, userId string) error {
|
||||
_, span := u.tracer.Start(ctx, "postgres::DeactivateUser")
|
||||
defer span.End()
|
||||
|
||||
query := `update users set active=false where id = $1;`
|
||||
_, err := u.db.ExecContext(ctx, query, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *userRepo) SetUserEmailVerified(ctx context.Context, userId string) error {
|
||||
_, span := u.tracer.Start(ctx, "postgres::SetUserEmailVerified")
|
||||
defer span.End()
|
||||
|
||||
@ -48,9 +48,9 @@ func (s *shortlinkService) CreateShortlink(ctx context.Context, url string) (str
|
||||
expiration := time.Now().Add(7 * 24 * time.Hour)
|
||||
|
||||
dto := repos.ShortlinkDTO{
|
||||
Id: id,
|
||||
Url: url,
|
||||
Expiration: expiration,
|
||||
Id: id,
|
||||
Url: url,
|
||||
ExpiresAt: expiration,
|
||||
}
|
||||
if err := s.repo.AddShortlink(ctx, dto); err != nil {
|
||||
return "", err
|
||||
@ -73,7 +73,7 @@ func (s *shortlinkService) GetShortlink(ctx context.Context, id string) (string,
|
||||
if link == nil {
|
||||
return "", ErrShortlinkNotexist
|
||||
}
|
||||
if time.Now().After(link.Expiration) {
|
||||
if time.Now().After(link.ExpiresAt) {
|
||||
return "", ErrShortlinkExpired
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ func (u *userService) AuthenticateUser(ctx context.Context, email, password stri
|
||||
}
|
||||
|
||||
func (u *userService) VerifyEmail(ctx context.Context, actionToken string) error {
|
||||
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenVerifyEmail)
|
||||
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenTargetVerifyEmail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -162,7 +162,7 @@ func (u *userService) SendEmailForgotPassword(ctx context.Context, email string)
|
||||
models.ActionTokenDTO{
|
||||
UserId: user.Id,
|
||||
Value: uuid.New().String(),
|
||||
Target: models.ActionTokenTargetForgotPassword,
|
||||
Target: models.ActionTokenTargetRestorePassword,
|
||||
Expiration: time.Now().Add(15 * time.Minute),
|
||||
},
|
||||
)
|
||||
@ -179,7 +179,7 @@ func (u *userService) sendEmailVerifyUser(ctx context.Context, userId, email str
|
||||
models.ActionTokenDTO{
|
||||
UserId: userId,
|
||||
Value: uuid.New().String(),
|
||||
Target: models.ActionTokenVerifyEmail,
|
||||
Target: models.ActionTokenTargetVerifyEmail,
|
||||
Expiration: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
)
|
||||
@ -207,7 +207,7 @@ func (u *userService) SendEmailVerifyUser(ctx context.Context, email string) err
|
||||
}
|
||||
|
||||
func (u *userService) ChangePasswordWithToken(ctx context.Context, actionToken, newPassword string) error {
|
||||
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenTargetForgotPassword)
|
||||
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenTargetRestorePassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
18
sql/00_common.sql
Normal file
18
sql/00_common.sql
Normal file
@ -0,0 +1,18 @@
|
||||
create or replace function trg_proc_row_updated()
|
||||
returns trigger as $$
|
||||
begin
|
||||
if new is distinct from old then
|
||||
new.updated_at = now();
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function trg_proc_row_created()
|
||||
returns trigger as $$
|
||||
begin
|
||||
new.created_at = now();
|
||||
new.updated_at = now();
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
@ -4,38 +4,20 @@ create table if not exists users (
|
||||
secret varchar(256) not null,
|
||||
full_name varchar(256) not null,
|
||||
email_verified boolean not null default false,
|
||||
active boolean,
|
||||
created_at timestamp,
|
||||
updated_at timestamp
|
||||
);
|
||||
|
||||
create index if not exists idx_users_email on users(email);
|
||||
|
||||
create or replace function set_created_at()
|
||||
returns trigger as $$
|
||||
begin
|
||||
new.created_at = now();
|
||||
new.updated_at = now();
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace trigger trg_user_created
|
||||
before insert on users
|
||||
for each row
|
||||
execute function set_created_at();
|
||||
|
||||
create or replace function set_updated_at()
|
||||
returns trigger as $$
|
||||
begin
|
||||
if new is distinct from old then
|
||||
new.updated_at = now();
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
execute function trg_proc_row_created();
|
||||
|
||||
create or replace trigger trg_user_updated
|
||||
before update on users
|
||||
for each row
|
||||
when(new is distinct from old)
|
||||
execute function set_updated_at();
|
||||
execute function trg_proc_row_updated();
|
||||
@ -1,5 +1,17 @@
|
||||
create table if not exists shortlinks (
|
||||
id text primary key,
|
||||
url text,
|
||||
expiration date
|
||||
);
|
||||
id int generated always as identity,
|
||||
url text not null,
|
||||
expires_at timestamp not null,
|
||||
created_at timestamp,
|
||||
updated_at timestamp
|
||||
|
||||
create or replace trigger trg_shortlink_created
|
||||
before insert on shortlinks
|
||||
for each row
|
||||
when new is distinct from old
|
||||
execute function trg_proc_row_created();
|
||||
|
||||
create or replace trigger trg_shortlink_updated
|
||||
before update on shortlinks
|
||||
for each row when new is distinct from old
|
||||
execute function trg_proc_row_updated();
|
||||
@ -1,9 +1,26 @@
|
||||
create table if not exists action_tokens (
|
||||
id int generated always as identity,
|
||||
user_id int,
|
||||
value text,
|
||||
target int,
|
||||
expiration timestamp,
|
||||
id int primary key generated always as identity,
|
||||
user_id int references users(id),
|
||||
value text not null,
|
||||
target text not null,
|
||||
expires_at timestamp not null,
|
||||
created_at timestamp,
|
||||
updated_at timestamp
|
||||
|
||||
primary key(id)
|
||||
);
|
||||
constraint pk_action_tokens_id primary key(id),
|
||||
constraint check chk_action_tokens_target target in ('verify', 'restore')
|
||||
);
|
||||
|
||||
create index if not exists idx_action_tokens_value on actions_tokens(value);
|
||||
|
||||
create or replace trigger trg_action_token_created
|
||||
before insert on action_tokens
|
||||
for each row
|
||||
when new is distinct from old
|
||||
execute function trg_proc_row_created();
|
||||
|
||||
create or replace trigger trg_action_token_updated
|
||||
before update on action_tokens
|
||||
for each row
|
||||
when new is distinct from old
|
||||
execute function trg_proc_row_updated();
|
||||
Loading…
x
Reference in New Issue
Block a user