add issue item stuff.
This commit is contained in:
@@ -12,6 +12,7 @@ type Database interface {
|
||||
Activities() repositories.ActivityRepository
|
||||
Issues() repositories.IssueRepository
|
||||
IssueTasks() repositories.IssueTaskRepository
|
||||
IssueItems() repositories.IssueItemRepository
|
||||
Items() repositories.ItemRepository
|
||||
Projects() repositories.ProjectRepository
|
||||
Session() repositories.SessionRepository
|
||||
|
||||
@@ -17,6 +17,7 @@ type DB struct {
|
||||
activities *activityRepository
|
||||
issues *issueRepository
|
||||
issueTasks *issueTaskRepository
|
||||
issueItems *issueItemRepository
|
||||
items *itemRepository
|
||||
projects *projectRepository
|
||||
sessions *sessionRepository
|
||||
@@ -36,6 +37,10 @@ func (db *DB) IssueTasks() repositories.IssueTaskRepository {
|
||||
return db.issueTasks
|
||||
}
|
||||
|
||||
func (db *DB) IssueItems() repositories.IssueItemRepository {
|
||||
return db.issueItems
|
||||
}
|
||||
|
||||
func (db *DB) Items() repositories.ItemRepository {
|
||||
return db.items
|
||||
}
|
||||
@@ -95,12 +100,14 @@ func Open(connectionString string) (*DB, error) {
|
||||
sessions := &sessionRepository{db: db}
|
||||
projectStatuses := &projectStatusRepository{db: db}
|
||||
issueTasks := &issueTaskRepository{db: db}
|
||||
issueItems := &issueItemRepository{db: db}
|
||||
|
||||
return &DB{
|
||||
db: db,
|
||||
activities: activities,
|
||||
issues: issues,
|
||||
issueTasks: issueTasks,
|
||||
issueItems: issueItems,
|
||||
items: items,
|
||||
projects: projects,
|
||||
users: users,
|
||||
|
||||
@@ -90,15 +90,15 @@ func (r *issueTaskRepository) Insert(ctx context.Context, task models.IssueTask)
|
||||
|
||||
_, err = tx.NamedExecContext(ctx, `
|
||||
INSERT INTO issue_task (
|
||||
issue_task_id, issue_id, activity_id, created_time,
|
||||
updated_time, due_time, status_stage, status_name,
|
||||
name, description, estimated_time, estimated_units,
|
||||
points_multiplier
|
||||
issue_task_id, issue_id, activity_id, created_time,
|
||||
updated_time, due_time, status_stage, status_name,
|
||||
name, description, estimated_time, estimated_units,
|
||||
points_multiplier
|
||||
) VALUES (
|
||||
:issue_task_id, :issue_id, :activity_id, :created_time,
|
||||
:updated_time, :due_time, :status_stage, :status_name,
|
||||
:name, :description, :estimated_time, :estimated_units,
|
||||
:points_multiplier
|
||||
:issue_task_id, :issue_id, :activity_id, :created_time,
|
||||
:updated_time, :due_time, :status_stage, :status_name,
|
||||
:name, :description, :estimated_time, :estimated_units,
|
||||
:points_multiplier
|
||||
)
|
||||
`, task)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package mysqldriver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.aiterp.net/stufflog/server/internal/slerrors"
|
||||
"git.aiterp.net/stufflog/server/models"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type issueItemRepository struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func (r *issueItemRepository) Find(ctx context.Context, id string) (*models.IssueItem, error) {
|
||||
issueItem := models.IssueItem{}
|
||||
err := r.db.GetContext(ctx, &issueItem, "SELECT * FROM issue_item WHERE issue_item_id=?", id)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, slerrors.NotFound("Issue item")
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &issueItem, nil
|
||||
}
|
||||
|
||||
func (r *issueItemRepository) List(ctx context.Context, filter models.IssueItemFilter) ([]*models.IssueItem, error) {
|
||||
q := sq.Select("issue_item.*").From("issue_item").GroupBy("issue_item.issue_item_id")
|
||||
if len(filter.IssueItemIDs) > 0 {
|
||||
q = q.Where(sq.Eq{"issue_item_id": filter.IssueIDs})
|
||||
}
|
||||
if len(filter.IssueIDs) > 0 {
|
||||
q = q.Where(sq.Eq{"issue_id": filter.IssueIDs})
|
||||
}
|
||||
if len(filter.IssueAssignees) > 0 || len(filter.IssueOwners) > 0 || filter.IssueMinStage != nil || filter.IssueMaxStage != nil {
|
||||
q = q.Join("issue ON issue.issue_id = issue_item.issue_id")
|
||||
}
|
||||
if len(filter.IssueAssignees) > 0 {
|
||||
q = q.Where(sq.Eq{"issue.assignee_id": filter.IssueAssignees})
|
||||
}
|
||||
if len(filter.IssueOwners) > 0 {
|
||||
q = q.Where(sq.Eq{"issue.owner_id": filter.IssueOwners})
|
||||
}
|
||||
if filter.IssueMinStage != nil && filter.IssueMaxStage != nil && *filter.IssueMinStage == *filter.IssueMaxStage {
|
||||
q = q.Where(sq.Eq{"issue.status_stage": *filter.IssueMinStage})
|
||||
} else {
|
||||
if filter.IssueMinStage != nil {
|
||||
q = q.Where(sq.GtOrEq{"issue.status_stage": *filter.IssueMinStage})
|
||||
}
|
||||
if filter.IssueMaxStage != nil {
|
||||
q = q.Where(sq.LtOrEq{"issue.status_stage": *filter.IssueMaxStage})
|
||||
}
|
||||
}
|
||||
if len(filter.ItemIDs) > 0 {
|
||||
q = q.Where(sq.Eq{"item_id": filter.IssueIDs})
|
||||
}
|
||||
if len(filter.ItemTags) > 0 {
|
||||
q = q.Join("item_tag ON item_tag.item_id = issue_item.item_id").Where(
|
||||
sq.Eq{"item_tag.tag": filter.ItemTags},
|
||||
)
|
||||
}
|
||||
if filter.Acquired != nil {
|
||||
q = q.Where(sq.Eq{"acquired": *filter.Acquired})
|
||||
}
|
||||
|
||||
query, args, err := q.ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := make([]*models.IssueItem, 0, 16)
|
||||
err = r.db.SelectContext(ctx, &results, query, args...)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return []*models.IssueItem{}, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (r *issueItemRepository) Insert(ctx context.Context, item models.IssueItem) (*models.IssueItem, error) {
|
||||
if item.IssueID == "" {
|
||||
return nil, errors.New("missing issue id")
|
||||
}
|
||||
|
||||
tx, err := r.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nextID, err := incCounter(ctx, tx, counterKindIssueSubID, item.IssueID)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
item.ID = fmt.Sprintf("%s-%d", item.IssueID, nextID)
|
||||
|
||||
_, err = tx.NamedExecContext(ctx, `
|
||||
INSERT INTO issue_item (
|
||||
issue_item_id, issue_id, item_id, quantity, acquired
|
||||
) VALUES (
|
||||
:issue_item_id, :issue_id, :item_id, :quantity, :acquired
|
||||
);
|
||||
`, item)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &item, nil
|
||||
}
|
||||
|
||||
func (r *issueItemRepository) Save(ctx context.Context, item models.IssueItem) error {
|
||||
_, err := r.db.NamedExecContext(ctx, `
|
||||
UPDATE issue_item SET
|
||||
acquired=:acquired,
|
||||
quantity=:quantity
|
||||
WHERE issue_item_id=:issue_item_id
|
||||
`, item)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *issueItemRepository) Delete(ctx context.Context, item models.IssueItem) error {
|
||||
_, err := r.db.ExecContext(ctx, "DELETE FROM issue_item WHERE issue_item_id=? LIMIT 1;", item.ID)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.aiterp.net/stufflog/server/models"
|
||||
)
|
||||
|
||||
type IssueItemRepository interface {
|
||||
Find(ctx context.Context, id string) (*models.IssueItem, error)
|
||||
List(ctx context.Context, filter models.IssueItemFilter) ([]*models.IssueItem, error)
|
||||
Insert(ctx context.Context, item models.IssueItem) (*models.IssueItem, error)
|
||||
Save(ctx context.Context, item models.IssueItem) error
|
||||
Delete(ctx context.Context, item models.IssueItem) error
|
||||
}
|
||||
Reference in New Issue
Block a user