mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:37:30 +00:00
get / list implemented
This commit is contained in:
@@ -52,6 +52,14 @@ type InstanceDomainRepository interface {
|
||||
instanceDomainConditions
|
||||
instanceDomainChanges
|
||||
|
||||
// Get returns a single domain based on the criteria.
|
||||
// If no domain is found, it returns an error of type [database.ErrNotFound].
|
||||
// If multiple domains are found, it returns an error of type [database.ErrMultipleRows].
|
||||
Get(ctx context.Context, opts ...database.QueryOption) (*InstanceDomain, error)
|
||||
// List returns a list of domains based on the criteria.
|
||||
// If no domains are found, it returns an empty slice.
|
||||
List(ctx context.Context, opts ...database.QueryOption) ([]*InstanceDomain, error)
|
||||
|
||||
// Add adds a new domain to the instance.
|
||||
Add(ctx context.Context, domain *AddInstanceDomain) error
|
||||
// Update updates an existing domain in the instance.
|
||||
|
@@ -94,9 +94,3 @@ type MemberRepository interface {
|
||||
RemoveMember(ctx context.Context, orgID, userID string) error
|
||||
}
|
||||
|
||||
// DomainRepository is a sub repository of the org repository and maybe the instance repository.
|
||||
type DomainRepository interface {
|
||||
AddDomain(ctx context.Context, domain string) error
|
||||
SetDomainVerified(ctx context.Context, domain string) error
|
||||
RemoveDomain(ctx context.Context, domain string) error
|
||||
}
|
||||
|
@@ -56,6 +56,14 @@ type OrganizationDomainRepository interface {
|
||||
organizationDomainConditions
|
||||
organizationDomainChanges
|
||||
|
||||
// Get returns a single domain based on the criteria.
|
||||
// If no domain is found, it returns an error of type [database.ErrNotFound].
|
||||
// If multiple domains are found, it returns an error of type [database.ErrMultipleRows].
|
||||
Get(ctx context.Context, opts ...database.QueryOption) (*OrganizationDomain, error)
|
||||
// List returns a list of domains based on the criteria.
|
||||
// If no domains are found, it returns an empty slice.
|
||||
List(ctx context.Context, opts ...database.QueryOption) ([]*OrganizationDomain, error)
|
||||
|
||||
// Add adds a new domain to the organization.
|
||||
Add(ctx context.Context, domain *AddOrganizationDomain) error
|
||||
// Update updates an existing domain in the organization.
|
||||
|
@@ -2,37 +2,58 @@ package database
|
||||
|
||||
type QueryOption func(opts *QueryOpts)
|
||||
|
||||
// WithCondition sets the condition for the query.
|
||||
func WithCondition(condition Condition) QueryOption {
|
||||
return func(opts *QueryOpts) {
|
||||
opts.Condition = condition
|
||||
}
|
||||
}
|
||||
|
||||
// WithOrderBy sets the columns to order the results by.
|
||||
func WithOrderBy(orderBy ...Column) QueryOption {
|
||||
return func(opts *QueryOpts) {
|
||||
opts.OrderBy = orderBy
|
||||
}
|
||||
}
|
||||
|
||||
// WithLimit sets the maximum number of results to return.
|
||||
func WithLimit(limit uint32) QueryOption {
|
||||
return func(opts *QueryOpts) {
|
||||
opts.Limit = limit
|
||||
}
|
||||
}
|
||||
|
||||
// WithOffset sets the number of results to skip before returning the results.
|
||||
func WithOffset(offset uint32) QueryOption {
|
||||
return func(opts *QueryOpts) {
|
||||
opts.Offset = offset
|
||||
}
|
||||
}
|
||||
|
||||
// QueryOpts holds the options for a query.
|
||||
// It is used to build the SQL SELECT statement.
|
||||
type QueryOpts struct {
|
||||
// Condition is the condition to filter the results.
|
||||
// It is used to build the WHERE clause of the SQL statement.
|
||||
Condition Condition
|
||||
// OrderBy is the columns to order the results by.
|
||||
// It is used to build the ORDER BY clause of the SQL statement.
|
||||
OrderBy Columns
|
||||
// Limit is the maximum number of results to return.
|
||||
// It is used to build the LIMIT clause of the SQL statement.
|
||||
Limit uint32
|
||||
// Offset is the number of results to skip before returning the results.
|
||||
// It is used to build the OFFSET clause of the SQL statement.
|
||||
Offset uint32
|
||||
}
|
||||
|
||||
func (opts *QueryOpts) Write(builder *StatementBuilder) {
|
||||
opts.WriteCondition(builder)
|
||||
opts.WriteOrderBy(builder)
|
||||
opts.WriteLimit(builder)
|
||||
opts.WriteOffset(builder)
|
||||
}
|
||||
|
||||
func (opts *QueryOpts) WriteCondition(builder *StatementBuilder) {
|
||||
if opts.Condition == nil {
|
||||
return
|
||||
|
@@ -18,6 +18,39 @@ type instanceDomain struct {
|
||||
// repository
|
||||
// -------------------------------------------------------------
|
||||
|
||||
const queryInstanceDomainStmt = `SELECT instance_id, domain, is_verified, is_primary, verification_type, created_at, updated_at ` +
|
||||
`FROM zitadel.instance_domains`
|
||||
|
||||
// Get implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).Get of instanceDomain.instance.
|
||||
func (i *instanceDomain) Get(ctx context.Context, opts ...database.QueryOption) (*domain.InstanceDomain, error) {
|
||||
options := new(database.QueryOpts)
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
var builder database.StatementBuilder
|
||||
builder.WriteString(queryInstanceDomainStmt)
|
||||
options.Write(&builder)
|
||||
|
||||
return scanInstanceDomain(ctx, i.client, &builder)
|
||||
}
|
||||
|
||||
// List implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).List of instanceDomain.instance.
|
||||
func (i *instanceDomain) List(ctx context.Context, opts ...database.QueryOption) ([]*domain.InstanceDomain, error) {
|
||||
options := new(database.QueryOpts)
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
var builder database.StatementBuilder
|
||||
builder.WriteString(queryInstanceDomainStmt)
|
||||
options.Write(&builder)
|
||||
|
||||
return scanInstanceDomains(ctx, i.client, &builder)
|
||||
}
|
||||
|
||||
// Add implements [domain.InstanceDomainRepository].
|
||||
func (i *instanceDomain) Add(ctx context.Context, domain *domain.AddInstanceDomain) error {
|
||||
var builder database.StatementBuilder
|
||||
@@ -42,7 +75,7 @@ func (i *instanceDomain) Remove(ctx context.Context, condition database.Conditio
|
||||
}
|
||||
|
||||
// Update implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method (instance).Update of instanceDomain.instance.
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).Update of instanceDomain.instance.
|
||||
func (i *instanceDomain) Update(ctx context.Context, condition database.Condition, changes ...database.Change) (int64, error) {
|
||||
var builder database.StatementBuilder
|
||||
|
||||
@@ -102,7 +135,7 @@ func (i instanceDomain) IsVerifiedCondition(isVerified bool) database.Condition
|
||||
// -------------------------------------------------------------
|
||||
|
||||
// CreatedAtColumn implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method (instance).CreatedAtColumn of instanceDomain.instance.
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).CreatedAtColumn of instanceDomain.instance.
|
||||
func (instanceDomain) CreatedAtColumn() database.Column {
|
||||
return database.NewColumn("created_at")
|
||||
}
|
||||
@@ -128,7 +161,7 @@ func (instanceDomain) IsVerifiedColumn() database.Column {
|
||||
}
|
||||
|
||||
// UpdatedAtColumn implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method (instance).UpdatedAtColumn of instanceDomain.instance.
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).UpdatedAtColumn of instanceDomain.instance.
|
||||
func (instanceDomain) UpdatedAtColumn() database.Column {
|
||||
return database.NewColumn("updated_at")
|
||||
}
|
||||
@@ -146,3 +179,30 @@ func (instanceDomain) IsGeneratedColumn() database.Column {
|
||||
// -------------------------------------------------------------
|
||||
// scanners
|
||||
// -------------------------------------------------------------
|
||||
|
||||
func scanInstanceDomains(ctx context.Context, querier database.Querier, builder *database.StatementBuilder) ([]*domain.InstanceDomain, error) {
|
||||
rows, err := querier.Query(ctx, builder.String(), builder.Args()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var instanceDomains []*domain.InstanceDomain
|
||||
if err := rows.(database.CollectableRows).Collect(&instanceDomains); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return instanceDomains, nil
|
||||
}
|
||||
|
||||
func scanInstanceDomain(ctx context.Context, querier database.Querier, builder *database.StatementBuilder) (*domain.InstanceDomain, error) {
|
||||
rows, err := querier.Query(ctx, builder.String(), builder.Args()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
instanceDomain := &domain.InstanceDomain{}
|
||||
if err := rows.(database.CollectableRows).CollectExactlyOneRow(instanceDomain); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return instanceDomain, nil
|
||||
}
|
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
)
|
||||
@@ -73,44 +71,9 @@ func (o *org) Create(ctx context.Context, organization *domain.Organization) err
|
||||
builder.AppendArgs(organization.ID, organization.Name, organization.InstanceID, organization.State)
|
||||
builder.WriteString(createOrganizationStmt)
|
||||
|
||||
err := o.client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(&organization.CreatedAt, &organization.UpdatedAt)
|
||||
if err != nil {
|
||||
return checkCreateOrgErr(err)
|
||||
}
|
||||
return nil
|
||||
return o.client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(&organization.CreatedAt, &organization.UpdatedAt)
|
||||
}
|
||||
|
||||
func checkCreateOrgErr(err error) error {
|
||||
var pgErr *pgconn.PgError
|
||||
if !errors.As(err, &pgErr) {
|
||||
return err
|
||||
}
|
||||
// constraint violation
|
||||
if pgErr.Code == "23514" {
|
||||
if pgErr.ConstraintName == "organizations_name_check" {
|
||||
return errors.New("organization name not provided")
|
||||
}
|
||||
if pgErr.ConstraintName == "organizations_id_check" {
|
||||
return errors.New("organization id not provided")
|
||||
}
|
||||
}
|
||||
// duplicate
|
||||
if pgErr.Code == "23505" {
|
||||
if pgErr.ConstraintName == "organizations_pkey" {
|
||||
return errors.New("organization id already exists")
|
||||
}
|
||||
if pgErr.ConstraintName == "org_unique_instance_id_name_idx" {
|
||||
return errors.New("organization name already exists for instance")
|
||||
}
|
||||
}
|
||||
// invalid instance id
|
||||
if pgErr.Code == "23503" {
|
||||
if pgErr.ConstraintName == "organizations_instance_id_fkey" {
|
||||
return errors.New("invalid instance id")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Update implements [domain.OrganizationRepository].
|
||||
func (o *org) Update(ctx context.Context, id domain.OrgIdentifierCondition, instanceID string, changes ...database.Change) (int64, error) {
|
||||
|
@@ -14,10 +14,45 @@ type orgDomain struct {
|
||||
*org
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// repository
|
||||
// -------------------------------------------------------------
|
||||
|
||||
const queryOrganizationDomainStmt = `SELECT instance_id, org_id, domain, is_verified, is_primary, verification_type, created_at, updated_at ` +
|
||||
`FROM zitadel.organization_domains`
|
||||
|
||||
// Get implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).Get of orgDomain.org.
|
||||
func (o *orgDomain) Get(ctx context.Context, opts ...database.QueryOption) (*domain.OrganizationDomain, error) {
|
||||
options := new(database.QueryOpts)
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
var builder database.StatementBuilder
|
||||
builder.WriteString(queryOrganizationDomainStmt)
|
||||
options.Write(&builder)
|
||||
|
||||
return scanOrganizationDomain(ctx, o.client, &builder)
|
||||
}
|
||||
|
||||
// List implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).List of orgDomain.org.
|
||||
func (o *orgDomain) List(ctx context.Context, opts ...database.QueryOption) ([]*domain.OrganizationDomain, error) {
|
||||
options := new(database.QueryOpts)
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
var builder database.StatementBuilder
|
||||
builder.WriteString(queryOrganizationDomainStmt)
|
||||
options.Write(&builder)
|
||||
|
||||
return scanOrganizationDomains(ctx, o.client, &builder)
|
||||
}
|
||||
|
||||
// Add implements [domain.OrganizationDomainRepository].
|
||||
func (o *orgDomain) Add(ctx context.Context, domain *domain.AddOrganizationDomain) error {
|
||||
var builder database.StatementBuilder
|
||||
@@ -32,7 +67,7 @@ func (o *orgDomain) Add(ctx context.Context, domain *domain.AddOrganizationDomai
|
||||
}
|
||||
|
||||
// Update implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method (*org).Update of orgDomain.org.
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).Update of orgDomain.org.
|
||||
func (o *orgDomain) Update(ctx context.Context, condition database.Condition, changes ...database.Change) (int64, error) {
|
||||
var builder database.StatementBuilder
|
||||
|
||||
@@ -83,7 +118,7 @@ func (o orgDomain) DomainCondition(op database.TextOperation, domain string) dat
|
||||
}
|
||||
|
||||
// InstanceIDCondition implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method (*org).InstanceIDCondition of orgDomain.org.
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).InstanceIDCondition of orgDomain.org.
|
||||
func (o orgDomain) InstanceIDCondition(instanceID string) database.Condition {
|
||||
return database.NewTextCondition(o.InstanceIDColumn(), database.TextOperationEqual, instanceID)
|
||||
}
|
||||
@@ -108,7 +143,7 @@ func (o orgDomain) OrgIDCondition(orgID string) database.Condition {
|
||||
// -------------------------------------------------------------
|
||||
|
||||
// CreatedAtColumn implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method (*org).CreatedAtColumn of orgDomain.org.
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).CreatedAtColumn of orgDomain.org.
|
||||
func (orgDomain) CreatedAtColumn() database.Column {
|
||||
return database.NewColumn("created_at")
|
||||
}
|
||||
@@ -119,7 +154,7 @@ func (orgDomain) DomainColumn() database.Column {
|
||||
}
|
||||
|
||||
// InstanceIDColumn implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method (*org).InstanceIDColumn of orgDomain.org.
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).InstanceIDColumn of orgDomain.org.
|
||||
func (orgDomain) InstanceIDColumn() database.Column {
|
||||
return database.NewColumn("instance_id")
|
||||
}
|
||||
@@ -140,7 +175,7 @@ func (orgDomain) OrgIDColumn() database.Column {
|
||||
}
|
||||
|
||||
// UpdatedAtColumn implements [domain.OrganizationDomainRepository].
|
||||
// Subtle: this method shadows the method (*org).UpdatedAtColumn of orgDomain.org.
|
||||
// Subtle: this method shadows the method ([domain.OrganizationRepository]).UpdatedAtColumn of orgDomain.org.
|
||||
func (orgDomain) UpdatedAtColumn() database.Column {
|
||||
return database.NewColumn("updated_at")
|
||||
}
|
||||
@@ -153,3 +188,29 @@ func (orgDomain) VerificationTypeColumn() database.Column {
|
||||
// -------------------------------------------------------------
|
||||
// scanners
|
||||
// -------------------------------------------------------------
|
||||
|
||||
func scanOrganizationDomain(ctx context.Context, client database.Querier, builder *database.StatementBuilder) (*domain.OrganizationDomain, error) {
|
||||
rows, err := client.Query(ctx, builder.String(), builder.Args()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
organizationDomain := &domain.OrganizationDomain{}
|
||||
if err := rows.(database.CollectableRows).CollectExactlyOneRow(organizationDomain); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return organizationDomain, nil
|
||||
}
|
||||
|
||||
func scanOrganizationDomains(ctx context.Context, client database.Querier, builder *database.StatementBuilder) ([]*domain.OrganizationDomain, error) {
|
||||
rows, err := client.Query(ctx, builder.String(), builder.Args()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var organizationDomains []*domain.OrganizationDomain
|
||||
if err := rows.(database.CollectableRows).Collect(&organizationDomains); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return organizationDomains, nil
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ func (b *StatementBuilder) WriteArg(arg any) {
|
||||
b.WriteString(b.AppendArg(arg))
|
||||
}
|
||||
|
||||
// AppebdArg adds the argument to the statement and returns the placeholder.
|
||||
// AppendArg adds the argument to the statement and returns the placeholder.
|
||||
func (b *StatementBuilder) AppendArg(arg any) (placeholder string) {
|
||||
if b.existingArgs == nil {
|
||||
b.existingArgs = make(map[any]string)
|
||||
|
Reference in New Issue
Block a user