2020-12-01 20:06:49 +01:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
2020-12-03 14:51:15 +01:00
|
|
|
"errors"
|
2020-12-04 23:22:05 +01:00
|
|
|
log "github.com/Sirupsen/logrus"
|
2021-09-16 22:51:53 +02:00
|
|
|
"reflect"
|
2020-12-04 23:22:05 +01:00
|
|
|
"time"
|
2020-12-01 20:06:49 +01:00
|
|
|
)
|
|
|
|
|
2020-12-04 23:22:05 +01:00
|
|
|
const databaseTimeFormat = "2006-01-02T15:04:05:99Z"
|
|
|
|
|
|
|
|
// GetParsedTime returns the timestamp as it will retrieved from the database
|
|
|
|
// This allows us to create timestamp consistency on return values from create requests
|
|
|
|
func GetParsedTime(t time.Time) time.Time {
|
|
|
|
parsedTime, err := time.Parse(databaseTimeFormat, t.Format(databaseTimeFormat))
|
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
}
|
|
|
|
return parsedTime
|
|
|
|
}
|
|
|
|
|
2020-12-01 20:06:49 +01:00
|
|
|
type RetrieveQueryParams struct {
|
|
|
|
Offset int
|
|
|
|
Count int
|
|
|
|
SortBy string
|
|
|
|
SortInverted bool
|
|
|
|
}
|
|
|
|
|
2021-10-12 13:37:51 +02:00
|
|
|
// ObjectProperties describe database entities.
|
|
|
|
// It mainly used for NoSQL implementations (currently BoltDB) to preserve same
|
|
|
|
// data structure of different implementations and easy change it if required.
|
2021-05-07 12:08:34 +02:00
|
|
|
type ObjectProperties struct {
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName string
|
|
|
|
IsGlobal bool // doesn't belong to other table, for example to project or user.
|
|
|
|
ForeignColumnSuffix string
|
|
|
|
PrimaryColumnName string
|
|
|
|
SortableColumns []string
|
|
|
|
DefaultSortingColumn string
|
|
|
|
SortInverted bool // sort from high to low object ID by default. It is useful for some NoSQL implementations.
|
|
|
|
Type reflect.Type // to which type the table bust be mapped.
|
2021-05-07 12:08:34 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 13:47:32 +02:00
|
|
|
var ErrNotFound = errors.New("no rows in result set")
|
|
|
|
var ErrInvalidOperation = errors.New("invalid operation")
|
2020-12-01 20:06:49 +01:00
|
|
|
|
2021-11-02 20:30:45 +01:00
|
|
|
type ValidationError struct {
|
|
|
|
Message string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ValidationError) Error() string {
|
|
|
|
return e.Message
|
|
|
|
}
|
|
|
|
|
2020-12-01 20:06:49 +01:00
|
|
|
type Store interface {
|
|
|
|
Connect() error
|
|
|
|
Close() error
|
2021-12-19 13:31:23 +01:00
|
|
|
// IsInitialized indicates is database already initialized, or it is empty.
|
|
|
|
// The method is useful for creating required entities in database during first run.
|
2021-12-18 14:16:34 +01:00
|
|
|
IsInitialized() (bool, error)
|
2020-12-01 20:06:49 +01:00
|
|
|
Migrate() error
|
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
GetEnvironment(projectID int, environmentID int) (Environment, error)
|
|
|
|
GetEnvironments(projectID int, params RetrieveQueryParams) ([]Environment, error)
|
|
|
|
UpdateEnvironment(env Environment) error
|
|
|
|
CreateEnvironment(env Environment) (Environment, error)
|
2020-12-04 17:29:37 +01:00
|
|
|
DeleteEnvironment(projectID int, templateID int) error
|
|
|
|
DeleteEnvironmentSoft(projectID int, templateID int) error
|
2020-12-03 14:51:15 +01:00
|
|
|
|
2020-12-07 13:13:59 +01:00
|
|
|
GetInventory(projectID int, inventoryID int) (Inventory, error)
|
|
|
|
GetInventories(projectID int, params RetrieveQueryParams) ([]Inventory, error)
|
|
|
|
UpdateInventory(inventory Inventory) error
|
|
|
|
CreateInventory(inventory Inventory) (Inventory, error)
|
2020-12-07 20:48:52 +01:00
|
|
|
DeleteInventory(projectID int, inventoryID int) error
|
|
|
|
DeleteInventorySoft(projectID int, inventoryID int) error
|
|
|
|
|
|
|
|
GetRepository(projectID int, repositoryID int) (Repository, error)
|
|
|
|
GetRepositories(projectID int, params RetrieveQueryParams) ([]Repository, error)
|
|
|
|
UpdateRepository(repository Repository) error
|
|
|
|
CreateRepository(repository Repository) (Repository, error)
|
|
|
|
DeleteRepository(projectID int, repositoryID int) error
|
|
|
|
DeleteRepositorySoft(projectID int, repositoryID int) error
|
|
|
|
|
2021-09-10 00:41:36 +02:00
|
|
|
GetAccessKey(projectID int, accessKeyID int) (AccessKey, error)
|
2020-12-08 08:23:33 +01:00
|
|
|
GetAccessKeys(projectID int, params RetrieveQueryParams) ([]AccessKey, error)
|
2021-09-09 23:31:06 +02:00
|
|
|
|
2020-12-08 08:23:33 +01:00
|
|
|
UpdateAccessKey(accessKey AccessKey) error
|
|
|
|
CreateAccessKey(accessKey AccessKey) (AccessKey, error)
|
|
|
|
DeleteAccessKey(projectID int, accessKeyID int) error
|
|
|
|
DeleteAccessKeySoft(projectID int, accessKeyID int) error
|
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
GetUsers(params RetrieveQueryParams) ([]User, error)
|
2021-05-06 14:41:31 +02:00
|
|
|
CreateUserWithoutPassword(user User) (User, error)
|
2021-03-12 22:13:39 +01:00
|
|
|
CreateUser(user UserWithPwd) (User, error)
|
2020-12-01 20:06:49 +01:00
|
|
|
DeleteUser(userID int) error
|
2021-08-28 13:44:41 +02:00
|
|
|
|
|
|
|
// UpdateUser updates all fields of the entity except Pwd.
|
|
|
|
// Pwd should be present of you want update user password. Empty Pwd ignored.
|
2021-03-12 22:13:39 +01:00
|
|
|
UpdateUser(user UserWithPwd) error
|
2020-12-01 20:06:49 +01:00
|
|
|
SetUserPassword(userID int, password string) error
|
2020-12-04 23:41:26 +01:00
|
|
|
GetUser(userID int) (User, error)
|
2020-12-17 15:00:05 +01:00
|
|
|
GetUserByLoginOrEmail(login string, email string) (User, error)
|
2020-12-01 20:06:49 +01:00
|
|
|
|
2020-12-16 20:19:20 +01:00
|
|
|
GetProject(projectID int) (Project, error)
|
|
|
|
GetProjects(userID int) ([]Project, error)
|
2020-12-04 23:41:26 +01:00
|
|
|
CreateProject(project Project) (Project, error)
|
2020-12-16 20:19:20 +01:00
|
|
|
DeleteProject(projectID int) error
|
|
|
|
UpdateProject(project Project) error
|
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
GetTemplates(projectID int, params RetrieveQueryParams) ([]Template, error)
|
|
|
|
CreateTemplate(template Template) (Template, error)
|
|
|
|
UpdateTemplate(template Template) error
|
|
|
|
GetTemplate(projectID int, templateID int) (Template, error)
|
2020-12-03 14:51:15 +01:00
|
|
|
DeleteTemplate(projectID int, templateID int) error
|
|
|
|
|
2021-09-06 13:05:10 +02:00
|
|
|
GetSchedules() ([]Schedule, error)
|
|
|
|
GetTemplateSchedules(projectID int, templateID int) ([]Schedule, error)
|
|
|
|
CreateSchedule(schedule Schedule) (Schedule, error)
|
|
|
|
UpdateSchedule(schedule Schedule) error
|
|
|
|
GetSchedule(projectID int, scheduleID int) (Schedule, error)
|
|
|
|
DeleteSchedule(projectID int, scheduleID int) error
|
|
|
|
|
2020-12-17 15:00:05 +01:00
|
|
|
GetProjectUsers(projectID int, params RetrieveQueryParams) ([]User, error)
|
2020-12-04 23:41:26 +01:00
|
|
|
CreateProjectUser(projectUser ProjectUser) (ProjectUser, error)
|
2020-12-17 15:00:05 +01:00
|
|
|
DeleteProjectUser(projectID int, userID int) error
|
|
|
|
GetProjectUser(projectID int, userID int) (ProjectUser, error)
|
|
|
|
UpdateProjectUser(projectUser ProjectUser) error
|
2020-12-03 14:51:15 +01:00
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
CreateEvent(event Event) (Event, error)
|
2020-12-20 19:00:59 +01:00
|
|
|
GetUserEvents(userID int, params RetrieveQueryParams) ([]Event, error)
|
|
|
|
GetEvents(projectID int, params RetrieveQueryParams) ([]Event, error)
|
2020-12-01 20:06:49 +01:00
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
GetAPITokens(userID int) ([]APIToken, error)
|
|
|
|
CreateAPIToken(token APIToken) (APIToken, error)
|
|
|
|
GetAPIToken(tokenID string) (APIToken, error)
|
2020-12-03 14:51:15 +01:00
|
|
|
ExpireAPIToken(userID int, tokenID string) error
|
|
|
|
|
2020-12-04 23:41:26 +01:00
|
|
|
GetSession(userID int, sessionID int) (Session, error)
|
2021-03-12 18:41:41 +01:00
|
|
|
CreateSession(session Session) (Session, error)
|
2020-12-03 14:51:15 +01:00
|
|
|
ExpireSession(userID int, sessionID int) error
|
|
|
|
TouchSession(userID int, sessionID int) error
|
|
|
|
|
2021-03-12 18:41:41 +01:00
|
|
|
CreateTask(task Task) (Task, error)
|
|
|
|
UpdateTask(task Task) error
|
|
|
|
|
2021-10-13 16:07:22 +02:00
|
|
|
GetTemplateTasks(template Template, params RetrieveQueryParams) ([]TaskWithTpl, error)
|
2021-03-12 18:41:41 +01:00
|
|
|
GetProjectTasks(projectID int, params RetrieveQueryParams) ([]TaskWithTpl, error)
|
|
|
|
GetTask(projectID int, taskID int) (Task, error)
|
|
|
|
DeleteTaskWithOutputs(projectID int, taskID int) error
|
|
|
|
GetTaskOutputs(projectID int, taskID int) ([]TaskOutput, error)
|
|
|
|
CreateTaskOutput(output TaskOutput) (TaskOutput, error)
|
2021-10-26 20:19:12 +02:00
|
|
|
|
|
|
|
GetView(projectID int, viewID int) (View, error)
|
|
|
|
GetViews(projectID int) ([]View, error)
|
2021-10-27 21:48:51 +02:00
|
|
|
GetViewTemplates(projectID int, viewID int, params RetrieveQueryParams) ([]Template, error)
|
2021-10-26 20:19:12 +02:00
|
|
|
UpdateView(view View) error
|
|
|
|
CreateView(view View) (View, error)
|
|
|
|
DeleteView(projectID int, viewID int) error
|
2021-10-27 13:43:04 +02:00
|
|
|
SetViewPositions(projectID int, viewPositions map[int]int) error
|
2020-12-01 20:06:49 +01:00
|
|
|
}
|
2020-12-07 20:48:52 +01:00
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var AccessKeyProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "access_key",
|
|
|
|
SortableColumns: []string{"name", "type"},
|
|
|
|
ForeignColumnSuffix: "key_id",
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(AccessKey{}),
|
|
|
|
DefaultSortingColumn: "name",
|
2021-05-07 12:08:34 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var EnvironmentProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project__environment",
|
|
|
|
SortableColumns: []string{"name"},
|
|
|
|
ForeignColumnSuffix: "environment_id",
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(Environment{}),
|
|
|
|
DefaultSortingColumn: "name",
|
2021-05-07 12:08:34 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var InventoryProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project__inventory",
|
|
|
|
SortableColumns: []string{"name"},
|
|
|
|
ForeignColumnSuffix: "inventory_id",
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(Inventory{}),
|
|
|
|
DefaultSortingColumn: "name",
|
2021-05-07 12:08:34 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var RepositoryProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project__repository",
|
|
|
|
ForeignColumnSuffix: "repository_id",
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(Repository{}),
|
|
|
|
DefaultSortingColumn: "name",
|
2021-05-07 12:08:34 +02:00
|
|
|
}
|
2020-12-07 20:48:52 +01:00
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var TemplateProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project__template",
|
|
|
|
SortableColumns: []string{"name"},
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(Template{}),
|
|
|
|
DefaultSortingColumn: "alias",
|
2021-05-08 22:25:31 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 13:05:10 +02:00
|
|
|
var ScheduleProps = ObjectProperties{
|
|
|
|
TableName: "project__schedule",
|
|
|
|
PrimaryColumnName: "id",
|
2021-09-16 22:51:53 +02:00
|
|
|
Type: reflect.TypeOf(Schedule{}),
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var ProjectUserProps = ObjectProperties{
|
2021-06-24 19:45:28 +02:00
|
|
|
TableName: "project__user",
|
2021-05-16 23:44:42 +02:00
|
|
|
PrimaryColumnName: "user_id",
|
2021-09-16 22:51:53 +02:00
|
|
|
Type: reflect.TypeOf(ProjectUser{}),
|
2021-05-09 22:08:10 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var ProjectProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project",
|
|
|
|
IsGlobal: true,
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(Project{}),
|
|
|
|
DefaultSortingColumn: "name",
|
2021-05-09 22:08:10 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var UserProps = ObjectProperties{
|
2021-06-24 19:45:28 +02:00
|
|
|
TableName: "user",
|
|
|
|
IsGlobal: true,
|
2021-05-16 23:44:42 +02:00
|
|
|
PrimaryColumnName: "id",
|
2021-09-16 22:51:53 +02:00
|
|
|
Type: reflect.TypeOf(User{}),
|
2021-05-09 22:08:10 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var SessionProps = ObjectProperties{
|
2021-06-24 19:45:28 +02:00
|
|
|
TableName: "session",
|
2021-05-16 23:44:42 +02:00
|
|
|
PrimaryColumnName: "id",
|
2021-09-16 22:51:53 +02:00
|
|
|
Type: reflect.TypeOf(Session{}),
|
2021-05-09 22:08:10 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var TokenProps = ObjectProperties{
|
2021-06-24 19:45:28 +02:00
|
|
|
TableName: "user__token",
|
2021-05-16 23:44:42 +02:00
|
|
|
PrimaryColumnName: "id",
|
2021-05-09 22:08:10 +02:00
|
|
|
}
|
2021-05-13 15:49:32 +02:00
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var TaskProps = ObjectProperties{
|
2021-06-24 19:45:28 +02:00
|
|
|
TableName: "task",
|
|
|
|
IsGlobal: true,
|
2021-05-16 23:44:42 +02:00
|
|
|
PrimaryColumnName: "id",
|
2021-06-24 21:53:36 +02:00
|
|
|
SortInverted: true,
|
2021-09-16 22:51:53 +02:00
|
|
|
Type: reflect.TypeOf(Task{}),
|
2021-05-13 15:49:32 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
var TaskOutputProps = ObjectProperties{
|
2021-09-16 22:51:53 +02:00
|
|
|
TableName: "task__output",
|
|
|
|
Type: reflect.TypeOf(TaskOutput{}),
|
2021-05-13 15:49:32 +02:00
|
|
|
}
|
2021-10-27 13:43:04 +02:00
|
|
|
|
|
|
|
var ViewProps = ObjectProperties{
|
2021-10-27 18:22:52 +02:00
|
|
|
TableName: "project__view",
|
|
|
|
PrimaryColumnName: "id",
|
|
|
|
Type: reflect.TypeOf(View{}),
|
|
|
|
DefaultSortingColumn: "position",
|
2021-10-27 13:43:04 +02:00
|
|
|
}
|