From 287b4d30f79abf26c3db3d19c32f8144544a081c Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 3 Nov 2023 16:49:15 +0100 Subject: [PATCH 01/20] wip --- integration/query_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/integration/query_test.go b/integration/query_test.go index d274ed3c3978..e123b04537cd 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1063,3 +1063,28 @@ func TestQueryIDDoc(t *testing.T) { actual = FilterAll(t, ctx, collection, bson.D{{"_id", bson.D{{"z", int32(4)}, {"a", int32(3)}}}}) AssertEqualDocumentsSlice(t, expected, actual) } + +func TestQueryTailableCursors(t *testing.T) { + t.Parallel() + + ctx, collection := setup.Setup(t) + + //command := bson.D{ + // {"create", collection.Name()}, + // {"capped", tc.capped}, + // {"max", tc.max}, + // {"size", tc.size}, + //} + + //var res bson.D + //err := collection.Database().RunCommand(ctx, command).Decode(&res) + //require.NoError(t, err) + //require.Nil(t, res) + + collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) + + cur, err := collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) + require.NoError(t, err) + + cur.Close(ctx) +} From 57cb8d6a7989368eec285e0eb025bf87186cb79c Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 3 Nov 2023 17:06:27 +0100 Subject: [PATCH 02/20] wip --- integration/query_test.go | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index e123b04537cd..1afaa0811ed9 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1067,24 +1067,19 @@ func TestQueryIDDoc(t *testing.T) { func TestQueryTailableCursors(t *testing.T) { t.Parallel() - ctx, collection := setup.Setup(t) - - //command := bson.D{ - // {"create", collection.Name()}, - // {"capped", tc.capped}, - // {"max", tc.max}, - // {"size", tc.size}, - //} + // to return proper error we need to implement tailable cursors + t.Skip("https://github.com/FerretDB/FerretDB/issues/2283") - //var res bson.D - //err := collection.Database().RunCommand(ctx, command).Decode(&res) - //require.NoError(t, err) - //require.Nil(t, res) + ctx, collection := setup.Setup(t) collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) - cur, err := collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) - require.NoError(t, err) + expectedErr := mongo.CommandError{ + Code: 2, + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree: $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", + Name: "BadValue", + } - cur.Close(ctx) + _, err := collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) + AssertEqualCommandError(t, expectedErr, err) } From 945ce8ca0ddce52c92aebd32e23bddc68cc1edb9 Mon Sep 17 00:00:00 2001 From: noisersup Date: Mon, 6 Nov 2023 12:25:09 +0100 Subject: [PATCH 03/20] wip --- integration/query_test.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index 1afaa0811ed9..9880280fb83b 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1067,17 +1067,22 @@ func TestQueryIDDoc(t *testing.T) { func TestQueryTailableCursors(t *testing.T) { t.Parallel() - // to return proper error we need to implement tailable cursors - t.Skip("https://github.com/FerretDB/FerretDB/issues/2283") - ctx, collection := setup.Setup(t) collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) expectedErr := mongo.CommandError{ - Code: 2, - Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree: $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", - Name: "BadValue", + Code: 238, + Message: "find: support for field \"tailable\" with non-default value true is not implemented yet", + Name: "NotImplemented", + } + + if setup.IsMongoDB(t) { + expectedErr = mongo.CommandError{ + Code: 2, + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree: $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", + Name: "BadValue", + } } _, err := collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) From 8d90d261eb4768055510be847bd34e5ccffc9855 Mon Sep 17 00:00:00 2001 From: noisersup Date: Mon, 6 Nov 2023 14:59:47 +0100 Subject: [PATCH 04/20] lint --- integration/query_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index 9880280fb83b..3aaaf09b5901 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1079,9 +1079,10 @@ func TestQueryTailableCursors(t *testing.T) { if setup.IsMongoDB(t) { expectedErr = mongo.CommandError{ - Code: 2, - Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree: $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", - Name: "BadValue", + Code: 2, + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree:" + + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", + Name: "BadValue", } } From 32c3a0d9453f619a7267f887e6cac27fa4ac5588 Mon Sep 17 00:00:00 2001 From: noisersup Date: Mon, 6 Nov 2023 15:14:48 +0100 Subject: [PATCH 05/20] wip --- integration/query_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index 3aaaf09b5901..6bc67add45e0 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1069,7 +1069,8 @@ func TestQueryTailableCursors(t *testing.T) { ctx, collection := setup.Setup(t) - collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) + _, err := collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) + require.NoError(t, err) expectedErr := mongo.CommandError{ Code: 238, @@ -1086,6 +1087,6 @@ func TestQueryTailableCursors(t *testing.T) { } } - _, err := collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) + _, err = collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) AssertEqualCommandError(t, expectedErr, err) } From 0f8479fe04afb040f14da4f80020aebdcbc10310 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 14:28:58 +0100 Subject: [PATCH 06/20] wip --- integration/query_test.go | 24 +++++++++--------- internal/backends/collection.go | 13 ++++++++++ internal/backends/postgresql/collection.go | 29 ++++++++++++++++++++++ internal/handlers/common/find.go | 2 +- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index 6bc67add45e0..bb9b78f2817b 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1072,20 +1072,20 @@ func TestQueryTailableCursors(t *testing.T) { _, err := collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) require.NoError(t, err) - expectedErr := mongo.CommandError{ - Code: 238, - Message: "find: support for field \"tailable\" with non-default value true is not implemented yet", - Name: "NotImplemented", - } + //expectedErr := mongo.CommandError{ + // Code: 238, + // Message: "find: support for field \"tailable\" with non-default value true is not implemented yet", + // Name: "NotImplemented", + //} - if setup.IsMongoDB(t) { - expectedErr = mongo.CommandError{ - Code: 2, - Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree:" + - " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", - Name: "BadValue", - } + //if setup.IsMongoDB(t) { + expectedErr := mongo.CommandError{ + Code: 2, + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree:" + + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", + Name: "BadValue", } + //} _, err = collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) AssertEqualCommandError(t, expectedErr, err) diff --git a/internal/backends/collection.go b/internal/backends/collection.go index 9afd365d1079..07d2a68369cb 100644 --- a/internal/backends/collection.go +++ b/internal/backends/collection.go @@ -48,6 +48,7 @@ type Collection interface { Stats(context.Context, *CollectionStatsParams) (*CollectionStatsResult, error) Compact(context.Context, *CompactParams) (*CompactResult, error) + Capped(context.Context) (bool, error) ListIndexes(context.Context, *ListIndexesParams) (*ListIndexesResult, error) CreateIndexes(context.Context, *CreateIndexesParams) (*CreateIndexesResult, error) @@ -288,6 +289,18 @@ func (cc *collectionContract) Compact(ctx context.Context, params *CompactParams return res, err } +// Capped returns true if collection is capped. +// +// The errors for non-existing database and non-existing collection are the same. +func (cc *collectionContract) Capped(ctx context.Context) (bool, error) { + defer observability.FuncCall(ctx)() + + res, err := cc.c.Capped(ctx) + checkError(err, ErrorCodeCollectionDoesNotExist) + + return res, err +} + // ListIndexesParams represents the parameters of Collection.ListIndexes method. type ListIndexesParams struct{} diff --git a/internal/backends/postgresql/collection.go b/internal/backends/postgresql/collection.go index 1b90353cac9b..101509ef052f 100644 --- a/internal/backends/postgresql/collection.go +++ b/internal/backends/postgresql/collection.go @@ -464,6 +464,35 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return new(backends.CompactResult), nil } +// Capped implements backends.Collection interface. +func (c *collection) Capped(ctx context.Context) (bool, error) { + db, err := c.r.DatabaseGetExisting(ctx, c.dbName) + if err != nil { + return false, lazyerrors.Error(err) + } + + if db == nil { + return false, backends.NewError( + backends.ErrorCodeCollectionDoesNotExist, + lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + ) + } + + coll, err := c.r.CollectionGet(ctx, c.dbName, c.name) + if err != nil { + return false, lazyerrors.Error(err) + } + + if coll == nil { + return false, backends.NewError( + backends.ErrorCodeCollectionDoesNotExist, + lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + ) + } + + return coll.Capped(), nil +} + // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { db, err := c.r.DatabaseGetExisting(ctx, c.dbName) diff --git a/internal/handlers/common/find.go b/internal/handlers/common/find.go index 229c77c98e1a..80611b3ef91c 100644 --- a/internal/handlers/common/find.go +++ b/internal/handlers/common/find.go @@ -39,6 +39,7 @@ type FindParams struct { SingleBatch bool `ferretdb:"singleBatch,opt"` Comment string `ferretdb:"comment,opt"` MaxTimeMS int64 `ferretdb:"maxTimeMS,opt,wholePositiveNumber"` + Tailable bool `ferretdb:"tailable,opt"` Collation *types.Document `ferretdb:"collation,unimplemented"` Let *types.Document `ferretdb:"let,unimplemented"` @@ -52,7 +53,6 @@ type FindParams struct { ReturnKey bool `ferretdb:"returnKey,unimplemented-non-default"` ShowRecordId bool `ferretdb:"showRecordId,unimplemented-non-default"` //nolint:lll // TODO https://github.com/FerretDB/FerretDB/issues/3467 - Tailable bool `ferretdb:"tailable,unimplemented-non-default"` OplogReplay bool `ferretdb:"oplogReplay,unimplemented-non-default"` NoCursorTimeout bool `ferretdb:"noCursorTimeout,unimplemented-non-default"` AwaitData bool `ferretdb:"awaitData,unimplemented-non-default"` From 7207410f0ae7d2afb73d6971d50dc351ccea1802 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 15:22:56 +0100 Subject: [PATCH 07/20] wip --- internal/handlers/sqlite/msg_find.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index 0ba863104751..a4998ba4d494 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -66,6 +66,24 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er return nil, lazyerrors.Error(err) } + if params.Tailable { + capped, err := c.Capped(ctx) + if err != nil { + return nil, err + } + + if capped { + return nil, commonerrors.NewCommandErrorMsgWithArgument( + commonerrors.ErrBadValue, + fmt.Sprintf("error processing query: ns=%s.%s:"+ + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", params.DB, params.Collection), + "find", + ) + } + + return nil, common.Unimplemented(document, "tailable") + } + qp := &backends.QueryParams{ Comment: params.Comment, } From 4521f7326bc0c8a81aa85269d5bc4f40da847c07 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 15:28:52 +0100 Subject: [PATCH 08/20] wip --- .../backends/decorators/oplog/collection.go | 5 ++++ internal/backends/hana/collection.go | 5 ++++ internal/backends/sqlite/collection.go | 30 +++++++++++++++++++ internal/handlers/sqlite/msg_find.go | 2 +- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/internal/backends/decorators/oplog/collection.go b/internal/backends/decorators/oplog/collection.go index 2cc3e4c69c12..44b6d7533788 100644 --- a/internal/backends/decorators/oplog/collection.go +++ b/internal/backends/decorators/oplog/collection.go @@ -199,6 +199,11 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return c.origC.Compact(ctx, params) } +// DropIndexes implements backends.Collection interface. +func (c *collection) Capped(ctx context.Context) (bool, error) { + return c.origC.Capped(ctx) +} + // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return c.origC.ListIndexes(ctx, params) diff --git a/internal/backends/hana/collection.go b/internal/backends/hana/collection.go index 609032f1e0ba..794b178d43c6 100644 --- a/internal/backends/hana/collection.go +++ b/internal/backends/hana/collection.go @@ -59,6 +59,11 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return nil, lazyerrors.New("not implemented yet") } +// Capped implements backends.Collection interface. +func (c *collection) Capped(ctx context.Context) (bool, error) { + return false, lazyerrors.New("not implemented yet") +} + // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return nil, lazyerrors.New("not implemented yet") diff --git a/internal/backends/sqlite/collection.go b/internal/backends/sqlite/collection.go index c802c3d5d4f3..257e56ecd724 100644 --- a/internal/backends/sqlite/collection.go +++ b/internal/backends/sqlite/collection.go @@ -437,6 +437,36 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return new(backends.CompactResult), nil } +// Capped implements backends.Collection interface. +func (c *collection) Capped(ctx context.Context) (bool, error) { + return false, nil + //db, err := c.r.DatabaseGetExisting(ctx, c.dbName) + //if err != nil { + // return false, lazyerrors.Error(err) + //} + + //if db == nil { + // return false, backends.NewError( + // backends.ErrorCodeCollectionDoesNotExist, + // lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + // ) + //} + + //coll, err := c.r.CollectionGet(ctx, c.dbName, c.name) + //if err != nil { + // return false, lazyerrors.Error(err) + //} + + //if coll == nil { + // return false, backends.NewError( + // backends.ErrorCodeCollectionDoesNotExist, + // lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + // ) + //} + + //return coll.Capped(), nil +} + // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { db := c.r.DatabaseGetExisting(ctx, c.dbName) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index a4998ba4d494..5be72cbf02d4 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -72,7 +72,7 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er return nil, err } - if capped { + if !capped { return nil, commonerrors.NewCommandErrorMsgWithArgument( commonerrors.ErrBadValue, fmt.Sprintf("error processing query: ns=%s.%s:"+ From e79dc9c6c550f315dd09cf7eda9c9587a9cf6847 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 15:34:44 +0100 Subject: [PATCH 09/20] wip --- integration/query_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/query_test.go b/integration/query_test.go index bb9b78f2817b..d630ad7cc4d6 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1081,7 +1081,7 @@ func TestQueryTailableCursors(t *testing.T) { //if setup.IsMongoDB(t) { expectedErr := mongo.CommandError{ Code: 2, - Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree:" + + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursors:" + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", Name: "BadValue", } From b7879d1449a5169bbba4ced8af46a02cc022ed20 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 15:59:51 +0100 Subject: [PATCH 10/20] wip --- internal/handlers/sqlite/msg_find.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index 5be72cbf02d4..29aa773427fd 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -75,7 +75,7 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er if !capped { return nil, commonerrors.NewCommandErrorMsgWithArgument( commonerrors.ErrBadValue, - fmt.Sprintf("error processing query: ns=%s.%s:"+ + fmt.Sprintf("error processing query: ns=%s.%sTree:"+ " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", params.DB, params.Collection), "find", ) From a94820131eddea4f3ac82142f38d160e149e1818 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 16:31:33 +0100 Subject: [PATCH 11/20] wip --- integration/query_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/integration/query_test.go b/integration/query_test.go index d630ad7cc4d6..7d565eddc118 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1072,20 +1072,12 @@ func TestQueryTailableCursors(t *testing.T) { _, err := collection.InsertOne(ctx, bson.D{{"v", int32(42)}}) require.NoError(t, err) - //expectedErr := mongo.CommandError{ - // Code: 238, - // Message: "find: support for field \"tailable\" with non-default value true is not implemented yet", - // Name: "NotImplemented", - //} - - //if setup.IsMongoDB(t) { expectedErr := mongo.CommandError{ Code: 2, Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursors:" + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", Name: "BadValue", } - //} _, err = collection.Find(ctx, bson.D{{}}, options.Find().SetCursorType(options.Tailable)) AssertEqualCommandError(t, expectedErr, err) From 6a4b27d2ae1450746aa1845168c3a377ad84ea8a Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 20:56:20 +0100 Subject: [PATCH 12/20] wip --- integration/query_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/query_test.go b/integration/query_test.go index 528a5a4ca7fe..948088612617 100644 --- a/integration/query_test.go +++ b/integration/query_test.go @@ -1213,7 +1213,7 @@ func TestQueryTailableCursors(t *testing.T) { expectedErr := mongo.CommandError{ Code: 2, - Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursors:" + + Message: "error processing query: ns=TestQueryTailableCursors.TestQueryTailableCursorsTree:" + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", Name: "BadValue", } From 541ec44f1ad1cfb32b3ca605a57efed442a1b429 Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 20:58:19 +0100 Subject: [PATCH 13/20] wip --- internal/backends/sqlite/collection.go | 43 ++++++++++---------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/internal/backends/sqlite/collection.go b/internal/backends/sqlite/collection.go index ceacc91ee5e7..b4eea8b8c5a5 100644 --- a/internal/backends/sqlite/collection.go +++ b/internal/backends/sqlite/collection.go @@ -439,32 +439,23 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams // Capped implements backends.Collection interface. func (c *collection) Capped(ctx context.Context) (bool, error) { - return false, nil - //db, err := c.r.DatabaseGetExisting(ctx, c.dbName) - //if err != nil { - // return false, lazyerrors.Error(err) - //} - - //if db == nil { - // return false, backends.NewError( - // backends.ErrorCodeCollectionDoesNotExist, - // lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - // ) - //} - - //coll, err := c.r.CollectionGet(ctx, c.dbName, c.name) - //if err != nil { - // return false, lazyerrors.Error(err) - //} - - //if coll == nil { - // return false, backends.NewError( - // backends.ErrorCodeCollectionDoesNotExist, - // lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - // ) - //} - - //return coll.Capped(), nil + db := c.r.DatabaseGetExisting(ctx, c.dbName) + if db == nil { + return false, backends.NewError( + backends.ErrorCodeCollectionDoesNotExist, + lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + ) + } + + coll := c.r.CollectionGet(ctx, c.dbName, c.name) + if coll == nil { + return false, backends.NewError( + backends.ErrorCodeCollectionDoesNotExist, + lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), + ) + } + + return coll.Capped(), nil } // ListIndexes implements backends.Collection interface. From 7763081497855613987412c0c0abf59b31c0e6ad Mon Sep 17 00:00:00 2001 From: noisersup Date: Wed, 8 Nov 2023 21:03:41 +0100 Subject: [PATCH 14/20] wip --- internal/backends/decorators/dummy/collection.go | 5 +++++ internal/backends/decorators/oplog/collection.go | 2 +- internal/handlers/sqlite/msg_find.go | 12 +++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/backends/decorators/dummy/collection.go b/internal/backends/decorators/dummy/collection.go index a0e656f76638..75376ac86ed5 100644 --- a/internal/backends/decorators/dummy/collection.go +++ b/internal/backends/decorators/dummy/collection.go @@ -65,6 +65,11 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return c.c.Compact(ctx, params) } +// Capped implements backends.Collection interface. +func (c *collection) Capped(ctx context.Context) (bool, error) { + return c.c.Capped(ctx) +} + // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return c.c.ListIndexes(ctx, params) diff --git a/internal/backends/decorators/oplog/collection.go b/internal/backends/decorators/oplog/collection.go index 44b6d7533788..f9223a96bdd7 100644 --- a/internal/backends/decorators/oplog/collection.go +++ b/internal/backends/decorators/oplog/collection.go @@ -199,7 +199,7 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return c.origC.Compact(ctx, params) } -// DropIndexes implements backends.Collection interface. +// Capped implements backends.Collection interface. func (c *collection) Capped(ctx context.Context) (bool, error) { return c.origC.Capped(ctx) } diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index c857f8f2276f..cc23f352826d 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -67,7 +67,9 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er } if params.Tailable { - capped, err := c.Capped(ctx) + var capped bool + + capped, err = c.Capped(ctx) if err != nil { return nil, err } @@ -75,8 +77,12 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er if !capped { return nil, commonerrors.NewCommandErrorMsgWithArgument( commonerrors.ErrBadValue, - fmt.Sprintf("error processing query: ns=%s.%sTree:"+ - " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", params.DB, params.Collection), + fmt.Sprintf( + "error processing query: ns=%s.%sTree:"+ + " $eq null\nSort: {}\nProj: {}\n tailable cursor requested on non capped collection", + params.DB, + params.Collection, + ), "find", ) } From 5dd3ed8eef2977730ab6ca75ec04adae6d10ef3a Mon Sep 17 00:00:00 2001 From: noisersup Date: Thu, 9 Nov 2023 18:52:34 +0100 Subject: [PATCH 15/20] wip --- internal/handlers/sqlite/msg_find.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index cc23f352826d..dafcb28ec047 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -67,14 +67,25 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er } if params.Tailable { - var capped bool - - capped, err = c.Capped(ctx) + // TODO https://github.com/FerretDB/FerretDB/issues/3601 + res, err := db.ListCollections(ctx, &backends.ListCollectionsParams{}) if err != nil { return nil, err } - if !capped { + var collInfo *backends.CollectionInfo + + for _, coll := range res.Collections { + if coll.Name == params.Collection { + collInfo = &coll + } + } + + if collInfo == nil { + // coll doesnt exist + } + + if !collInfo.Capped() { return nil, commonerrors.NewCommandErrorMsgWithArgument( commonerrors.ErrBadValue, fmt.Sprintf( From 131d6b487cbbfde8d8980a7632fc3be1e315fc3d Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 10 Nov 2023 14:27:35 +0100 Subject: [PATCH 16/20] wip --- internal/handlers/sqlite/msg_find.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index dafcb28ec047..9f4a21e800d1 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -68,7 +68,7 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er if params.Tailable { // TODO https://github.com/FerretDB/FerretDB/issues/3601 - res, err := db.ListCollections(ctx, &backends.ListCollectionsParams{}) + res, err := db.ListCollections(ctx, nil) if err != nil { return nil, err } From f4c672d0aa5235f206222798842e1c09184b142e Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 10 Nov 2023 14:30:26 +0100 Subject: [PATCH 17/20] wip --- internal/handlers/sqlite/msg_find.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index 9f4a21e800d1..53d0a546ac95 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -81,11 +81,7 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er } } - if collInfo == nil { - // coll doesnt exist - } - - if !collInfo.Capped() { + if collInfo != nil && !collInfo.Capped() { return nil, commonerrors.NewCommandErrorMsgWithArgument( commonerrors.ErrBadValue, fmt.Sprintf( From 238d828379ea4be0836805e2c6478cda45048951 Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 10 Nov 2023 14:56:56 +0100 Subject: [PATCH 18/20] wip --- internal/handlers/sqlite/msg_find.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/handlers/sqlite/msg_find.go b/internal/handlers/sqlite/msg_find.go index 53d0a546ac95..596f10a1798d 100644 --- a/internal/handlers/sqlite/msg_find.go +++ b/internal/handlers/sqlite/msg_find.go @@ -67,14 +67,15 @@ func (h *Handler) MsgFind(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, er } if params.Tailable { - // TODO https://github.com/FerretDB/FerretDB/issues/3601 - res, err := db.ListCollections(ctx, nil) + var res *backends.ListCollectionsResult + var collInfo *backends.CollectionInfo + + res, err = db.ListCollections(ctx, nil) if err != nil { return nil, err } - var collInfo *backends.CollectionInfo - + // TODO https://github.com/FerretDB/FerretDB/issues/3601 for _, coll := range res.Collections { if coll.Name == params.Collection { collInfo = &coll From c39e8db13566aca105c1f3fa563a8db06fe334cc Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 10 Nov 2023 17:02:53 +0100 Subject: [PATCH 19/20] wip --- internal/backends/collection.go | 13 --------- .../backends/decorators/oplog/collection.go | 5 ---- internal/backends/postgresql/collection.go | 29 ------------------- internal/backends/sqlite/collection.go | 21 -------------- 4 files changed, 68 deletions(-) diff --git a/internal/backends/collection.go b/internal/backends/collection.go index 2d29ae59aeab..e7be7aab494f 100644 --- a/internal/backends/collection.go +++ b/internal/backends/collection.go @@ -48,7 +48,6 @@ type Collection interface { Stats(context.Context, *CollectionStatsParams) (*CollectionStatsResult, error) Compact(context.Context, *CompactParams) (*CompactResult, error) - Capped(context.Context) (bool, error) ListIndexes(context.Context, *ListIndexesParams) (*ListIndexesResult, error) CreateIndexes(context.Context, *CreateIndexesParams) (*CreateIndexesResult, error) @@ -289,18 +288,6 @@ func (cc *collectionContract) Compact(ctx context.Context, params *CompactParams return res, err } -// Capped returns true if collection is capped. -// -// The errors for non-existing database and non-existing collection are the same. -func (cc *collectionContract) Capped(ctx context.Context) (bool, error) { - defer observability.FuncCall(ctx)() - - res, err := cc.c.Capped(ctx) - checkError(err, ErrorCodeCollectionDoesNotExist) - - return res, err -} - // ListIndexesParams represents the parameters of Collection.ListIndexes method. type ListIndexesParams struct{} diff --git a/internal/backends/decorators/oplog/collection.go b/internal/backends/decorators/oplog/collection.go index f9223a96bdd7..2cc3e4c69c12 100644 --- a/internal/backends/decorators/oplog/collection.go +++ b/internal/backends/decorators/oplog/collection.go @@ -199,11 +199,6 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return c.origC.Compact(ctx, params) } -// Capped implements backends.Collection interface. -func (c *collection) Capped(ctx context.Context) (bool, error) { - return c.origC.Capped(ctx) -} - // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return c.origC.ListIndexes(ctx, params) diff --git a/internal/backends/postgresql/collection.go b/internal/backends/postgresql/collection.go index 8e385e6c1808..fdcdbd6928bf 100644 --- a/internal/backends/postgresql/collection.go +++ b/internal/backends/postgresql/collection.go @@ -464,35 +464,6 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return new(backends.CompactResult), nil } -// Capped implements backends.Collection interface. -func (c *collection) Capped(ctx context.Context) (bool, error) { - db, err := c.r.DatabaseGetExisting(ctx, c.dbName) - if err != nil { - return false, lazyerrors.Error(err) - } - - if db == nil { - return false, backends.NewError( - backends.ErrorCodeCollectionDoesNotExist, - lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - ) - } - - coll, err := c.r.CollectionGet(ctx, c.dbName, c.name) - if err != nil { - return false, lazyerrors.Error(err) - } - - if coll == nil { - return false, backends.NewError( - backends.ErrorCodeCollectionDoesNotExist, - lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - ) - } - - return coll.Capped(), nil -} - // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { db, err := c.r.DatabaseGetExisting(ctx, c.dbName) diff --git a/internal/backends/sqlite/collection.go b/internal/backends/sqlite/collection.go index b4eea8b8c5a5..846c8eee9687 100644 --- a/internal/backends/sqlite/collection.go +++ b/internal/backends/sqlite/collection.go @@ -437,27 +437,6 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return new(backends.CompactResult), nil } -// Capped implements backends.Collection interface. -func (c *collection) Capped(ctx context.Context) (bool, error) { - db := c.r.DatabaseGetExisting(ctx, c.dbName) - if db == nil { - return false, backends.NewError( - backends.ErrorCodeCollectionDoesNotExist, - lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - ) - } - - coll := c.r.CollectionGet(ctx, c.dbName, c.name) - if coll == nil { - return false, backends.NewError( - backends.ErrorCodeCollectionDoesNotExist, - lazyerrors.Errorf("no ns %s.%s", c.dbName, c.name), - ) - } - - return coll.Capped(), nil -} - // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { db := c.r.DatabaseGetExisting(ctx, c.dbName) From ec181f419a2423c0c08828fc0360028dbe92a33c Mon Sep 17 00:00:00 2001 From: noisersup Date: Fri, 10 Nov 2023 17:04:24 +0100 Subject: [PATCH 20/20] wip --- internal/backends/decorators/dummy/collection.go | 5 ----- internal/backends/hana/collection.go | 5 ----- 2 files changed, 10 deletions(-) diff --git a/internal/backends/decorators/dummy/collection.go b/internal/backends/decorators/dummy/collection.go index 75376ac86ed5..a0e656f76638 100644 --- a/internal/backends/decorators/dummy/collection.go +++ b/internal/backends/decorators/dummy/collection.go @@ -65,11 +65,6 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return c.c.Compact(ctx, params) } -// Capped implements backends.Collection interface. -func (c *collection) Capped(ctx context.Context) (bool, error) { - return c.c.Capped(ctx) -} - // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return c.c.ListIndexes(ctx, params) diff --git a/internal/backends/hana/collection.go b/internal/backends/hana/collection.go index 794b178d43c6..609032f1e0ba 100644 --- a/internal/backends/hana/collection.go +++ b/internal/backends/hana/collection.go @@ -59,11 +59,6 @@ func (c *collection) Compact(ctx context.Context, params *backends.CompactParams return nil, lazyerrors.New("not implemented yet") } -// Capped implements backends.Collection interface. -func (c *collection) Capped(ctx context.Context) (bool, error) { - return false, lazyerrors.New("not implemented yet") -} - // ListIndexes implements backends.Collection interface. func (c *collection) ListIndexes(ctx context.Context, params *backends.ListIndexesParams) (*backends.ListIndexesResult, error) { return nil, lazyerrors.New("not implemented yet")