Skip to content

Commit 3808de6

Browse files
committed
fixed sugar.{Make,Remove}Recursive + added integration test + fixed test table paths
1 parent 7237e32 commit 3808de6

File tree

4 files changed

+149
-92
lines changed

4 files changed

+149
-92
lines changed

sugar/path.go

Lines changed: 89 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,93 +6,81 @@ import (
66
"path"
77
"strings"
88

9-
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
10-
11-
"github.com/ydb-platform/ydb-go-sdk/v3"
129
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
13-
"github.com/ydb-platform/ydb-go-sdk/v3/retry"
1410
"github.com/ydb-platform/ydb-go-sdk/v3/scheme"
1511
"github.com/ydb-platform/ydb-go-sdk/v3/table"
12+
"github.com/ydb-platform/ydb-go-sdk/v3/topic"
1613
)
1714

1815
const (
1916
sysTable = ".sys"
2017
)
2118

22-
type dbNamer interface {
19+
type dbName interface {
2320
Name() string
2421
}
2522

26-
type dbSchemer interface {
23+
type dbScheme interface {
2724
Scheme() scheme.Client
2825
}
2926

30-
type dbTabler interface {
27+
type dbTable interface {
3128
Table() table.Client
3229
}
3330

31+
type dbTopic interface {
32+
Topic() topic.Client
33+
}
34+
3435
type dbForMakeRecursive interface {
35-
dbNamer
36-
dbSchemer
36+
dbName
37+
dbScheme
3738
}
3839

3940
type dbFoRemoveRecursive interface {
40-
dbNamer
41-
dbSchemer
42-
dbTabler
41+
dbName
42+
dbScheme
43+
dbTable
44+
dbTopic
4345
}
4446

4547
// MakeRecursive creates path inside database
4648
// pathToCreate is a database root relative path
4749
// MakeRecursive method equal bash command `mkdir -p ~/path/to/create`
4850
// where `~` - is a root of database
4951
func MakeRecursive(ctx context.Context, db dbForMakeRecursive, pathToCreate string) error {
50-
pathToCreate = path.Join(db.Name(), pathToCreate)
51-
for i := len(db.Name()) + 1; i < len(pathToCreate); i++ {
52-
x := strings.IndexByte(pathToCreate[i:], '/')
53-
if x == -1 {
54-
x = len(pathToCreate[i:]) - 1
55-
}
56-
i += x
57-
var (
58-
err error
59-
info scheme.Entry
60-
sub = pathToCreate[:i+1]
52+
if strings.HasPrefix(pathToCreate, sysTable+"/") {
53+
return xerrors.WithStackTrace(
54+
fmt.Errorf("making directory %q inside system path %q not supported", pathToCreate, sysTable),
55+
)
56+
}
57+
58+
absPath := path.Join(db.Name(), pathToCreate)
59+
60+
err := db.Scheme().MakeDirectory(ctx, absPath)
61+
if err != nil {
62+
return xerrors.WithStackTrace(
63+
fmt.Errorf("cannot make directory %q: %w", absPath, err),
64+
)
65+
}
66+
67+
info, err := db.Scheme().DescribePath(ctx, absPath)
68+
if err != nil {
69+
return xerrors.WithStackTrace(
70+
fmt.Errorf("cannot describe path %q: %w", absPath, err),
71+
)
72+
}
73+
74+
switch info.Type {
75+
case
76+
scheme.EntryDatabase,
77+
scheme.EntryDirectory:
78+
return nil
79+
default:
80+
return xerrors.WithStackTrace(
81+
fmt.Errorf("entry %q exists but it is not a directory: %s", absPath, info.Type),
6182
)
62-
err = retry.Retry(ctx, func(ctx context.Context) (err error) {
63-
info, err = db.Scheme().DescribePath(ctx, sub)
64-
return err
65-
}, retry.WithIdempotent(true))
66-
if ydb.IsOperationError(err, Ydb.StatusIds_SCHEME_ERROR) {
67-
err = retry.Retry(ctx, func(ctx context.Context) (err error) {
68-
return db.Scheme().MakeDirectory(ctx, sub)
69-
}, retry.WithIdempotent(true))
70-
if err != nil {
71-
return xerrors.WithStackTrace(err)
72-
}
73-
err = retry.Retry(ctx, func(ctx context.Context) (err error) {
74-
info, err = db.Scheme().DescribePath(ctx, sub)
75-
return err
76-
}, retry.WithIdempotent(true))
77-
if err != nil {
78-
return xerrors.WithStackTrace(err)
79-
}
80-
}
81-
if err != nil {
82-
return xerrors.WithStackTrace(err)
83-
}
84-
switch info.Type {
85-
case
86-
scheme.EntryDatabase,
87-
scheme.EntryDirectory:
88-
// OK
89-
default:
90-
return xerrors.WithStackTrace(fmt.Errorf("entry %q exists but it is a %s",
91-
sub, info.Type,
92-
))
93-
}
9483
}
95-
return nil
9684
}
9785

9886
// RemoveRecursive remove selected directory or table names in database.
@@ -103,19 +91,32 @@ func MakeRecursive(ctx context.Context, db dbForMakeRecursive, pathToCreate stri
10391
// where `~` - is a root of database
10492
func RemoveRecursive(ctx context.Context, db dbFoRemoveRecursive, pathToRemove string) error {
10593
fullSysTablePath := path.Join(db.Name(), sysTable)
106-
var list func(int, string) error
107-
list = func(i int, p string) error {
108-
var dir scheme.Directory
109-
var err error
110-
err = retry.Retry(ctx, func(ctx context.Context) (err error) {
111-
dir, err = db.Scheme().ListDirectory(ctx, p)
112-
return xerrors.WithStackTrace(err)
113-
}, retry.WithIdempotent(true))
114-
if ydb.IsOperationErrorSchemeError(err) {
94+
var rmPath func(int, string) error
95+
rmPath = func(i int, p string) error {
96+
if exists, err := IsDirectoryExists(ctx, db.Scheme(), p); err != nil {
97+
return xerrors.WithStackTrace(
98+
fmt.Errorf("check directory %q exists failed: %w", p, err),
99+
)
100+
} else if !exists {
115101
return nil
116102
}
103+
104+
entry, err := db.Scheme().DescribePath(ctx, p)
117105
if err != nil {
118-
return xerrors.WithStackTrace(err)
106+
return xerrors.WithStackTrace(
107+
fmt.Errorf("cannot describe path %q: %w", p, err),
108+
)
109+
}
110+
111+
if entry.Type != scheme.EntryDirectory {
112+
return nil
113+
}
114+
115+
dir, err := db.Scheme().ListDirectory(ctx, p)
116+
if err != nil {
117+
return xerrors.WithStackTrace(
118+
fmt.Errorf("listing directory %q failed: %w", p, err),
119+
)
119120
}
120121

121122
for _, child := range dir.Children {
@@ -125,33 +126,45 @@ func RemoveRecursive(ctx context.Context, db dbFoRemoveRecursive, pathToRemove s
125126
}
126127
switch child.Type {
127128
case scheme.EntryDirectory:
128-
if err = list(i+1, pt); err != nil {
129-
return xerrors.WithStackTrace(err)
130-
}
131-
err = db.Scheme().RemoveDirectory(ctx, pt)
132-
if err != nil {
133-
return xerrors.WithStackTrace(err)
129+
if err = rmPath(i+1, pt); err != nil {
130+
return xerrors.WithStackTrace(
131+
fmt.Errorf("recursive removing directory %q failed: %w", pt, err),
132+
)
134133
}
135134

136135
case scheme.EntryTable:
137136
err = db.Table().Do(ctx, func(ctx context.Context, session table.Session) (err error) {
138137
return session.DropTable(ctx, pt)
139138
}, table.WithIdempotent())
140139
if err != nil {
141-
return xerrors.WithStackTrace(err)
140+
return xerrors.WithStackTrace(
141+
fmt.Errorf("removing table %q failed: %w", pt, err),
142+
)
142143
}
143144

144145
case scheme.EntryTopic:
145146
err = db.Topic().Drop(ctx, pt)
146147
if err != nil {
147-
return xerrors.WithStackTrace(err)
148+
return xerrors.WithStackTrace(
149+
fmt.Errorf("removing topic %q failed: %w", pt, err),
150+
)
148151
}
149152

150153
default:
151-
return xerrors.WithStackTrace(fmt.Errorf("unknown entry type: %s", child.Type.String()))
154+
return xerrors.WithStackTrace(
155+
fmt.Errorf("unknown entry type: %s", child.Type.String()),
156+
)
152157
}
153158
}
159+
160+
err = db.Scheme().RemoveDirectory(ctx, p)
161+
if err != nil {
162+
return xerrors.WithStackTrace(
163+
fmt.Errorf("removing directory %q failed: %w", p, err),
164+
)
165+
}
166+
154167
return nil
155168
}
156-
return list(0, path.Join(db.Name(), pathToRemove))
169+
return rmPath(0, path.Join(db.Name(), pathToRemove))
157170
}

tests/integration/database_sql_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type databaseSQLScope struct {
3030

3131
func TestDatabaseSql(t *testing.T) {
3232
scope := databaseSQLScope{
33-
folder: "database_sql_test",
33+
folder: t.Name(),
3434
}
3535
ctx, cancel := context.WithTimeout(context.Background(), 42*time.Second)
3636
defer cancel()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//go:build !fast
2+
// +build !fast
3+
4+
package integration
5+
6+
import (
7+
"context"
8+
"os"
9+
"path"
10+
"testing"
11+
"time"
12+
13+
"github.com/stretchr/testify/require"
14+
15+
"github.com/ydb-platform/ydb-go-sdk/v3"
16+
"github.com/ydb-platform/ydb-go-sdk/v3/sugar"
17+
"github.com/ydb-platform/ydb-go-sdk/v3/topic/topicoptions"
18+
"github.com/ydb-platform/ydb-go-sdk/v3/topic/topictypes"
19+
)
20+
21+
func TestSugarMakeRemoveRecursive(t *testing.T) {
22+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
23+
defer cancel()
24+
db, err := ydb.Open(
25+
ctx,
26+
os.Getenv("YDB_CONNECTION_STRING"),
27+
ydb.WithAccessTokenCredentials(
28+
os.Getenv("YDB_ACCESS_TOKEN_CREDENTIALS"),
29+
),
30+
)
31+
require.NoError(t, err, os.Getenv("YDB_CONNECTION_STRING"))
32+
defer func() { _ = db.Close(ctx) }()
33+
34+
err = sugar.MakeRecursive(ctx, db, path.Join(".sys", t.Name(), "path", "to", "tables"))
35+
require.Error(t, err)
36+
37+
err = sugar.MakeRecursive(ctx, db, path.Join(t.Name(), "path", "to", "tables"))
38+
require.NoError(t, err)
39+
40+
_, err = db.Scripting().Execute(ctx, `
41+
PRAGMA TablePathPrefix("`+path.Join(db.Name(), t.Name(), "path", "to", "tables")+`");
42+
CREATE TABLE testTable (id Uint64, PRIMARY KEY (id));`, nil,
43+
)
44+
require.NoError(t, err)
45+
46+
err = db.Topic().Create(ctx, path.Join(db.Name(), t.Name(), "path", "to", "topics", "testTopic"),
47+
topicoptions.CreateWithSupportedCodecs(topictypes.CodecRaw),
48+
topicoptions.CreateWithConsumer(topictypes.Consumer{Name: "test-consumer"}),
49+
)
50+
require.NoError(t, err)
51+
52+
err = sugar.MakeRecursive(ctx, db, path.Join(t.Name(), "path", "to", "tables", "and", "another", "child", "directory"))
53+
require.NoError(t, err)
54+
55+
err = sugar.RemoveRecursive(ctx, db, t.Name())
56+
require.NoError(t, err)
57+
}

tests/integration/table_test.go

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"github.com/ydb-platform/ydb-go-sdk/v3/config"
3535
"github.com/ydb-platform/ydb-go-sdk/v3/internal/decimal"
3636
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xsync"
37-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest"
3837
"github.com/ydb-platform/ydb-go-sdk/v3/log"
3938
"github.com/ydb-platform/ydb-go-sdk/v3/meta"
4039
"github.com/ydb-platform/ydb-go-sdk/v3/retry"
@@ -180,21 +179,9 @@ func (s *stats) removeFromInFlight(t testing.TB, id string) {
180179
t.Logf("session '%s' removed from in-flight", id)
181180
}
182181

183-
func TestTableMultiple(t *testing.T) {
184-
xtest.AllowByFlag(t, "HUGE_TEST")
185-
xtest.TestManyTimes(t, func(t testing.TB) {
186-
testTable(t)
187-
}, xtest.StopAfter(time.Hour))
188-
}
189-
190-
func TestTable(t *testing.T) {
191-
testTable(t)
192-
}
193-
194-
//nolint:gocyclo
195-
func testTable(t testing.TB) {
182+
func TestTable(t *testing.T) { //nolint:gocyclo
196183
scope := tableTestScope{
197-
folder: "table_test",
184+
folder: t.Name(),
198185
}
199186

200187
testDuration := 55 * time.Second

0 commit comments

Comments
 (0)