Skip to content

Commit

Permalink
feat: implement query service (#4121)
Browse files Browse the repository at this point in the history
also hooks up go runtime

fixes #3993

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
worstell and github-actions[bot] authored Jan 20, 2025
1 parent a08d3c0 commit 906935a
Show file tree
Hide file tree
Showing 97 changed files with 4,790 additions and 454 deletions.
1 change: 1 addition & 0 deletions backend/admin/testdata/go/dischema/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions backend/admin/testdata/go/dischema/go.sum

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

50 changes: 49 additions & 1 deletion backend/controller/sql/database_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func TestMySQL(t *testing.T) {
in.Call[in.Obj, in.Obj]("mysql", "query", map[string]any{}, func(t testing.TB, response in.Obj) {
assert.Equal(t, "hello", response["data"])
}),
in.IfLanguage("go", in.ExecModuleTest("mysql")),
// TODO: handle query verbs in ftltest
// in.IfLanguage("go", in.ExecModuleTest("mysql")),
in.Call[in.Obj, in.Obj]("mysql", "query", map[string]any{}, func(t testing.TB, response in.Obj) {
assert.Equal(t, "hello", response["data"])
}),
Expand Down Expand Up @@ -79,3 +80,50 @@ func TestMySQL(t *testing.T) {
})),
)
}

func TestSQLVerbs(t *testing.T) {
in.Run(t,
in.WithLanguages("go"),
in.CopyModule("mysql"),
in.Deploy("mysql"),

// Test EXEC operation - insert a record with all types
in.Call[in.Obj, in.Obj]("mysql", "insertTestTypes", in.Obj{
"intVal": 42,
"floatVal": 3.14,
"textVal": "hello world",
"boolVal": true,
"timeVal": "2024-01-01T12:00:00Z",
"optionalVal": "optional value",
}, nil),

// Test ONE operation - get the inserted record
in.Call[in.Obj, in.Obj]("mysql", "getTestType", in.Obj{"id": 1}, func(t testing.TB, response in.Obj) {
intVal := response["intVal"].(float64)
floatVal := response["floatVal"].(float64)

assert.Equal(t, float64(42), intVal)
assert.Equal(t, 3.14, floatVal)
assert.Equal(t, "hello world", response["textVal"])
assert.Equal(t, true, response["boolVal"])
assert.Equal(t, "2024-01-01T12:00:00Z", response["timeVal"])
// todo: make optionals work with test helper
// assert.Equal(t, "optional value", response["optionalVal"])
}),

// Test MANY operation - get all records
in.Call[in.Obj, []in.Obj]("mysql", "getAllTestTypes", in.Obj{}, func(t testing.TB, response []in.Obj) {
record := response[0]
intVal := record["intVal"].(float64)
floatVal := record["floatVal"].(float64)

assert.Equal(t, float64(42), intVal)
assert.Equal(t, 3.14, floatVal)
assert.Equal(t, "hello world", record["textVal"])
assert.Equal(t, true, record["boolVal"])
assert.Equal(t, "2024-01-01T12:00:00Z", record["timeVal"])
// todo: make optionals work with test helper
// assert.Equal(t, "optional value", record["optionalVal"])
}),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@ SELECT data FROM requests;

-- name: CreateRequest :exec
INSERT INTO requests (data) VALUES (?);

-- name: InsertTestTypes :exec
INSERT INTO test_types (int_val, float_val, text_val, bool_val, time_val, optional_val)
VALUES (?, ?, ?, ?, ?, ?);

-- name: GetTestType :one
SELECT id, int_val, float_val, text_val, bool_val, time_val, optional_val
FROM test_types
WHERE id = ?;

-- name: GetAllTestTypes :many
SELECT id, int_val, float_val, text_val, bool_val, time_val, optional_val
FROM test_types;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
-- migrate:up
CREATE TABLE requests
(
data TEXT,
data TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- migrate:down
DROP TABLE requests;
DROP TABLE requests;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- migrate:up
CREATE TABLE test_types (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
int_val INTEGER NOT NULL,
float_val DOUBLE NOT NULL,
text_val TEXT NOT NULL,
bool_val BOOLEAN NOT NULL,
time_val TIMESTAMP NOT NULL,
optional_val TEXT
);

-- migrate:down
DROP TABLE test_types;
2 changes: 1 addition & 1 deletion backend/controller/sql/testdata/go/mysql/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.23.0

require (
github.com/alecthomas/assert/v2 v2.11.0
github.com/alecthomas/types v0.17.0
github.com/block/ftl v0.189.0
)

Expand All @@ -23,7 +24,6 @@ require (
github.com/alecthomas/kong v1.6.0 // indirect
github.com/alecthomas/participle/v2 v2.1.1 // indirect
github.com/alecthomas/repr v0.4.0 // indirect
github.com/alecthomas/types v0.17.0 // indirect
github.com/amacneil/dbmate/v2 v2.24.2 // indirect
github.com/aws/aws-sdk-go-v2 v1.32.7 // indirect
github.com/aws/aws-sdk-go-v2/config v1.28.7 // indirect
Expand Down
19 changes: 7 additions & 12 deletions backend/controller/sql/testdata/go/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ type InsertRequest struct {
type InsertResponse struct{}

//ftl:verb
func Insert(ctx context.Context, req InsertRequest, db ftl.DatabaseHandle[MyDbConfig]) (InsertResponse, error) {
err := persistRequest(ctx, req, db)
func Insert(ctx context.Context, req InsertRequest, createRequest CreateRequestClient) (InsertResponse, error) {
err := createRequest(ctx, CreateRequestQuery{Data: req.Data})
if err != nil {
return InsertResponse{}, err
}
Expand All @@ -29,16 +29,11 @@ func Insert(ctx context.Context, req InsertRequest, db ftl.DatabaseHandle[MyDbCo
}

//ftl:verb
func Query(ctx context.Context, db ftl.DatabaseHandle[MyDbConfig]) (map[string]string, error) {
var result string
err := db.Get(ctx).QueryRowContext(ctx, "SELECT data FROM requests").Scan(&result)
return map[string]string{"data": result}, err
}

func persistRequest(ctx context.Context, req InsertRequest, db ftl.DatabaseHandle[MyDbConfig]) error {
_, err := db.Get(ctx).Exec("INSERT INTO requests (data) VALUES (?);", req.Data)
func Query(ctx context.Context, getRequestData GetRequestDataClient) (map[string]string, error) {
result, err := getRequestData(ctx)
if err != nil {
return err
return nil, err
}
return nil

return map[string]string{"data": result[0].Data}, nil
}
63 changes: 52 additions & 11 deletions backend/controller/sql/testdata/go/mysql/queries.ftl.go

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

6 changes: 4 additions & 2 deletions backend/controller/sql/testdata/go/mysql/types.ftl.go

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

Loading

0 comments on commit 906935a

Please sign in to comment.