Skip to content

Commit

Permalink
fix: clean up database metadata (#1115)
Browse files Browse the repository at this point in the history
we're still not extracting database calls in either runtime, but this
fixes the metadata type
  • Loading branch information
worstell authored Mar 21, 2024
1 parent 80b91c3 commit 3efd221
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 245 deletions.
352 changes: 176 additions & 176 deletions backend/protos/xyz/block/ftl/v1/schema/schema.pb.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/protos/xyz/block/ftl/v1/schema/schema.proto
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ message MetadataCalls {

message MetadataDatabases {
optional Position pos = 1;
repeated Database calls = 2;
repeated Ref calls = 2;
}

message MetadataIngress {
Expand Down
8 changes: 0 additions & 8 deletions backend/schema/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,3 @@ func DatabaseFromProto(s *schemapb.Database) *Database {
Comments: s.Comments,
}
}

func databaseListToSchema(s []*schemapb.Database) []*Database {
var out []*Database
for _, n := range s {
out = append(out, DatabaseFromProto(n))
}
return out
}
6 changes: 3 additions & 3 deletions backend/schema/metadatadatabases.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
type MetadataDatabases struct {
Pos Position `parser:"" protobuf:"1,optional"`

Calls []*Database `parser:"'+' 'database' 'calls' @@ (',' @@)*" protobuf:"2"`
Calls []*Ref `parser:"'+' 'database' 'calls' @@ (',' @@)*" protobuf:"2"`
}

var _ Metadata = (*MetadataDatabases)(nil)
Expand All @@ -35,7 +35,7 @@ func (m *MetadataDatabases) String() string {
w += len(str)
fmt.Fprint(out, str)
}
fmt.Fprintln(out)
fmt.Fprint(out)
return out.String()
}

Expand All @@ -51,6 +51,6 @@ func (*MetadataDatabases) schemaMetadata() {}
func (m *MetadataDatabases) ToProto() proto.Message {
return &schemapb.MetadataDatabases{
Pos: posToProto(m.Pos),
Calls: nodeListToProto[*schemapb.Database](m.Calls),
Calls: nodeListToProto[*schemapb.Ref](m.Calls),
}
}
2 changes: 1 addition & 1 deletion backend/schema/protobuf_dec.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func metadataToSchema(s *schemapb.Metadata) Metadata {
case *schemapb.Metadata_Databases:
return &MetadataDatabases{
Pos: posFromProto(s.Databases.Pos),
Calls: databaseListToSchema(s.Databases.Calls),
Calls: refListToSchema(s.Databases.Calls),
}

case *schemapb.Metadata_Ingress:
Expand Down
26 changes: 19 additions & 7 deletions backend/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ func TestSchemaString(t *testing.T) {
module todo {
config configValue String
secret secretValue String
database testdb
data CreateRequest {
name {String: String}? +alias json "rqn"
}
Expand All @@ -39,10 +43,8 @@ module todo {
when Time
}
secret secretValue String
verb create(todo.CreateRequest) todo.CreateResponse
+calls todo.destroy
+calls todo.destroy +database calls todo.testdb
verb destroy(builtin.HttpRequest<todo.DestroyRequest>) builtin.HttpResponse<todo.DestroyResponse, String>
+ingress http GET /todo/destroy/{id}
Expand Down Expand Up @@ -95,6 +97,9 @@ func TestVisit(t *testing.T) {
Module
Config
String
Secret
String
Database
Data
Field
Optional
Expand All @@ -115,13 +120,13 @@ Module
String
Field
Time
Secret
String
Verb
Ref
Ref
MetadataCalls
Ref
MetadataDatabases
Ref
Verb
Ref
Ref
Expand Down Expand Up @@ -365,6 +370,7 @@ func TestParseModule(t *testing.T) {
module todo {
config configValue String
secret secretValue String
database testdb
data CreateRequest {
name {String: String}? +alias json "rqn"
Expand All @@ -381,7 +387,7 @@ module todo {
when Time
}
verb create(todo.CreateRequest) todo.CreateResponse
+calls todo.destroy
+calls todo.destroy +database calls todo.testdb
verb destroy(builtin.HttpRequest<todo.DestroyRequest>) builtin.HttpResponse<todo.DestroyResponse, String>
+ingress http GET /todo/destroy/{id}
}
Expand Down Expand Up @@ -429,6 +435,9 @@ var testSchema = MustValidate(&Schema{
Name: "configValue",
Type: &String{},
},
&Database{
Name: "testdb",
},
&Data{
Name: "CreateRequest",
Fields: []*Field{
Expand Down Expand Up @@ -457,7 +466,10 @@ var testSchema = MustValidate(&Schema{
&Verb{Name: "create",
Request: &Ref{Module: "todo", Name: "CreateRequest"},
Response: &Ref{Module: "todo", Name: "CreateResponse"},
Metadata: []Metadata{&MetadataCalls{Calls: []*Ref{{Module: "todo", Name: "destroy"}}}}},
Metadata: []Metadata{
&MetadataCalls{Calls: []*Ref{{Module: "todo", Name: "destroy"}}},
&MetadataDatabases{Calls: []*Ref{{Module: "todo", Name: "testdb"}}},
}},
&Verb{Name: "destroy",
Request: &Ref{Module: "builtin", Name: "HttpRequest", TypeParameters: []Type{&Ref{Module: "todo", Name: "DestroyRequest"}}},
Response: &Ref{Module: "builtin", Name: "HttpResponse", TypeParameters: []Type{&Ref{Module: "todo", Name: "DestroyResponse"}, &String{}}},
Expand Down
39 changes: 30 additions & 9 deletions backend/schema/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func Validate(schema *Schema) (*Schema, error) {
case *Ref:
if mdecl := scopes.Resolve(*n); mdecl != nil {
switch decl := mdecl.Symbol.(type) {
case *Verb, *Enum:
case *Verb, *Enum, *Database, *Config, *Secret:
if mdecl.Module != nil {
n.Module = mdecl.Module.Name
}
Expand All @@ -121,7 +121,6 @@ func Validate(schema *Schema) (*Schema, error) {
case *TypeParameter:
default:
merr = append(merr, fmt.Errorf("%s: invalid reference %q at %q", n.Pos, n, mdecl.Symbol.Position()))

}
} else {
merr = append(merr, fmt.Errorf("%s: unknown reference %q", n.Pos, n))
Expand Down Expand Up @@ -209,8 +208,10 @@ func ValidateModule(module *Module) error {
case *Ref:
if mdecl := scopes.Resolve(*n); mdecl != nil {
switch decl := mdecl.Symbol.(type) {
case *Verb, *Enum:
n.Module = mdecl.Module.Name
case *Verb, *Enum, *Database, *Config, *Secret:
if n.Module == "" {
n.Module = mdecl.Module.Name
}
if len(n.TypeParameters) != 0 {
merr = append(merr, fmt.Errorf("%s: reference to %s %q cannot have type parameters",
n.Pos, reflect.TypeOf(decl).Elem().Name(), n.Name))
Expand All @@ -224,7 +225,6 @@ func ValidateModule(module *Module) error {
n.Pos, n.Name, len(n.TypeParameters), len(decl.TypeParameters)))
}
case *TypeParameter:

default:
if n.Module == "" {
merr = append(merr, fmt.Errorf("%s: unqualified reference to invalid %s %q", n.Pos, reflect.TypeOf(decl).Elem().Name(), n))
Expand Down Expand Up @@ -293,16 +293,37 @@ func ValidateModule(module *Module) error {
sort.SliceStable(module.Decls, func(i, j int) bool {
iDecl := module.Decls[i]
jDecl := module.Decls[j]
iType := reflect.TypeOf(iDecl).String()
jType := reflect.TypeOf(jDecl).String()
if iType == jType {
iPriority := getDeclSortingPriority(iDecl)
jPriority := getDeclSortingPriority(jDecl)
if iPriority == jPriority {
return iDecl.GetName() < jDecl.GetName()
}
return iType < jType
return iPriority < jPriority
})
return errors.Join(merr...)
}

// getDeclSortingPriority (used for schema sorting) is pulled out into it's own switch so the Go sumtype check will fail
// if a new Decl is added but not explicitly prioritized
func getDeclSortingPriority(decl Decl) int {
priority := 0
switch decl.(type) {
case *Config:
priority = 1
case *Secret:
priority = 2
case *Database:
priority = 3
case *Enum:
priority = 4
case *Data:
priority = 5
case *Verb:
priority = 6
}
return priority
}

// Sort and de-duplicate errors.
func cleanErrors(merr []error) []error {
if len(merr) == 0 {
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 37 additions & 37 deletions go-runtime/compile/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,36 +45,7 @@ func TestExtractModuleSchema(t *testing.T) {
expected := `module one {
config configValue one.Config
data Config {
field String
}
data Nested {
}
data Req {
int Int
int64 Int
float Float
string String
slice [String]
map {String: String}
nested one.Nested
optional one.Nested?
time Time
user two.User +alias json "u"
bytes Bytes
enumRef two.TwoEnum
}
data Resp {
}
data SinkReq {
}
data SourceResp {
}
secret secretValue String
enum Color(String) {
Red("Red")
Expand Down Expand Up @@ -105,7 +76,36 @@ func TestExtractModuleSchema(t *testing.T) {
Two(2)
}
secret secretValue String
data Config {
field String
}
data Nested {
}
data Req {
int Int
int64 Int
float Float
string String
slice [String]
map {String: String}
nested one.Nested
optional one.Nested?
time Time
user two.User +alias json "u"
bytes Bytes
enumRef two.TwoEnum
}
data Resp {
}
data SinkReq {
}
data SourceResp {
}
verb nothing(Unit) Unit
Expand All @@ -124,6 +124,12 @@ func TestExtractModuleSchemaTwo(t *testing.T) {
assert.NoError(t, err)
actual = schema.Normalise(actual)
expected := `module two {
enum TwoEnum(String) {
Red("Red")
Blue("Blue")
Green("Green")
}
data Payload<T> {
body T
}
Expand All @@ -136,12 +142,6 @@ func TestExtractModuleSchemaTwo(t *testing.T) {
user two.User
}
enum TwoEnum(String) {
Red("Red")
Blue("Blue")
Green("Green")
}
verb callsTwo(two.Payload<String>) two.Payload<String>
+calls two.two
Expand Down
Binary file added kotlin-runtime/ftl-runtime/schema.pb
Binary file not shown.

0 comments on commit 3efd221

Please sign in to comment.