Skip to content

Commit ed61da7

Browse files
authored
feat: extract databases in Kotlin schema (#762)
<img width="685" alt="Screenshot 2024-01-11 at 8 56 38 PM" src="https://github.com/TBD54566975/ftl/assets/72891690/4eb8fcaf-6b43-4ab4-806e-67e27ab0682a">
1 parent 422d68a commit ed61da7

File tree

17 files changed

+995
-326
lines changed

17 files changed

+995
-326
lines changed

backend/schema/database.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package schema
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"google.golang.org/protobuf/proto"
8+
9+
schemapb "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/schema"
10+
)
11+
12+
type Database struct {
13+
Pos Position `parser:"" protobuf:"1,optional"`
14+
15+
Comments []string `parser:"@Comment*" protobuf:"3"`
16+
Name string `parser:"'database' @Ident" protobuf:"2"`
17+
}
18+
19+
var _ Decl = (*Database)(nil)
20+
21+
// schemaDecl implements Decl
22+
func (*Database) schemaDecl() {}
23+
func (d *Database) schemaChildren() []Node { return nil }
24+
func (d *Database) String() string {
25+
w := &strings.Builder{}
26+
fmt.Fprint(w, encodeComments(d.Comments))
27+
fmt.Fprintf(w, "database %s", d.Name)
28+
return w.String()
29+
}
30+
31+
func (d *Database) ToProto() proto.Message {
32+
return &schemapb.Database{
33+
Pos: posToProto(d.Pos),
34+
Name: d.Name,
35+
Comments: d.Comments,
36+
}
37+
}
38+
func DatabaseToSchema(s *schemapb.Database) *Database {
39+
return &Database{
40+
Pos: posFromProto(s.Pos),
41+
Name: s.Name,
42+
Comments: s.Comments,
43+
}
44+
}
45+
46+
func databaseListToSchema(s []*schemapb.Database) []*Database {
47+
var out []*Database
48+
for _, n := range s {
49+
out = append(out, DatabaseToSchema(n))
50+
}
51+
return out
52+
}

backend/schema/jsonschema.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ func nodeToJSSchema(node Node, dataRefs map[DataRef]bool) *jsonschema.Schema {
126126
{TypeObject: &jsonschema.Schema{Type: &jsonschema.Type{SimpleTypes: &null}}},
127127
}}
128128

129-
case Decl, *Field, Metadata, *MetadataCalls, *MetadataIngress,
129+
case Decl, *Field, Metadata, *MetadataCalls, *MetadataDatabases, *MetadataIngress,
130130
IngressPathComponent, *IngressPathLiteral, *IngressPathParameter, *Module,
131-
*Schema, Type, *Verb, *VerbRef, *SourceRef, *SinkRef:
131+
*Schema, Type, *Database, *Verb, *VerbRef, *SourceRef, *SinkRef:
132132
panic(fmt.Sprintf("unsupported node type %T", node))
133133

134134
default:

backend/schema/metadatadatabases.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package schema
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"google.golang.org/protobuf/proto"
8+
9+
schemapb "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/schema"
10+
)
11+
12+
type MetadataDatabases struct {
13+
Pos Position `parser:"" protobuf:"1,optional"`
14+
15+
Calls []*Database `parser:"'database' 'calls' @@ (',' @@)*" protobuf:"2"`
16+
}
17+
18+
var _ Metadata = (*MetadataDatabases)(nil)
19+
20+
func (m *MetadataDatabases) String() string {
21+
out := &strings.Builder{}
22+
fmt.Fprint(out, "database calls ")
23+
w := 6
24+
for i, call := range m.Calls {
25+
if i > 0 {
26+
fmt.Fprint(out, ", ")
27+
w += 2
28+
}
29+
str := call.String()
30+
if w+len(str) > 70 {
31+
w = 6
32+
fmt.Fprint(out, "\n ")
33+
}
34+
w += len(str)
35+
fmt.Fprint(out, str)
36+
}
37+
fmt.Fprintln(out)
38+
return out.String()
39+
}
40+
41+
func (m *MetadataDatabases) schemaChildren() []Node {
42+
out := make([]Node, 0, len(m.Calls))
43+
for _, ref := range m.Calls {
44+
out = append(out, ref)
45+
}
46+
return out
47+
}
48+
func (*MetadataDatabases) schemaMetadata() {}
49+
50+
func (m *MetadataDatabases) ToProto() proto.Message {
51+
return &schemapb.MetadataDatabases{
52+
Pos: posToProto(m.Pos),
53+
Calls: nodeListToProto[*schemapb.Database](m.Calls),
54+
}
55+
}

backend/schema/normalise.go

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ func Normalise[T Node](n T) T {
3232
c.Fields = normaliseSlice(c.Fields)
3333
c.Metadata = normaliseSlice(c.Metadata)
3434

35+
case *Database:
36+
c.Pos = zero
37+
3538
case *DataRef:
3639
c.Pos = zero
3740

@@ -77,6 +80,10 @@ func Normalise[T Node](n T) T {
7780
c.Pos = zero
7881
c.Calls = normaliseSlice(c.Calls)
7982

83+
case *MetadataDatabases:
84+
c.Pos = zero
85+
c.Calls = normaliseSlice(c.Calls)
86+
8087
case *MetadataIngress:
8188
c.Pos = zero
8289
c.Path = normaliseSlice(c.Path)

backend/schema/parser.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import (
1212
)
1313

1414
var (
15-
declUnion = []Decl{&Data{}, &Verb{}}
15+
declUnion = []Decl{&Data{}, &Verb{}, &Database{}}
1616
nonOptionalTypeUnion = []Type{
1717
&Int{}, &Float{}, &String{}, &Bytes{}, &Bool{}, &Time{}, &Array{},
1818
&Map{}, &DataRef{}, &Unit{},
1919
}
2020
typeUnion = append(nonOptionalTypeUnion, &Optional{})
21-
metadataUnion = []Metadata{&MetadataCalls{}, &MetadataIngress{}}
21+
metadataUnion = []Metadata{&MetadataCalls{}, &MetadataIngress{}, &MetadataDatabases{}}
2222
ingressUnion = []IngressPathComponent{&IngressPathLiteral{}, &IngressPathParameter{}}
2323

2424
// Used by protobuf generation.

backend/schema/protobuf_dec.go

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ func declListToSchema(s []*schemapb.Decl) []Decl {
2525
out = append(out, VerbToSchema(n.Verb))
2626
case *schemapb.Decl_Data:
2727
out = append(out, DataToSchema(n.Data))
28+
case *schemapb.Decl_Database:
29+
out = append(out, DatabaseToSchema(n.Database))
2830
}
2931
}
3032
return out
@@ -74,6 +76,12 @@ func metadataToSchema(s *schemapb.Metadata) Metadata {
7476
Calls: verbRefListToSchema(s.Calls.Calls),
7577
}
7678

79+
case *schemapb.Metadata_Databases:
80+
return &MetadataDatabases{
81+
Pos: posFromProto(s.Databases.Pos),
82+
Calls: databaseListToSchema(s.Databases.Calls),
83+
}
84+
7785
case *schemapb.Metadata_Ingress:
7886
return &MetadataIngress{
7987
Pos: posFromProto(s.Ingress.Pos),

backend/schema/protobuf_enc.go

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ func declListToProto(nodes []Decl) []*schemapb.Decl {
3030
v = &schemapb.Decl_Verb{Verb: n.ToProto().(*schemapb.Verb)}
3131
case *Data:
3232
v = &schemapb.Decl_Data{Data: n.ToProto().(*schemapb.Data)}
33+
case *Database:
34+
v = &schemapb.Decl_Database{Database: n.ToProto().(*schemapb.Database)}
3335
}
3436
out[i] = &schemapb.Decl{Value: v}
3537
}
@@ -44,6 +46,9 @@ func metadataListToProto(nodes []Metadata) []*schemapb.Metadata {
4446
case *MetadataCalls:
4547
v = &schemapb.Metadata_Calls{Calls: n.ToProto().(*schemapb.MetadataCalls)}
4648

49+
case *MetadataDatabases:
50+
v = &schemapb.Metadata_Databases{Databases: n.ToProto().(*schemapb.MetadataDatabases)}
51+
4752
case *MetadataIngress:
4853
v = &schemapb.Metadata_Ingress{Ingress: n.ToProto().(*schemapb.MetadataIngress)}
4954

backend/schema/validate.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ func ValidateModule(module *Module) error {
179179
}
180180
}
181181

182-
case *Array, *Bool, *DataRef, *Field, *Float, *Int,
182+
case *Array, *Bool, *DataRef, *Database, *Field, *Float, *Int,
183183
*Time, *Map, *Module, *Schema, *String, *Bytes, *VerbRef,
184-
*MetadataCalls, *MetadataIngress, IngressPathComponent,
184+
*MetadataCalls, *MetadataDatabases, *MetadataIngress, IngressPathComponent,
185185
*IngressPathLiteral, *IngressPathParameter, *Optional,
186186
*SourceRef, *SinkRef, *Unit:
187187
case Type, Metadata, Decl: // Union sql.

examples/kotlin/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
<artifactId>ftl-runtime</artifactId>
3535
<version>${ftl.version}</version>
3636
</dependency>
37+
<dependency>
38+
<groupId>org.postgresql</groupId>
39+
<artifactId>postgresql</artifactId>
40+
<version>42.7.1</version>
41+
</dependency>
3742
</dependencies>
3843

3944
<build>

frontend/src/protos/xyz/block/ftl/v1/schema/schema_pb.ts

+106
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)