uuidmapping

package
v0.10.0-alpha.0 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2022 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RelationTupleTableName     = "keto_relation_tuples"
	RelationTupleUUIDTableName = "keto_relation_tuples_uuid"
	UUIDMappingTableName       = "keto_uuid_mappings"
	MigrationVersion           = "20220513200500000000"
)

Variables

View Source
var (
	Migrations = func(namespaces namespace.Manager) popx.Migrations {
		return popx.Migrations{

			{
				Version:   MigrationVersion,
				Name:      name,
				Path:      name,
				Direction: "up",
				DBType:    "all",
				Type:      "go",
				Runner: func(_ popx.Migration, conn *pop.Connection, _ *pop.Tx) error {
					var (
						relationTuples []OldRelationTuple
						err            error
						lastID         uuid.UUID
					)
					for {
						relationTuples, err = GetRelationTuples[OldRelationTuple](conn, lastID)
						if err != nil {
							return fmt.Errorf("could not get old relation tuples: %w", err)
						}
						if len(relationTuples) == 0 {
							break
						}
						lastID = relationTuples[len(relationTuples)-1].ID

						mappings := make([]*UUIDMapping, len(relationTuples)*2)
						newTuples := make([]*NewRelationTuple, len(relationTuples))
						for i := range relationTuples {
							err, newTuples[i], mappings[i*2], mappings[i*2+1] = relationTuples[i].ToNew(namespaces)
							if err != nil {
								return errors.WithStack(err)
							}
						}

						if err := BatchWriteMappings(conn, mappings); err != nil {
							return fmt.Errorf("could not write mappings: %w", err)
						}
						if err := BatchInsertTuples(conn, newTuples); err != nil {
							return fmt.Errorf("could not insert new tuples: %w", err)
						}
					}

					return nil
				},
			},

			{
				Version:   MigrationVersion,
				Name:      name,
				Path:      name,
				Direction: "down",
				DBType:    "all",
				Type:      "go",
				Runner: func(_ popx.Migration, conn *pop.Connection, _ *pop.Tx) error {
					var (
						relationTuples []NewRelationTuple
						err            error
						lastID         uuid.UUID
					)
					for {
						relationTuples, err = GetRelationTuples[NewRelationTuple](conn, lastID)
						if err != nil {
							return fmt.Errorf("could not get new relation tuples: %w", err)
						}
						if len(relationTuples) == 0 {
							break
						}
						lastID = relationTuples[len(relationTuples)-1].ID

						mappings := make(map[uuid.UUID][]*string, len(relationTuples)*2)
						oldTuples := make([]*OldRelationTuple, len(relationTuples))
						ctx := context.Background()
						for i, rt := range relationTuples {
							ot := &OldRelationTuple{
								ID:        rt.ID,
								NetworkID: rt.NetworkID,
								Relation:  rt.Relation,
								SubjectID: sql.NullString{
									Valid: rt.SubjectID.Valid,
								},
								SubjectSetObject: sql.NullString{
									Valid: rt.SubjectSetObject.Valid,
								},
								SubjectSetRelation: rt.SubjectSetRelation,
								CommitTime:         rt.CommitTime,
							}

							namespace, err := namespaces.GetNamespaceByName(ctx, rt.Namespace)
							if err != nil {
								return fmt.Errorf("could not get namespace: %w", err)
							}
							ot.NamespaceID = namespace.ID

							if rt.SubjectSetNamespace.Valid {
								subjectSetNamespace, err := namespaces.GetNamespaceByName(ctx, rt.SubjectSetNamespace.String)
								if err != nil {
									return fmt.Errorf("could not get subject namespace: %w", err)
								}
								if err = ot.SubjectSetNamespaceID.Scan(subjectSetNamespace.ID); err != nil {
									return err
								}
							}

							mappings[rt.Object] = append(mappings[rt.Object], &ot.Object)
							switch {
							case rt.SubjectID.Valid:
								mappings[rt.SubjectID.UUID] = append(mappings[rt.SubjectID.UUID], &ot.SubjectID.String)
							case rt.SubjectSetObject.Valid:
								mappings[rt.SubjectSetObject.UUID] = append(mappings[rt.SubjectSetObject.UUID], &ot.SubjectSetObject.String)
							}
							oldTuples[i] = ot
						}
						if err := BatchReplaceUUIDs(conn, mappings); err != nil {
							return fmt.Errorf("could not replace UUIDs: %w", err)
						}

						if err := BatchInsertTuples(conn, oldTuples); err != nil {
							return fmt.Errorf("could not insert old tuples: %w", err)
						}
					}

					return nil
				},
			},
		}
	}
)

Functions

func BatchInsertTuples

func BatchInsertTuples[RT interface {
	pop.TableNameAble
	ColumnProvider
	ColumnNameAble
}](conn *pop.Connection, rts []RT) error

func BatchReplaceUUIDs

func BatchReplaceUUIDs(conn *pop.Connection, uuidToTargets map[uuid.UUID][]*string) error

func BatchWriteMappings

func BatchWriteMappings(conn *pop.Connection, mappings []*UUIDMapping) (err error)

func ConstructArgs

func ConstructArgs[T ColumnProvider](nCols int, items []T) (string, []interface{})

func GetRelationTuples

func GetRelationTuples[RT interface {
	ColumnNameAble
	pop.TableNameAble
}](conn *pop.Connection, lastID uuid.UUID) (
	res []RT, err error,
)

Types

type ColumnNameAble

type ColumnNameAble interface {
	// contains filtered or unexported methods
}

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

type ColumnProvider

type ColumnProvider interface {
	// contains filtered or unexported methods
}

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

type NewRelationTuple

type NewRelationTuple struct {
	ID                  uuid.UUID      `db:"shard_id"`
	NetworkID           uuid.UUID      `db:"nid"`
	Namespace           string         `db:"namespace"`
	Object              uuid.UUID      `db:"object"`
	Relation            string         `db:"relation"`
	SubjectID           uuid.NullUUID  `db:"subject_id"`
	SubjectSetNamespace sql.NullString `db:"subject_set_namespace"`
	SubjectSetObject    uuid.NullUUID  `db:"subject_set_object"`
	SubjectSetRelation  sql.NullString `db:"subject_set_relation"`
	CommitTime          time.Time      `db:"commit_time"`
}

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

func (NewRelationTuple) TableName

func (NewRelationTuple) TableName() string

type OldRelationTuple

type OldRelationTuple struct {
	// An ID field is required to make pop happy. The actual ID is a
	// composite primary key.
	ID                    uuid.UUID      `db:"shard_id"`
	NetworkID             uuid.UUID      `db:"nid"`
	NamespaceID           int32          `db:"namespace_id"`
	Object                string         `db:"object"`
	Relation              string         `db:"relation"`
	SubjectID             sql.NullString `db:"subject_id"`
	SubjectSetNamespaceID sql.NullInt32  `db:"subject_set_namespace_id"`
	SubjectSetObject      sql.NullString `db:"subject_set_object"`
	SubjectSetRelation    sql.NullString `db:"subject_set_relation"`
	CommitTime            time.Time      `db:"commit_time"`
}

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

func (OldRelationTuple) TableName

func (OldRelationTuple) TableName() string

func (*OldRelationTuple) ToNew

func (rt *OldRelationTuple) ToNew(n namespace.Manager) (err error, newRT *NewRelationTuple, objectMapping *UUIDMapping, subjectMapping *UUIDMapping)

func (*OldRelationTuple) ToUUID

func (rt *OldRelationTuple) ToUUID(s string) uuid.UUID

type UUIDMapping

type UUIDMapping struct {
	ID                   uuid.UUID `db:"id"`
	StringRepresentation string    `db:"string_representation"`
}

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

func (UUIDMapping) TableName

func (UUIDMapping) TableName() string

type UUIDMappings

type UUIDMappings []*UUIDMapping

We copy the definitions of OldRelationTuple and UUIDMapping here so that the migration will always work on the same definitions.

func (UUIDMappings) TableName

func (UUIDMappings) TableName() string

Jump to

Keyboard shortcuts

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