Skip to content

Commit 1f814b6

Browse files
author
maksim.konovalov
committed
Added logic for working with Tarantool schema via Box
- Implemented the `box.Schema()` method that returns a `Schema` object for schema-related operations
1 parent d8e2284 commit 1f814b6

File tree

9 files changed

+527
-50
lines changed

9 files changed

+527
-50
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
1111
### Added
1212

1313
- Extend box with replication information (#427).
14+
- Implemented box.schema.user operations requests and sugar interface.
1415

1516
### Changed
1617

box/box.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ func New(conn tarantool.Doer) *Box {
1717
}
1818
}
1919

20+
// Schema returns a new Schema instance, providing access to schema-related operations.
21+
// It uses the connection from the Box instance to communicate with Tarantool.
22+
func (b *Box) Schema() *Schema {
23+
return NewSchema(b.conn)
24+
}
25+
2026
// Info retrieves the current information of the Tarantool instance.
2127
// It calls the "box.info" function and parses the result into the Info structure.
2228
func (b *Box) Info() (Info, error) {

box/example_test.go

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/tarantool/go-tarantool/v2/box"
1919
)
2020

21-
func Example() {
21+
func ExampleBox_Info() {
2222
dialer := tarantool.NetDialer{
2323
Address: "127.0.0.1:3013",
2424
User: "test",
@@ -58,3 +58,132 @@ func Example() {
5858
fmt.Printf("Box info uuids are equal")
5959
fmt.Printf("Current box info: %+v\n", resp.Info)
6060
}
61+
62+
func ExampleSchemaUser_Exists() {
63+
dialer := tarantool.NetDialer{
64+
Address: "127.0.0.1:3013",
65+
User: "test",
66+
Password: "test",
67+
}
68+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
69+
client, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
70+
cancel()
71+
if err != nil {
72+
log.Fatalf("Failed to connect: %s", err)
73+
}
74+
75+
// You can use UserExistsRequest type and call it directly.
76+
fut := client.Do(box.NewUserExistsRequest("user"))
77+
78+
resp := &box.UserExistsResponse{}
79+
80+
err = fut.GetTyped(resp)
81+
if err != nil {
82+
log.Fatalf("Failed get box schema user exists with error: %s", err)
83+
}
84+
85+
// Or use simple User implementation.
86+
b := box.New(client)
87+
exists, err := b.Schema().User().Exists(ctx, "user")
88+
if err != nil {
89+
log.Fatalf("Failed get box schema user exists with error: %s", err)
90+
}
91+
92+
if exists != resp.Exists {
93+
log.Fatalf("Box schema users exists are not equal")
94+
}
95+
96+
fmt.Printf("Box schema users exists are equal")
97+
fmt.Printf("Current exists state: %+v\n", exists)
98+
}
99+
100+
func ExampleSchemaUser_Create() {
101+
// Connect to Tarantool
102+
dialer := tarantool.NetDialer{
103+
Address: "127.0.0.1:3013",
104+
User: "test",
105+
Password: "test",
106+
}
107+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
108+
client, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
109+
cancel()
110+
if err != nil {
111+
log.Fatalf("Failed to connect: %s", err)
112+
}
113+
defer client.Close()
114+
115+
// Create SchemaUser
116+
schemaUser := box.NewSchemaUser(client)
117+
118+
// Create a new user
119+
username := "new_user"
120+
options := box.UserCreateOptions{
121+
IfNotExists: true,
122+
Password: "secure_password",
123+
}
124+
err = schemaUser.Create(ctx, username, options)
125+
if err != nil {
126+
log.Fatalf("Failed to create user: %s", err)
127+
}
128+
129+
fmt.Printf("User '%s' created successfully\n", username)
130+
}
131+
132+
func ExampleSchemaUser_Drop() {
133+
// Connect to Tarantool
134+
dialer := tarantool.NetDialer{
135+
Address: "127.0.0.1:3013",
136+
User: "test",
137+
Password: "test",
138+
}
139+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
140+
client, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
141+
cancel()
142+
if err != nil {
143+
log.Fatalf("Failed to connect: %s", err)
144+
}
145+
defer client.Close()
146+
147+
// Create SchemaUser
148+
schemaUser := box.NewSchemaUser(client)
149+
150+
// Drop an existing user
151+
username := "new_user"
152+
options := box.UserDropOptions{
153+
IfExists: true,
154+
}
155+
err = schemaUser.Drop(ctx, username, options)
156+
if err != nil {
157+
log.Fatalf("Failed to drop user: %s", err)
158+
}
159+
160+
fmt.Printf("User '%s' dropped successfully\n", username)
161+
}
162+
163+
func ExampleSchemaUser_Password() {
164+
// Connect to Tarantool
165+
dialer := tarantool.NetDialer{
166+
Address: "127.0.0.1:3013",
167+
User: "test",
168+
Password: "test",
169+
}
170+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
171+
client, err := tarantool.Connect(ctx, dialer, tarantool.Opts{})
172+
cancel()
173+
if err != nil {
174+
log.Fatalf("Failed to connect: %s", err)
175+
}
176+
defer client.Close()
177+
178+
// Create SchemaUser
179+
schemaUser := box.NewSchemaUser(client)
180+
181+
// Get the password hash of an existing user
182+
username := "existing_user"
183+
passwordHash, err := schemaUser.Password(ctx, username)
184+
if err != nil {
185+
log.Fatalf("Failed to get password hash: %s", err)
186+
}
187+
188+
fmt.Printf("Password hash for user '%s': %s\n", username, passwordHash)
189+
}

box/info.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,14 @@ func (ir *InfoResponse) DecodeMsgpack(d *msgpack.Decoder) error {
112112
// InfoRequest represents a request to retrieve information about the Tarantool instance.
113113
// It implements the tarantool.Request interface.
114114
type InfoRequest struct {
115-
baseRequest
116-
}
117-
118-
// Body method is used to serialize the request's body.
119-
// It is part of the tarantool.Request interface implementation.
120-
func (i InfoRequest) Body(res tarantool.SchemaResolver, enc *msgpack.Encoder) error {
121-
return i.impl.Body(res, enc)
115+
*tarantool.CallRequest // Underlying Tarantool call request.
122116
}
123117

124118
// NewInfoRequest returns a new empty info request.
125119
func NewInfoRequest() InfoRequest {
126-
req := InfoRequest{}
127-
req.impl = newCall("box.info")
128-
return req
120+
callReq := tarantool.NewCallRequest("box.info")
121+
122+
return InfoRequest{
123+
callReq,
124+
}
129125
}

box/request.go

Lines changed: 0 additions & 38 deletions
This file was deleted.

box/schema.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package box
2+
3+
import "github.com/tarantool/go-tarantool/v2"
4+
5+
// Schema represents the schema-related operations in Tarantool.
6+
// It holds a connection to interact with the Tarantool instance.
7+
type Schema struct {
8+
conn tarantool.Doer // Connection interface for interacting with Tarantool.
9+
}
10+
11+
// NewSchema creates a new Schema instance with the provided Tarantool connection.
12+
// It initializes a Schema object that can be used for schema-related operations
13+
// such as managing users, tables, and other schema elements in the Tarantool instance.
14+
func NewSchema(conn tarantool.Doer) *Schema {
15+
return &Schema{conn: conn} // Pass the connection to the Schema.
16+
}
17+
18+
// User returns a new SchemaUser instance, allowing schema-related user operations.
19+
func (s *Schema) User() *SchemaUser {
20+
return NewSchemaUser(s.conn)
21+
}

0 commit comments

Comments
 (0)