Skip to content

Commit

Permalink
chore: finish joins
Browse files Browse the repository at this point in the history
  • Loading branch information
markphelps committed Jan 31, 2023
1 parent 7797e39 commit bd84114
Show file tree
Hide file tree
Showing 5 changed files with 329 additions and 224 deletions.
58 changes: 34 additions & 24 deletions internal/storage/sql/common/evaluation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ import (
flipt "go.flipt.io/flipt/rpc/flipt"
)

type optionalConstraint struct {
ID sql.NullString
Type sql.NullInt64
Property sql.NullString
Operator sql.NullString
Value sql.NullString
}

func (s *Store) GetEvaluationRules(ctx context.Context, flagKey string) ([]*storage.EvaluationRule, error) {
// get all rules for flag with their constraints if any
rows, err := s.builder.Select("r.id, r.flag_key, r.segment_key, s.match_type, r.\"rank\", c.id, c.type, c.property, c.operator, c.value").
Expand All @@ -38,8 +30,8 @@ func (s *Store) GetEvaluationRules(ctx context.Context, flagKey string) ([]*stor
}()

var (
seenRules = make(map[string]*storage.EvaluationRule)
rules = []*storage.EvaluationRule{}
uniqueRules = make(map[string]*storage.EvaluationRule)
rules = []*storage.EvaluationRule{}
)

for rows.Next() {
Expand All @@ -48,16 +40,26 @@ func (s *Store) GetEvaluationRules(ctx context.Context, flagKey string) ([]*stor
optionalConstraint optionalConstraint
)

if err := rows.Scan(&tempRule.ID, &tempRule.FlagKey, &tempRule.SegmentKey, &tempRule.SegmentMatchType, &tempRule.Rank, &optionalConstraint.ID, &optionalConstraint.Type, &optionalConstraint.Property, &optionalConstraint.Operator, &optionalConstraint.Value); err != nil {
return nil, err
if err := rows.Scan(
&tempRule.ID,
&tempRule.FlagKey,
&tempRule.SegmentKey,
&tempRule.SegmentMatchType,
&tempRule.Rank,
&optionalConstraint.Id,
&optionalConstraint.Type,
&optionalConstraint.Property,
&optionalConstraint.Operator,
&optionalConstraint.Value); err != nil {
return rules, err
}

if existingRule, ok := seenRules[tempRule.ID]; ok {
if existingRule, ok := uniqueRules[tempRule.ID]; ok {
// current rule we know about
if optionalConstraint.ID.Valid {
if optionalConstraint.Id.Valid {
constraint := storage.EvaluationConstraint{
ID: optionalConstraint.ID.String,
Type: flipt.ComparisonType(optionalConstraint.Type.Int64),
ID: optionalConstraint.Id.String,
Type: flipt.ComparisonType(optionalConstraint.Type.Int32),
Property: optionalConstraint.Property.String,
Operator: optionalConstraint.Operator.String,
Value: optionalConstraint.Value.String,
Expand All @@ -74,24 +76,28 @@ func (s *Store) GetEvaluationRules(ctx context.Context, flagKey string) ([]*stor
Rank: tempRule.Rank,
}

if optionalConstraint.ID.Valid {
if optionalConstraint.Id.Valid {
constraint := storage.EvaluationConstraint{
ID: optionalConstraint.ID.String,
Type: flipt.ComparisonType(optionalConstraint.Type.Int64),
ID: optionalConstraint.Id.String,
Type: flipt.ComparisonType(optionalConstraint.Type.Int32),
Property: optionalConstraint.Property.String,
Operator: optionalConstraint.Operator.String,
Value: optionalConstraint.Value.String,
}
newRule.Constraints = append(newRule.Constraints, constraint)
}

seenRules[newRule.ID] = newRule
uniqueRules[newRule.ID] = newRule
rules = append(rules, newRule)
}
}

if err := rows.Err(); err != nil {
return nil, err
return rules, err
}

if err := rows.Close(); err != nil {
return rules, err
}

return rules, nil
Expand Down Expand Up @@ -125,13 +131,13 @@ func (s *Store) GetEvaluationDistributions(ctx context.Context, ruleID string) (
if err := rows.Scan(
&d.ID, &d.RuleID, &d.VariantID, &d.Rollout, &d.VariantKey, &attachment,
); err != nil {
return nil, err
return distributions, err
}

if attachment.Valid {
attachmentString, err := compactJSONString(attachment.String)
if err != nil {
return nil, err
return distributions, err
}
d.VariantAttachment = attachmentString
}
Expand All @@ -140,7 +146,11 @@ func (s *Store) GetEvaluationDistributions(ctx context.Context, ruleID string) (
}

if err := rows.Err(); err != nil {
return nil, err
return distributions, err
}

if err := rows.Close(); err != nil {
return distributions, err
}

return distributions, nil
Expand Down
140 changes: 66 additions & 74 deletions internal/storage/sql/common/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,17 @@ func emptyAsNil(str string) *string {
return &str
}

// GetFlag gets a flag
// GetFlag gets a flag with variants by key
func (s *Store) GetFlag(ctx context.Context, key string) (*flipt.Flag, error) {
var (
createdAt fliptsql.Timestamp
updatedAt fliptsql.Timestamp

flag = &flipt.Flag{}

query = s.builder.Select("\"key\", name, description, enabled, created_at, updated_at").
err = s.builder.Select("\"key\", name, description, enabled, created_at, updated_at").
From("flags").
Where(sq.Eq{"\"key\"": key})

err = query.QueryRowContext(ctx).Scan(
Where(sq.Eq{"\"key\"": key}).QueryRowContext(ctx).Scan(
&flag.Key,
&flag.Name,
&flag.Description,
Expand All @@ -65,14 +63,58 @@ func (s *Store) GetFlag(ctx context.Context, key string) (*flipt.Flag, error) {
flag.CreatedAt = createdAt.Timestamp
flag.UpdatedAt = updatedAt.Timestamp

if err := s.variants(ctx, flag); err != nil {
return nil, err
query := s.builder.Select("id, flag_key, \"key\", name, description, attachment, created_at, updated_at").
From("variants").
Where(sq.Eq{"flag_key": flag.Key}).
OrderBy("created_at ASC")

rows, err := query.QueryContext(ctx)
if err != nil {
return flag, err
}

return flag, nil
defer func() {
if cerr := rows.Close(); cerr != nil && err == nil {
err = cerr
}
}()

for rows.Next() {
var (
variant flipt.Variant
createdAt, updatedAt fliptsql.Timestamp
attachment sql.NullString
)

if err := rows.Scan(
&variant.Id,
&variant.FlagKey,
&variant.Key,
&variant.Name,
&variant.Description,
&attachment,
&createdAt,
&updatedAt); err != nil {
return flag, err
}

variant.CreatedAt = createdAt.Timestamp
variant.UpdatedAt = updatedAt.Timestamp
if attachment.Valid {
compactedAttachment, err := compactJSONString(attachment.String)
if err != nil {
return flag, err
}
variant.Attachment = compactedAttachment
}

flag.Variants = append(flag.Variants, &variant)
}

return flag, rows.Err()
}

type variantRow struct {
type optionalVariant struct {
Id sql.NullString
Key sql.NullString
FlagKey sql.NullString
Expand All @@ -83,7 +125,7 @@ type variantRow struct {
UpdatedAt fliptsql.NullableTimestamp
}

// ListFlags lists all flags
// ListFlags lists all flags with variants
func (s *Store) ListFlags(ctx context.Context, opts ...storage.QueryOption) (storage.ResultSet[*flipt.Flag], error) {
params := &storage.QueryParams{}

Expand All @@ -109,9 +151,11 @@ func (s *Store) ListFlags(ctx context.Context, opts ...storage.QueryOption) (sto

if params.PageToken != "" {
var token PageToken

if err := json.Unmarshal([]byte(params.PageToken), &token); err != nil {
return results, fmt.Errorf("decoding page token %w", err)
}

offset = token.Offset
query = query.Offset(offset)
} else if params.Offset > 0 {
Expand All @@ -135,18 +179,18 @@ func (s *Store) ListFlags(ctx context.Context, opts ...storage.QueryOption) (sto

for rows.Next() {
var (
f = &flipt.Flag{}
v = &variantRow{}
flag = &flipt.Flag{}
v = &optionalVariant{}

fCreatedAt fliptsql.Timestamp
fUpdatedAt fliptsql.Timestamp
)

if err := rows.Scan(
&f.Key,
&f.Name,
&f.Description,
&f.Enabled,
&flag.Key,
&flag.Name,
&flag.Description,
&flag.Enabled,
&fCreatedAt,
&fUpdatedAt,
&v.Id,
Expand All @@ -160,12 +204,12 @@ func (s *Store) ListFlags(ctx context.Context, opts ...storage.QueryOption) (sto
return results, err
}

f.CreatedAt = fCreatedAt.Timestamp
f.UpdatedAt = fUpdatedAt.Timestamp
flag.CreatedAt = fCreatedAt.Timestamp
flag.UpdatedAt = fUpdatedAt.Timestamp

// append flag to output results if we haven't seen it yet
if _, ok := uniqueFlags[f.Key]; !ok {
flags = append(flags, f)
// append flag to output results if we haven't seen it yet, to maintain order
if _, ok := uniqueFlags[flag.Key]; !ok {
flags = append(flags, flag)
}

// append variant to flag if it exists (not null)
Expand Down Expand Up @@ -199,7 +243,7 @@ func (s *Store) ListFlags(ctx context.Context, opts ...storage.QueryOption) (sto
variant.UpdatedAt = v.UpdatedAt.Timestamp
}

uniqueFlags[f.Key] = append(uniqueFlags[f.Key], variant)
uniqueFlags[flag.Key] = append(uniqueFlags[flag.Key], variant)
}
}

Expand Down Expand Up @@ -418,55 +462,3 @@ func (s *Store) DeleteVariant(ctx context.Context, r *flipt.DeleteVariantRequest

return err
}

func (s *Store) variants(ctx context.Context, flag *flipt.Flag) (err error) {
query := s.builder.Select("id, flag_key, \"key\", name, description, attachment, created_at, updated_at").
From("variants").
Where(sq.Eq{"flag_key": flag.Key}).
OrderBy("created_at ASC")

rows, err := query.QueryContext(ctx)
if err != nil {
return err
}

defer func() {
if cerr := rows.Close(); cerr != nil && err == nil {
err = cerr
}
}()

for rows.Next() {
var (
variant flipt.Variant
createdAt, updatedAt fliptsql.Timestamp
attachment sql.NullString
)

if err := rows.Scan(
&variant.Id,
&variant.FlagKey,
&variant.Key,
&variant.Name,
&variant.Description,
&attachment,
&createdAt,
&updatedAt); err != nil {
return err
}

variant.CreatedAt = createdAt.Timestamp
variant.UpdatedAt = updatedAt.Timestamp
if attachment.Valid {
compactedAttachment, err := compactJSONString(attachment.String)
if err != nil {
return err
}
variant.Attachment = compactedAttachment
}

flag.Variants = append(flag.Variants, &variant)
}

return rows.Err()
}
Loading

0 comments on commit bd84114

Please sign in to comment.