db

package
v0.12.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 7, 2023 License: BSD-3-Clause Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MembersNamespace       = "members"
	MembersDefaultPageSize = 100
	MaxNameLength          = 1024
)
View Source
const (
	ProjectNamespace     = "projects"
	MaxDescriptionLength = 2000
)
View Source
const (
	ProjectStatusIncomplete = "Incomplete"
	ProjectStatusActive     = "Active"
	ProjectStatusArchived   = "Archived"
)

Project states to return to the frontend.

View Source
const (
	TopicStatusActive   = "Active"
	TopicStatusArchived = "Archived"
	TopicStatusDeleting = "Deleting"
)

Topic states to return to the frontend.

View Source
const KeysNamespace = "object_keys"

Keys Namespace maps object IDs to their fully qualified database keys.

View Source
const OrganizationNamespace = "organizations"
View Source
const TenantNamespace = "tenants"
View Source
const TopicNamespace = "topics"

Variables

View Source
var (
	ErrNotConnected   = errors.New("not connected to trtl database")
	ErrNotFound       = errors.New("object not found for the specified key")
	ErrUnavailable    = errors.New("trtl database service is unavailable")
	ErrListBreak      = errors.New("on list item has stopped iterating")
	ErrOrgNotVerified = errors.New("could not verify organization")

	// Missing fields
	ErrMissingID           = errors.New("object requires id for serialization")
	ErrMissingOrgID        = errors.New("object requires organization id for serialization")
	ErrMissingTenantID     = errors.New("object requires tenant id for serialization")
	ErrMissingProjectID    = errors.New("object requires project id for serialization")
	ErrMissingMemberEmail  = errors.New("member email is required")
	ErrMissingMemberRole   = errors.New("member role is required")
	ErrMissingMemberStatus = errors.New("member status is required")
	ErrMissingProjectName  = errors.New("project name is required")
	ErrMissingTenantName   = errors.New("tenant name is required")
	ErrMissingEnvType      = errors.New("tenant environment type is required")
	ErrMissingTopicName    = errors.New("topic name is required")
	ErrMissingPageSize     = errors.New("cannot list database without a page size")
	ErrMissingOwnerID      = errors.New("model is missing owner id")

	// Invalid fields
	ErrNameTooLong          = errors.New("name cannot be longer than 1024 characters")
	ErrOrganizationTooLong  = errors.New("organization name cannot be longer than 1024 characters")
	ErrWorkspaceTooLong     = errors.New("workspace name cannot be longer than 1024 characters")
	ErrProfessionUnknown    = errors.New("unknown profession segment")
	ErrDeveloperUnknown     = errors.New("unknown developer segment")
	ErrDeveloperUnspecified = errors.New("unspecified developer segment")
	ErrInvalidWorkspace     = errors.New("workspace name must be at least 3 characters and cannot start with a number")
	ErrUnknownMemberRole    = errors.New("unknown member role")
	ErrInvalidProjectName   = errors.New("invalid project name")
	ErrInvalidTenantName    = errors.New("invalid tenant name")
	ErrInvalidTopicName     = errors.New("invalid topic name")
	ErrInvalidStorage       = errors.New("data storage must be greater than or equal to 0")

	// Database state errors
	ErrMemberExists        = errors.New("member already exists")
	ErrMemberEmailNotFound = errors.New("member does not exist")

	// Key errors
	ErrKeyNoID      = errors.New("key does not contain an id")
	ErrKeyWrongSize = errors.New("key is not the correct size")

	// Pagination index errors
	ErrIndexInvalidSize = errors.New("index is not a valid size")

	// Max-length errors
	ErrProjectDescriptionTooLong = errors.New("project description is too long")
	ErrTopicNameTooLong          = errors.New("topic name is too long")
)
View Source
var (
	TopicNameRegex     = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9\.\_\-]*$`)
	MaxTopicNameLength = 512
)

Topic names must be URL safe and begin with a letter.

View Source
var DeveloperSegmentStrings = map[DeveloperSegment]string{
	DeveloperSegmentUnspecified:            "Unspecified",
	DeveloperSegmentSomethingElse:          "Something else",
	DeveloperSegmentApplicationDevelopment: "Application development",
	DeveloperSegmentDataScience:            "Data science",
	DeveloperSegmentDataEngineering:        "Data engineering",
	DeveloperSegmentDeveloperExperience:    "Developer experience",
	DeveloperSegmentCybersecurity:          "Cybersecurity (blue or purple team)",
	DeveloperSegmentDevOps:                 "DevOps and observability",
}
View Source
var MemberStatusStrings = map[MemberStatus]string{
	MemberStatusPending:    "Pending",
	MemberStatusOnboarding: "Onboarding",
	MemberStatusActive:     "Active",
}
View Source
var NullID = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
View Source
var ProfessionSegmentStrings = map[ProfessionSegment]string{
	ProfessionSegmentUnspecified: "Unspecified",
	ProfessionSegmentWork:        "Work",
	ProfessionSegmentEducation:   "Education",
	ProfessionSegmentPersonal:    "Personal",
}
View Source
var TenantNameRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9\.\-_]*$`)

Tenant names must be URL safe and begin with a letter.

View Source
var (
	// Must be at least 3 characters, cannot start with a number, and is alphanumeric with + _ and -
	WorkspaceNameRegex = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9+_-]{2,}$`)
)

Functions

func Close

func Close() error

Close the connection to the database, once closed the package must be reconnected otherwise database operations will not succeed. If the database is already closed then no error will occur.

func Connect

func Connect(conf config.DatabaseConfig) (err error)

Connect to the trtl database, this function must be called at least once before any database interaction can occur. Multiple calls to Connect will not error (e.g. if the database is already connected then nothing will happen).

func CreateMember added in v0.2.0

func CreateMember(ctx context.Context, member *Member) (err error)

CreateMember adds a new Member to an organization in the database. Note: If a memberID is not passed in by the User, a new member id will be generated.

func CreateProject added in v0.2.0

func CreateProject(ctx context.Context, project *Project) (err error)

CreateProject adds a new project to an organization in the database. Note: If a project id is not passed in by the User, a new project id will be generated.

func CreateTenant

func CreateTenant(ctx context.Context, tenant *Tenant) (err error)

CreateTenant adds a new project to the database. Note: If a tenant id is not passed in by the User, a new tenant id will be generated.

func CreateTenantProject added in v0.2.0

func CreateTenantProject(ctx context.Context, project *Project) (err error)

CreateTenantProject adds a new project to a tenant in the database. Note: If a project id is not passed in by the User, a new project id will be generated.

func CreateTopic added in v0.2.0

func CreateTopic(ctx context.Context, topic *Topic) (err error)

CreateTopic adds a new topic to the database.

func CreateUserResources added in v0.3.0

func CreateUserResources(ctx context.Context, member *Member) (err error)

CreateUserResources creates all the necessary database objects for a new user given a partially constructed member model. This method should be called after a new user has been successfully registered with Quarterdeck in order to allow the user to access default resources such as the tenant and user profile info when they login.

func Delete

func Delete(ctx context.Context, model Model) (err error)

func DeleteMember added in v0.2.0

func DeleteMember(ctx context.Context, orgID, memberID ulid.ULID) (err error)

DeleteMember deletes a member with a given orgID and member ID.

func DeleteObjectKey added in v0.5.0

func DeleteObjectKey(ctx context.Context, key []byte) (err error)

Helper to delete an object's key from the database.

func DeleteProject added in v0.2.0

func DeleteProject(ctx context.Context, projectID ulid.ULID) (err error)

DeleteProject deletes a project with the given project id.

func DeleteTenant

func DeleteTenant(ctx context.Context, orgID, tenantID ulid.ULID) (err error)

Delete a tenant from the orgID and tenantID.

func DeleteTopic added in v0.2.0

func DeleteTopic(ctx context.Context, topicID ulid.ULID) (err error)

DeleteTopic deletes a topic by the given project ID and topic ID.

func Get

func Get(ctx context.Context, model Model) (err error)

Get retrieves a model value based on its key and namespace.

func GetMock added in v0.2.0

func GetMock() *mock.RemoteTrtl

func GetObjectKey added in v0.5.0

func GetObjectKey(ctx context.Context, objectID ulid.ULID) (key []byte, err error)

Helper to retrieve an object's key from its ID from the database.

func GetOrgIndex added in v0.5.2

func GetOrgIndex(ctx context.Context, resourceID ulid.ULID) (orgID ulid.ULID, err error)

Use the resourceID to retrieve the orgID from the database.

func IsConnected

func IsConnected() bool

IsConnected returns true if the database has been connected to without error and the db module is ready to interact with the trtl database.

func IsTesting added in v0.2.0

func IsTesting() bool

func List

func List(ctx context.Context, prefix []byte, namespace string, onListItem OnListItem, c *pg.Cursor) (cursor *pg.Cursor, err error)

List iterates over items in the database and calls the onListItem function for each of them. If onListItem returns ErrListBreak then the iteration will stop. If there are more items than the page size in the cursor then a new cursor is returned for the next page of items.

func Put

func Put(ctx context.Context, model Model) (err error)

func PutObjectKey added in v0.5.0

func PutObjectKey(ctx context.Context, object Model) (err error)

Helper to store an object's key in the database.

func PutOrgIndex added in v0.5.2

func PutOrgIndex(ctx context.Context, resourceID, orgID ulid.ULID) error

Store the resourceID as a key and the orgID as a value in the database.

func TimeToString added in v0.5.0

func TimeToString(t time.Time) string

Helper to convert a time.Time to an RFC3339Nano string for JSON serialization.

func UpdateLastLogin added in v0.7.0

func UpdateLastLogin(ctx context.Context, accessToken string, login time.Time) (err error)

UpdateLastLogin is a helper method that updates the last login time for a member given an access token. This should normally be called in a background task to prevent blocking the user from logging in.

func UpdateMember added in v0.2.0

func UpdateMember(ctx context.Context, member *Member) (err error)

UpdateMember updates the record of a member by its id.

func UpdateProject added in v0.2.0

func UpdateProject(ctx context.Context, project *Project) (err error)

UpdateProject updates the record of a project from its database model.

func UpdateTenant

func UpdateTenant(ctx context.Context, tenant *Tenant) (err error)

func UpdateTopic added in v0.2.0

func UpdateTopic(ctx context.Context, topic *Topic) (err error)

UpdateTopic updates the record of a topic from its database model.

func VerifyMemberEmail added in v0.5.2

func VerifyMemberEmail(ctx context.Context, orgID ulid.ULID, email string) (err error)

Helper method that returns an error if an email address is invalid or already exists in the organization.

func VerifyOrg added in v0.5.2

func VerifyOrg(ctx context.Context, claimsOrgID, resourceID ulid.ULID) error

VerifyOrg will check that resources are allocated to the correct organization. The method will take in an orgID from the claims and will return true if the orgID from the database is the same and an error if it is not.

Types

type DeveloperSegment added in v0.10.0

type DeveloperSegment uint8
const (
	DeveloperSegmentUnspecified DeveloperSegment = iota
	DeveloperSegmentSomethingElse
	DeveloperSegmentApplicationDevelopment
	DeveloperSegmentDataScience
	DeveloperSegmentDataEngineering
	DeveloperSegmentDeveloperExperience
	DeveloperSegmentCybersecurity
	DeveloperSegmentDevOps
)

func ParseDeveloperSegment added in v0.10.0

func ParseDeveloperSegment(segment string) (DeveloperSegment, error)

Parse a segment string into a DeveloperSegment, empty string is considered unspecified but not an error.

func (DeveloperSegment) String added in v0.10.0

func (d DeveloperSegment) String() string

type Key added in v0.5.0

type Key [32]byte

Key is composed of two concatenated IDs. The first 16 bytes are the ID of parent and the second 16 bytes are the ID of the object.

func CreateKey added in v0.5.0

func CreateKey(parentID, objectID ulid.ULID) (key Key, err error)

CreateKey creates a new key from a parent ID and object ID so that callers can lookup the object ID from its namespace.

func ParseKey added in v0.11.0

func ParseKey(s string) (key Key, err error)

ParseKey parses a string representation of a key into a Key struct.

func (Key) Key added in v0.5.0

func (k Key) Key() ([]byte, error)

Keys are stored by object ID. Since object IDs are locked monotonically increasing ulids they are guaranteed to be unique.

func (Key) MarshalValue added in v0.5.0

func (k Key) MarshalValue() ([]byte, error)

func (Key) Namespace added in v0.5.0

func (k Key) Namespace() string

func (Key) ObjectID added in v0.5.0

func (k Key) ObjectID() (id ulid.ULID, err error)

func (Key) ParentID added in v0.5.0

func (k Key) ParentID() (id ulid.ULID, err error)

func (Key) String added in v0.11.0

func (k Key) String() (_ string, err error)

String returns a string representation of the key with the parent ID concatenated with the object ID.

func (*Key) UnmarshalValue added in v0.5.0

func (k *Key) UnmarshalValue(data []byte) error

type Member added in v0.2.0

type Member struct {
	OrgID             ulid.ULID          `msgpack:"org_id"`
	ID                ulid.ULID          `msgpack:"id"`
	Email             string             `msgpack:"email"`
	Name              string             `msgpack:"name"`
	Organization      string             `msgpack:"organization"`
	Workspace         string             `msgpack:"workspace"`
	ProfessionSegment ProfessionSegment  `msgpack:"profession_segment"`
	DeveloperSegment  []DeveloperSegment `msgpack:"developer_segment"`
	Role              string             `msgpack:"role"`
	Invited           bool               `msgpack:"invited"`
	JoinedAt          time.Time          `msgpack:"joined_at"`
	LastActivity      time.Time          `msgpack:"last_activity"`
	Created           time.Time          `msgpack:"created"`
	Modified          time.Time          `msgpack:"modified"`
	// contains filtered or unexported fields
}

func GetMemberByEmail added in v0.5.2

func GetMemberByEmail(ctx context.Context, orgID ulid.ULID, email string) (member *Member, err error)

GetMemberByEmail returns a member by the exact email address without any lowercasing validation.

func ListMembers added in v0.2.0

func ListMembers(ctx context.Context, orgID ulid.ULID, c *pg.Cursor) (members []*Member, cursor *pg.Cursor, err error)

ListMembers retrieves a paginated list of members.

func RetrieveMember added in v0.2.0

func RetrieveMember(ctx context.Context, orgID, memberID ulid.ULID) (member *Member, err error)

RetrieveMember gets a member from the database with the given orgID and member ID.

func (*Member) IsOnboarded added in v0.10.0

func (m *Member) IsOnboarded() bool

IsOnboarded returns true if there is enough information to consider the member fully onboarded into the organization.

func (*Member) Key added in v0.2.0

func (m *Member) Key() (key []byte, err error)

Key is a 32 byte composite key combining the org id and member id.

func (*Member) MarshalValue added in v0.2.0

func (m *Member) MarshalValue() ([]byte, error)

func (*Member) Namespace added in v0.2.0

func (m *Member) Namespace() string

func (*Member) OnboardingStatus added in v0.10.0

func (m *Member) OnboardingStatus() MemberStatus

OnboardingStatus returns the current status of the member which is a derived value based on the information in the member record.

func (*Member) Picture added in v0.7.0

func (m *Member) Picture() string

func (*Member) ToAPI added in v0.5.0

func (m *Member) ToAPI() *api.Member

Convert the model to an API response

func (*Member) UnmarshalValue added in v0.2.0

func (m *Member) UnmarshalValue(data []byte) error

func (*Member) Validate added in v0.2.0

func (m *Member) Validate() error

Validate checks if the member is ready for storage, which can potentially return multiple errors in the form of a ValidationErrors.

type MemberStatus added in v0.5.2

type MemberStatus uint8
const (
	MemberStatusPending MemberStatus = iota
	MemberStatusOnboarding
	MemberStatusActive
)

func (MemberStatus) String added in v0.5.2

func (m MemberStatus) String() string

type Model

type Model interface {
	// Handle database storage semantics
	Key() ([]byte, error)
	Namespace() string

	// Handle serialization and deserialization of a single Model
	MarshalValue() ([]byte, error)
	UnmarshalValue([]byte) error
}

Models are structs that have key-value properties that can used for Get, Put, and Delete operations to the database. The Model interface allows us to unify common interaction patterns (for example checking connections) and returning specific errors as well as ensuring that serialization and deserialization occur correctly.

type OnListItem added in v0.5.2

type OnListItem func(*trtl.KVPair) error

type ProfessionSegment added in v0.10.0

type ProfessionSegment uint8
const (
	ProfessionSegmentUnspecified ProfessionSegment = iota
	ProfessionSegmentWork
	ProfessionSegmentEducation
	ProfessionSegmentPersonal
)

func ParseProfessionSegment added in v0.10.0

func ParseProfessionSegment(segment string) (ProfessionSegment, error)

Parse a segment string into a ProfessionSegment, empty string is considered unspecified but not an error.

func (ProfessionSegment) IsZero added in v0.11.0

func (p ProfessionSegment) IsZero() bool

func (ProfessionSegment) String added in v0.10.0

func (p ProfessionSegment) String() string

type Project added in v0.2.0

type Project struct {
	OrgID       ulid.ULID `msgpack:"org_id"`
	TenantID    ulid.ULID `msgpack:"tenant_id"`
	ID          ulid.ULID `msgpack:"id"`
	OwnerID     ulid.ULID `msgpack:"owner_id"`
	Name        string    `msgpack:"name"`
	Description string    `msgpack:"description"`
	Archived    bool      `msgpack:"archived"`
	APIKeys     uint64    `msgpack:"api_keys"`
	Topics      uint64    `msgpack:"topics"`
	Created     time.Time `msgpack:"created"`
	Modified    time.Time `msgpack:"modified"`
	// contains filtered or unexported fields
}

func ListProjects added in v0.2.0

func ListProjects(ctx context.Context, tenantID ulid.ULID, c *pg.Cursor) (projects []*Project, cursor *pg.Cursor, err error)

ListProjects retrieves a paginated list of projects.

func RetrieveProject added in v0.2.0

func RetrieveProject(ctx context.Context, projectID ulid.ULID) (project *Project, err error)

RetrieveProject gets a project from the database with the given project id.

func (*Project) Key added in v0.2.0

func (p *Project) Key() (key []byte, err error)

Key is a 32 composite key combining the tenant id and the project id.

func (*Project) MarshalValue added in v0.2.0

func (p *Project) MarshalValue() ([]byte, error)

func (*Project) Namespace added in v0.2.0

func (p *Project) Namespace() string

func (*Project) Owner added in v0.7.0

func (p *Project) Owner(ctx context.Context) (owner *Member, err error)

Owner sets the member info for the owner of the project if it's on the struct, otherwise the member record is fetched from the database and stored on the struct.

func (*Project) SetOwnerFromClaims added in v0.7.0

func (p *Project) SetOwnerFromClaims(claims *tokens.Claims) (err error)

SetOwnerFromClaims sets the owner of the project based on the user's claims. This should only be called when the owner ID is not already on the struct (e.g. when creating new project models). If the owner data just needs to be populated then the Owner() method should be used instead.

func (*Project) Status added in v0.7.0

func (p *Project) Status() string

Status returns the status of a project based on the number of API keys and topics

func (*Project) ToAPI added in v0.5.0

func (p *Project) ToAPI() *api.Project

Convert the model to an API response for create and update requests.

func (*Project) UnmarshalValue added in v0.2.0

func (p *Project) UnmarshalValue(data []byte) error

func (*Project) Validate added in v0.2.0

func (p *Project) Validate() (err error)

type Tenant

type Tenant struct {
	OrgID           ulid.ULID `msgpack:"org_id"`
	ID              ulid.ULID `msgpack:"id"`
	Name            string    `msgpack:"name"`
	EnvironmentType string    `msgpack:"environment_type"`
	Created         time.Time `msgpack:"created"`
	Modified        time.Time `msgpack:"modified"`
}

func ListTenants added in v0.2.0

func ListTenants(ctx context.Context, orgID ulid.ULID, c *pg.Cursor) (tenants []*Tenant, cursor *pg.Cursor, err error)

ListTenants retrieves a paginated list of tenants.

func RetrieveTenant

func RetrieveTenant(ctx context.Context, orgID, tenantID ulid.ULID) (tenant *Tenant, err error)

Retrieve a tenant from the orgID and tenantID.

func (*Tenant) Key

func (t *Tenant) Key() (key []byte, err error)

Key is a 32 byte composite key combining the org id and tenant id.

func (*Tenant) MarshalValue

func (t *Tenant) MarshalValue() ([]byte, error)

func (*Tenant) Namespace

func (t *Tenant) Namespace() string

func (*Tenant) ToAPI added in v0.5.0

func (t *Tenant) ToAPI() *api.Tenant

Convert the model to an API response.

func (*Tenant) UnmarshalValue

func (t *Tenant) UnmarshalValue(data []byte) error

func (*Tenant) Validate added in v0.3.0

func (t *Tenant) Validate() error

type Topic added in v0.2.0

type Topic struct {
	OrgID              ulid.ULID                `msgpack:"org_id"`
	ProjectID          ulid.ULID                `msgpack:"project_id"`
	ID                 ulid.ULID                `msgpack:"id"`
	Name               string                   `msgpack:"name"`
	State              pb.TopicTombstone_Status `msgpack:"state"`
	Events             float64                  `msgpack:"events"`
	Storage            float64                  `msgpack:"storage"`
	Publishers         *metatopic.Activity      `msgpack:"publishers"`
	Subscribers        *metatopic.Activity      `msgpack:"subscribers"`
	ConfirmDeleteToken string                   `msgpack:"confirm_delete_token"`
	Created            time.Time                `msgpack:"created"`
	Modified           time.Time                `msgpack:"modified"`
}

func ListTopics added in v0.2.0

func ListTopics(ctx context.Context, projectID ulid.ULID, c *pg.Cursor) (topics []*Topic, cursor *pg.Cursor, err error)

ListTopics retrieves a paginated list of topics.

func RetrieveTopic added in v0.2.0

func RetrieveTopic(ctx context.Context, topicID ulid.ULID) (topic *Topic, err error)

RetrieveTopic gets a topic from the database by the given topic ID.

func (*Topic) Key added in v0.2.0

func (t *Topic) Key() (key []byte, err error)

Key is a 32 composite key combining the project ID and the topic ID.

func (*Topic) MarshalValue added in v0.2.0

func (t *Topic) MarshalValue() ([]byte, error)

func (*Topic) Namespace added in v0.2.0

func (t *Topic) Namespace() string

func (*Topic) Status added in v0.7.0

func (t *Topic) Status() string

Status returns a human readable status string based on the internal state.

func (*Topic) ToAPI added in v0.5.0

func (t *Topic) ToAPI() *api.Topic

Convert the model to an API response.

func (*Topic) UnmarshalValue added in v0.2.0

func (t *Topic) UnmarshalValue(data []byte) error

func (*Topic) Validate added in v0.2.0

func (t *Topic) Validate() error

type ValidationError added in v0.3.0

type ValidationError struct {
	Field string
	Err   error
	Index int
}

ValidationError represents a validation error for a specific field and may contain an index if the field is a slice.

func (*ValidationError) AtIndex added in v0.10.0

func (e *ValidationError) AtIndex(index int) *ValidationError

func (*ValidationError) Error added in v0.7.0

func (e *ValidationError) Error() string

func (*ValidationError) Is added in v0.7.0

func (e *ValidationError) Is(target error) bool

func (*ValidationError) Unwrap added in v0.7.0

func (e *ValidationError) Unwrap() error

type ValidationErrors added in v0.10.0

type ValidationErrors []*ValidationError

func (ValidationErrors) Error added in v0.10.0

func (v ValidationErrors) Error() string

func (ValidationErrors) ToAPI added in v0.10.0

func (v ValidationErrors) ToAPI() api.FieldValidationErrors

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL