Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add schema migration get and set cmds to CLI #1650

Merged
merged 6 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions api/http/handlerfuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,73 @@ func patchSchemaHandler(rw http.ResponseWriter, req *http.Request) {
)
}

func setMigrationHandler(rw http.ResponseWriter, req *http.Request) {
cfgStr, err := readWithLimit(req.Body, rw)
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

db, err := dbFromContext(req.Context())
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

txn, err := db.NewTxn(req.Context(), false)
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

var cfg client.LensConfig
err = json.Unmarshal(cfgStr, &cfg)
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

err = db.LensRegistry().SetMigration(req.Context(), txn, cfg)
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

err = txn.Commit(req.Context())
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

sendJSON(
req.Context(),
rw,
simpleDataResponse("result", "success"),
http.StatusOK,
)
}

func getMigrationHandler(rw http.ResponseWriter, req *http.Request) {
db, err := dbFromContext(req.Context())
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

cfgs := db.LensRegistry().Config()
if err != nil {
handleErr(req.Context(), rw, err, http.StatusInternalServerError)
return
}

sendJSON(
req.Context(),
rw,
simpleDataResponse("configuration", cfgs),
http.StatusOK,
)
}

func getBlockHandler(rw http.ResponseWriter, req *http.Request) {
cidStr := chi.URLParam(req, "cid")

Expand Down
19 changes: 11 additions & 8 deletions api/http/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ const (
Version string = "v0"
versionedAPIPath string = "/api/" + Version

RootPath string = versionedAPIPath + ""
PingPath string = versionedAPIPath + "/ping"
DumpPath string = versionedAPIPath + "/debug/dump"
BlocksPath string = versionedAPIPath + "/blocks"
GraphQLPath string = versionedAPIPath + "/graphql"
SchemaPath string = versionedAPIPath + "/schema"
IndexPath string = versionedAPIPath + "/index"
PeerIDPath string = versionedAPIPath + "/peerid"
RootPath string = versionedAPIPath + ""
PingPath string = versionedAPIPath + "/ping"
DumpPath string = versionedAPIPath + "/debug/dump"
BlocksPath string = versionedAPIPath + "/blocks"
GraphQLPath string = versionedAPIPath + "/graphql"
SchemaPath string = versionedAPIPath + "/schema"
SchemaMigrationPath string = SchemaPath + "/migration"
IndexPath string = versionedAPIPath + "/index"
PeerIDPath string = versionedAPIPath + "/peerid"
)

func setRoutes(h *handler) *handler {
Expand Down Expand Up @@ -61,6 +62,8 @@ func setRoutes(h *handler) *handler {
h.Get(SchemaPath, h.handle(listSchemaHandler))
h.Post(SchemaPath, h.handle(loadSchemaHandler))
h.Patch(SchemaPath, h.handle(patchSchemaHandler))
h.Post(SchemaMigrationPath, h.handle(setMigrationHandler))
h.Get(SchemaMigrationPath, h.handle(getMigrationHandler))
h.Post(IndexPath, h.handle(createIndexHandler))
h.Delete(IndexPath, h.handle(dropIndexHandler))
h.Get(IndexPath, h.handle(listIndexHandler))
Expand Down
6 changes: 6 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func NewDefraCommand(cfg *config.Config) DefraCommand {
rpcCmd := MakeRPCCommand(cfg)
blocksCmd := MakeBlocksCommand()
schemaCmd := MakeSchemaCommand()
schemaMigrationCmd := MakeSchemaMigrationCommand()
indexCmd := MakeIndexCommand()
clientCmd := MakeClientCommand()
rpcReplicatorCmd := MakeReplicatorCommand()
Expand All @@ -78,10 +79,15 @@ func NewDefraCommand(cfg *config.Config) DefraCommand {
blocksCmd.AddCommand(
MakeBlocksGetCommand(cfg),
)
schemaMigrationCmd.AddCommand(
MakeSchemaMigrationSetCommand(cfg),
MakeSchemaMigrationGetCommand(cfg),
)
schemaCmd.AddCommand(
MakeSchemaAddCommand(cfg),
MakeSchemaListCommand(cfg),
MakeSchemaPatchCommand(cfg),
schemaMigrationCmd,
)
indexCmd.AddCommand(
MakeIndexCreateCommand(cfg),
Expand Down
25 changes: 25 additions & 0 deletions cli/schema_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2023 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"github.com/spf13/cobra"
)

func MakeSchemaMigrationCommand() *cobra.Command {
var cmd = &cobra.Command{
Use: "migration",
Short: "Interact with the schema migration system of a running DefraDB instance",
Long: `Make set or look for existing schema migrations on a DefraDB node.`,
}

return cmd
}
101 changes: 101 additions & 0 deletions cli/schema_migration_get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2023 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"

"github.com/spf13/cobra"

httpapi "github.com/sourcenetwork/defradb/api/http"
"github.com/sourcenetwork/defradb/client"
"github.com/sourcenetwork/defradb/config"
"github.com/sourcenetwork/defradb/errors"
"github.com/sourcenetwork/defradb/logging"
)

func MakeSchemaMigrationGetCommand(cfg *config.Config) *cobra.Command {
var cmd = &cobra.Command{
Use: "get",
Short: "Gets the schema migrations within DefraDB",
Long: `Gets the schema migrations within the local DefraDB node.

Example:
defradb client schema migration get'

Learn more about the DefraDB GraphQL Schema Language on https://docs.source.network.`,
Args: func(cmd *cobra.Command, args []string) error {
if err := cobra.NoArgs(cmd, args); err != nil {
return errors.New("this command take no arguments")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
endpoint, err := httpapi.JoinPaths(cfg.API.AddressToURL(), httpapi.SchemaMigrationPath)
if err != nil {
return errors.Wrap("join paths failed", err)
}

res, err := http.Get(endpoint.String())
if err != nil {
return errors.Wrap("failed to get schema migrations", err)
}

defer func() {
if e := res.Body.Close(); e != nil {
err = errors.Wrap(fmt.Sprintf("failed to read response body: %v", e.Error()), err)
}
}()
fredcarle marked this conversation as resolved.
Show resolved Hide resolved

response, err := io.ReadAll(res.Body)
if err != nil {
return errors.Wrap("failed to read response body", err)
}

stdout, err := os.Stdout.Stat()
if err != nil {
return errors.Wrap("failed to stat stdout", err)
}
if isFileInfoPipe(stdout) {
cmd.Println(string(response))
} else {
type migrationGetResponse struct {
Data struct {
Configuration []client.LensConfig `json:"configuration"`
} `json:"data"`
Errors []struct {
Message string `json:"message"`
} `json:"errors"`
}
r := migrationGetResponse{}
err = json.Unmarshal(response, &r)
log.FeedbackInfo(cmd.Context(), string(response))
if err != nil {
return NewErrFailedToUnmarshalResponse(err)
}
if len(r.Errors) > 0 {
log.FeedbackError(cmd.Context(), "Failed to get schema migrations",
logging.NewKV("Errors", r.Errors))
} else {
log.FeedbackInfo(cmd.Context(), "Successfully got schema migrations",
logging.NewKV("Configuration", r.Data.Configuration))
}
}

return nil
},
}
return cmd
}
Loading