Skip to content

Commit

Permalink
Implement LastSave command
Browse files Browse the repository at this point in the history
Signed-off-by: EdricCua <[email protected]>
  • Loading branch information
EdricCua committed Feb 5, 2025
1 parent c4e1c19 commit cb23720
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
39 changes: 39 additions & 0 deletions go/api/glide_cluster_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,3 +366,42 @@ func (client *GlideClusterClient) EchoWithOptions(echoOptions options.ClusterEch
}
return createClusterSingleValue[string](data), nil
}

// Returns UNIX TIME of the last DB save timestamp or startup timestamp if no save was made since then.
// The command will be routed to a random node.
//
// Parameters:
//
// route - Specifies the routing configuration for the command. The client will route the
// command to the nodes defined by route.
// Return value:
//
// UNIX TIME of the last DB save executed with success.
//
// Example:
//
// route := api.SimpleNodeRoute(api.RandomRoute)
// options := options.NewDBOptionsBuilder().SetRoute(route)
// result, err := client.LastSaveWithOptions(route)
// if err != nil {
// // handle error
// }
// fmt.Println(result) // Output: 1123456
//
// [valkey.io]: https://valkey.io/commands/lastsave/
func (client *GlideClusterClient) LastSaveWithOptions(opts options.RouteOption) (ClusterValue[int64], error) {
response, err := client.executeCommandWithRoute(C.LastSave, []string{}, opts.Route
if opts.Route != nil &&
(opts.Route).IsMultiNode() {
data, err := handleStringIntMapResponse(response)
if err != nil {
return createEmptyClusterValue[int64](), err
}
return createClusterMultiValue[int64](data), nil
}
data, err := handleIntResponse(response)
if err != nil {
return createEmptyClusterValue[int64](), err
}
return createClusterSingleValue[int64](data), nil
}
27 changes: 27 additions & 0 deletions go/api/response_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1160,3 +1160,30 @@ func handleTimeClusterResponse(response *C.struct_CommandResponse) (ClusterValue
}
return createClusterSingleValue(data), nil
}

func handleStringIntMapResponse(response *C.struct_CommandResponse) (map[string]int64, error) {
defer C.free_command_response(response)

typeErr := checkResponseType(response, C.Map, false)
if typeErr != nil {
return nil, typeErr
}

data, err := parseMap(response)
if err != nil {
return nil, err
}
aMap := data.(map[string]interface{})

converted, err := mapConverter[int64]{
nil, false,
}.convert(aMap)
if err != nil {
return nil, err
}
result, ok := converted.(map[string]int64)
if !ok {
return nil, &errors.RequestError{Msg: fmt.Sprintf("unexpected type of map: %T", converted)}
}
return result, nil
}
2 changes: 2 additions & 0 deletions go/api/server_management_cluster_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ type ServerManagementClusterCommands interface {
TimeWithOptions(routeOption options.RouteOption) (ClusterValue[[]string], error)

DBSizeWithOptions(routeOption options.RouteOption) (int64, error)

LastSaveWithOptions(routeOption options.RouteOption) (ClusterValue[int64], error)
}
25 changes: 25 additions & 0 deletions go/integTest/cluster_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,28 @@ func (suite *GlideTestSuite) TestEchoCluster() {
assert.Contains(t, strings.ToLower(messages), strings.ToLower("hello"))
}
}

func (suite *GlideTestSuite) TestLastSaveCluster() {
client := suite.defaultClusterClient()
t := suite.T()

// LastSave with option or with multiple options without route
opts := options.RouteOption{Route: nil}
response, err := client.LastSaveWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsSingleValue())

// same sections with random route
route := config.Route(config.RandomRoute)
opts = options.RouteOption{Route: route}
response, err = client.LastSaveWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsSingleValue())

// default sections, multi node route
route = config.Route(config.AllPrimaries)
opts = options.RouteOption{Route: route}
response, err = client.LastSaveWithOptions(opts)
assert.NoError(t, err)
assert.True(t, response.IsMultiValue())
}

0 comments on commit cb23720

Please sign in to comment.