migrate from github
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package invitation_repo
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationGetByIDOperation struct {
|
||||
repo *InvitationRepository
|
||||
id int64
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) GetByID(id int64) *InvitationGetByIDOperation {
|
||||
return &InvitationGetByIDOperation{
|
||||
repo: r,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationGetByIDOperation) WithTx(tx *gorm.DB) *InvitationGetByIDOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationGetByIDOperation) Exec() (*model.Invitation, error) {
|
||||
var invitation model.Invitation
|
||||
var err error
|
||||
|
||||
if op.tx != nil {
|
||||
err = op.tx.First(&invitation, op.id).Error
|
||||
} else {
|
||||
err = op.repo.db.First(&invitation, op.id).Error
|
||||
}
|
||||
|
||||
return &invitation, err
|
||||
}
|
||||
|
||||
type InvitationCreateOperation struct {
|
||||
repo *InvitationRepository
|
||||
invitation *model.Invitation
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) Create(invitation *model.Invitation) *InvitationCreateOperation {
|
||||
return &InvitationCreateOperation{
|
||||
repo: r,
|
||||
invitation: invitation,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationCreateOperation) WithTx(tx *gorm.DB) *InvitationCreateOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationCreateOperation) Exec() error {
|
||||
if op.tx != nil {
|
||||
return op.tx.Create(op.invitation).Error
|
||||
}
|
||||
return op.repo.db.Create(op.invitation).Error
|
||||
}
|
||||
|
||||
type InvitationUpdateOperation struct {
|
||||
repo *InvitationRepository
|
||||
invitation *model.Invitation
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) Update(invitation *model.Invitation) *InvitationUpdateOperation {
|
||||
return &InvitationUpdateOperation{
|
||||
repo: r,
|
||||
invitation: invitation,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationUpdateOperation) WithTx(tx *gorm.DB) *InvitationUpdateOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationUpdateOperation) Exec() error {
|
||||
if op.tx != nil {
|
||||
return op.tx.Save(op.invitation).Error
|
||||
}
|
||||
return op.repo.db.Save(op.invitation).Error
|
||||
}
|
||||
|
||||
type InvitationDeleteOperation struct {
|
||||
repo *InvitationRepository
|
||||
id int64
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) Delete(id int64) *InvitationDeleteOperation {
|
||||
return &InvitationDeleteOperation{
|
||||
repo: r,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationDeleteOperation) WithTx(tx *gorm.DB) *InvitationDeleteOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationDeleteOperation) Exec() error {
|
||||
if op.tx == nil {
|
||||
op.tx = op.repo.db
|
||||
}
|
||||
return op.tx.Delete(&model.Invitation{}, op.id).Error
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package invitation_repo
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationGetByCodeOperation struct {
|
||||
repo *InvitationRepository
|
||||
code string
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) GetByCode(code string) *InvitationGetByCodeOperation {
|
||||
return &InvitationGetByCodeOperation{
|
||||
repo: r,
|
||||
code: code,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationGetByCodeOperation) WithTx(tx *gorm.DB) *InvitationGetByCodeOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationGetByCodeOperation) Exec() (*model.Invitation, error) {
|
||||
var invitation model.Invitation
|
||||
var err error
|
||||
|
||||
if op.tx != nil {
|
||||
err = op.tx.Where("code = ?", op.code).First(&invitation).Error
|
||||
} else {
|
||||
err = op.repo.db.Where("code = ?", op.code).First(&invitation).Error
|
||||
}
|
||||
|
||||
return &invitation, err
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package invitation_repo
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type InvitationRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewInvitationRepository(db *gorm.DB) *InvitationRepository {
|
||||
return &InvitationRepository{db: db}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
package invitation_repo
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationListOperation struct {
|
||||
repo *InvitationRepository
|
||||
m *model.Invitation
|
||||
creatorID *int64
|
||||
keyword *string
|
||||
maxUsedCnt *int64
|
||||
expiresAtStart *string
|
||||
expiresAtEnd *string
|
||||
createdAtStart *string
|
||||
createdAtEnd *string
|
||||
disabled *bool
|
||||
sortField string
|
||||
sortDesc bool
|
||||
page int
|
||||
pageSize int
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) List(m *model.Invitation) *InvitationListOperation {
|
||||
return &InvitationListOperation{
|
||||
repo: r,
|
||||
m: m,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithTx(tx *gorm.DB) *InvitationListOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithCreatorID(creatorID *int64) *InvitationListOperation {
|
||||
op.creatorID = creatorID
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithKeyword(keyword *string) *InvitationListOperation {
|
||||
op.keyword = keyword
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithMaxUsedCnt(maxUsedCnt *int64) *InvitationListOperation {
|
||||
op.maxUsedCnt = maxUsedCnt
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithExpiresAtRange(start, end *string) *InvitationListOperation {
|
||||
op.expiresAtStart = start
|
||||
op.expiresAtEnd = end
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithCreatedAtRange(start, end *string) *InvitationListOperation {
|
||||
op.createdAtStart = start
|
||||
op.createdAtEnd = end
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithDisabled(disabled *bool) *InvitationListOperation {
|
||||
op.disabled = disabled
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithSort(field string, desc bool) *InvitationListOperation {
|
||||
op.sortField = field
|
||||
op.sortDesc = desc
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) WithPagination(page, pageSize int) *InvitationListOperation {
|
||||
op.page = page
|
||||
op.pageSize = pageSize
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) Exec() ([]model.Invitation, error) {
|
||||
db := op.repo.db
|
||||
if op.tx != nil {
|
||||
db = op.tx
|
||||
}
|
||||
|
||||
dbQuery := db.Model(&model.Invitation{})
|
||||
|
||||
if op.m != nil {
|
||||
dbQuery = dbQuery.Where(op.m)
|
||||
}
|
||||
|
||||
if op.creatorID != nil {
|
||||
dbQuery = dbQuery.Where("created_by = ?", *op.creatorID)
|
||||
}
|
||||
|
||||
if op.keyword != nil && *op.keyword != "" {
|
||||
dbQuery = dbQuery.Where("code ILIKE ?", "%"+*op.keyword+"%")
|
||||
}
|
||||
|
||||
if op.maxUsedCnt != nil {
|
||||
dbQuery = dbQuery.Where("max_used_cnt = ?", *op.maxUsedCnt)
|
||||
}
|
||||
|
||||
if op.expiresAtStart != nil && *op.expiresAtStart != "" {
|
||||
dbQuery = dbQuery.Where("expires_at >= ?", *op.expiresAtStart)
|
||||
}
|
||||
if op.expiresAtEnd != nil && *op.expiresAtEnd != "" {
|
||||
dbQuery = dbQuery.Where("expires_at <= ?", *op.expiresAtEnd)
|
||||
}
|
||||
if op.createdAtStart != nil && *op.createdAtStart != "" {
|
||||
dbQuery = dbQuery.Where("created_at >= ?", *op.createdAtStart)
|
||||
}
|
||||
if op.createdAtEnd != nil && *op.createdAtEnd != "" {
|
||||
dbQuery = dbQuery.Where("created_at <= ?", *op.createdAtEnd)
|
||||
}
|
||||
if op.disabled != nil {
|
||||
dbQuery = dbQuery.Where("disabled = ?", *op.disabled)
|
||||
}
|
||||
|
||||
sortField := op.sortField
|
||||
if sortField == "" {
|
||||
sortField = "created_at"
|
||||
}
|
||||
orderDirection := "ASC"
|
||||
if op.sortDesc {
|
||||
orderDirection = "DESC"
|
||||
}
|
||||
dbQuery = dbQuery.Order(sortField + " " + orderDirection)
|
||||
|
||||
page := op.page
|
||||
pageSize := op.pageSize
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
if pageSize > 100 {
|
||||
pageSize = 100
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
dbQuery = dbQuery.Offset(offset).Limit(pageSize)
|
||||
|
||||
var invitations []model.Invitation
|
||||
err := dbQuery.Find(&invitations).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return invitations, nil
|
||||
}
|
||||
|
||||
func (op *InvitationListOperation) ExecWithTotal() ([]model.Invitation, int64, error) {
|
||||
db := op.repo.db
|
||||
if op.tx != nil {
|
||||
db = op.tx
|
||||
}
|
||||
|
||||
dbQuery := db.Model(&model.Invitation{})
|
||||
|
||||
if op.m != nil {
|
||||
dbQuery = dbQuery.Where(op.m)
|
||||
}
|
||||
|
||||
if op.creatorID != nil {
|
||||
dbQuery = dbQuery.Where("created_by = ?", *op.creatorID)
|
||||
}
|
||||
|
||||
if op.keyword != nil && *op.keyword != "" {
|
||||
dbQuery = dbQuery.Where("code ILIKE ?", "%"+*op.keyword+"%")
|
||||
}
|
||||
|
||||
if op.maxUsedCnt != nil {
|
||||
dbQuery = dbQuery.Where("max_used_cnt = ?", *op.maxUsedCnt)
|
||||
}
|
||||
|
||||
if op.expiresAtStart != nil && *op.expiresAtStart != "" {
|
||||
dbQuery = dbQuery.Where("expires_at >= ?", *op.expiresAtStart)
|
||||
}
|
||||
if op.expiresAtEnd != nil && *op.expiresAtEnd != "" {
|
||||
dbQuery = dbQuery.Where("expires_at <= ?", *op.expiresAtEnd)
|
||||
}
|
||||
if op.createdAtStart != nil && *op.createdAtStart != "" {
|
||||
dbQuery = dbQuery.Where("created_at >= ?", *op.createdAtStart)
|
||||
}
|
||||
if op.createdAtEnd != nil && *op.createdAtEnd != "" {
|
||||
dbQuery = dbQuery.Where("created_at <= ?", *op.createdAtEnd)
|
||||
}
|
||||
if op.disabled != nil {
|
||||
dbQuery = dbQuery.Where("disabled = ?", *op.disabled)
|
||||
}
|
||||
|
||||
var total int64
|
||||
err := dbQuery.Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
sortField := op.sortField
|
||||
if sortField == "" {
|
||||
sortField = "created_at"
|
||||
}
|
||||
orderDirection := "ASC"
|
||||
if op.sortDesc {
|
||||
orderDirection = "DESC"
|
||||
}
|
||||
dbQuery = dbQuery.Order(sortField + " " + orderDirection)
|
||||
|
||||
page := op.page
|
||||
pageSize := op.pageSize
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
if pageSize > 100 {
|
||||
pageSize = 100
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
dbQuery = dbQuery.Offset(offset).Limit(pageSize)
|
||||
|
||||
var invitations []model.Invitation
|
||||
err = dbQuery.Find(&invitations).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return invitations, total, nil
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package invitation_repo
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationRecordCreateOperation struct {
|
||||
repo *InvitationRepository
|
||||
record *model.InvitationRecord
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) CreateRecord(record *model.InvitationRecord) *InvitationRecordCreateOperation {
|
||||
return &InvitationRecordCreateOperation{
|
||||
repo: r,
|
||||
record: record,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationRecordCreateOperation) WithTx(tx *gorm.DB) *InvitationRecordCreateOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordCreateOperation) Exec() error {
|
||||
if op.tx != nil {
|
||||
return op.tx.Create(op.record).Error
|
||||
}
|
||||
return op.repo.db.Create(op.record).Error
|
||||
}
|
||||
|
||||
type InvitationRecordListOperation struct {
|
||||
repo *InvitationRepository
|
||||
code *string
|
||||
status *string
|
||||
usedAtStart *string
|
||||
usedAtEnd *string
|
||||
creatorID *int64
|
||||
keyword *string
|
||||
page int
|
||||
pageSize int
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) ListRecords() *InvitationRecordListOperation {
|
||||
return &InvitationRecordListOperation{
|
||||
repo: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithTx(tx *gorm.DB) *InvitationRecordListOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithCode(code *string) *InvitationRecordListOperation {
|
||||
op.code = code
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithStatus(status *string) *InvitationRecordListOperation {
|
||||
op.status = status
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithUsedAtRange(start, end *string) *InvitationRecordListOperation {
|
||||
op.usedAtStart = start
|
||||
op.usedAtEnd = end
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithCreatorID(creatorID *int64) *InvitationRecordListOperation {
|
||||
op.creatorID = creatorID
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithKeyword(keyword *string) *InvitationRecordListOperation {
|
||||
op.keyword = keyword
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) WithPagination(page, pageSize int) *InvitationRecordListOperation {
|
||||
op.page = page
|
||||
op.pageSize = pageSize
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationRecordListOperation) ExecWithTotal() ([]model.InvitationRecord, int64, error) {
|
||||
db := op.repo.db
|
||||
if op.tx != nil {
|
||||
db = op.tx
|
||||
}
|
||||
|
||||
query := db.Model(&model.InvitationRecord{})
|
||||
if op.creatorID != nil {
|
||||
query = query.Joins("JOIN invitations ON invitations.code = invitation_records.code").
|
||||
Where("invitations.created_by = ?", *op.creatorID)
|
||||
}
|
||||
if op.code != nil && *op.code != "" {
|
||||
query = query.Where("code = ?", *op.code)
|
||||
}
|
||||
if op.keyword != nil && *op.keyword != "" {
|
||||
keyword := "%" + *op.keyword + "%"
|
||||
query = query.Where("invitation_records.code ILIKE ? OR invitation_records.used_by ILIKE ?", keyword, keyword)
|
||||
}
|
||||
if op.status != nil && *op.status != "" {
|
||||
query = query.Where("status = ?", *op.status)
|
||||
}
|
||||
if op.usedAtStart != nil && *op.usedAtStart != "" {
|
||||
query = query.Where("used_at >= ?", *op.usedAtStart)
|
||||
}
|
||||
if op.usedAtEnd != nil && *op.usedAtEnd != "" {
|
||||
query = query.Where("used_at <= ?", *op.usedAtEnd)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
page := op.page
|
||||
pageSize := op.pageSize
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
if pageSize > 200 {
|
||||
pageSize = 200
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
query = query.Order("used_at DESC").Offset(offset).Limit(pageSize)
|
||||
|
||||
var records []model.InvitationRecord
|
||||
if err := query.Find(&records).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return records, total, nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package invitation_repo
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationValidateAndUseOperation struct {
|
||||
repo *InvitationRepository
|
||||
code string
|
||||
tx *gorm.DB
|
||||
}
|
||||
|
||||
func (r *InvitationRepository) ValidateAndUse(code string) *InvitationValidateAndUseOperation {
|
||||
return &InvitationValidateAndUseOperation{
|
||||
repo: r,
|
||||
code: code,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *InvitationValidateAndUseOperation) WithTx(tx *gorm.DB) *InvitationValidateAndUseOperation {
|
||||
op.tx = tx
|
||||
return op
|
||||
}
|
||||
|
||||
func (op *InvitationValidateAndUseOperation) Exec() (bool, error) {
|
||||
db := op.repo.db
|
||||
if op.tx != nil {
|
||||
db = op.tx
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
result := db.Model(&model.Invitation{}).
|
||||
Where("code = ? AND deleted_at IS NULL AND disabled = ?", op.code, false).
|
||||
Where("(expires_at IS NULL OR expires_at > ?)", now).
|
||||
Where("(max_used_cnt IS NULL OR used_cnt < max_used_cnt)").
|
||||
UpdateColumn("used_cnt", gorm.Expr("used_cnt + ?", 1))
|
||||
|
||||
if result.Error != nil {
|
||||
return false, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
Reference in New Issue
Block a user