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

Add backend interface for dbStats #3267

Merged
merged 6 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
only include changes related to interface
  • Loading branch information
chilagrow committed Aug 29, 2023
commit 1946ee64a042f8f4bf1945527df17a07c34e4a97
18 changes: 1 addition & 17 deletions internal/backends/sqlite/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,24 +102,8 @@ func (db *database) RenameCollection(ctx context.Context, params *backends.Renam
}

// DBStats implements backends.Database interface.
//
// If the database does not exist, it returns *backends.DBStatsResult filled with zeros for all the fields.
func (db *database) DBStats(ctx context.Context) (*backends.DBStatsResult, error) {
stats := new(backends.DBStatsResult)

d := db.r.DatabaseGetExisting(ctx, db.name)
if d == nil {
return stats, nil
}

// Call ANALYZE to update statistics, the actual statistics are needed to estimate the number of rows in all tables,
// see https://www.sqlite.org/lang_analyze.html.
q := `ANALYZE`
if _, err := d.ExecContext(ctx, q); err != nil {
return nil, lazyerrors.Error(err)
}

return stats, nil
panic("not implemented")
}

// check interfaces
Expand Down
73 changes: 1 addition & 72 deletions internal/handlers/sqlite/msg_dbstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,83 +16,12 @@ package sqlite

import (
"context"
"fmt"

"github.com/FerretDB/FerretDB/internal/backends"
"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonerrors"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
"github.com/FerretDB/FerretDB/internal/util/must"
"github.com/FerretDB/FerretDB/internal/wire"
)

// MsgDBStats implements HandlerInterface.
func (h *Handler) MsgDBStats(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, error) {
document, err := msg.Document()
if err != nil {
return nil, lazyerrors.Error(err)
}

command := document.Command()

dbParam, err := common.GetRequiredParam[string](document, "$db")
if err != nil {
return nil, err
}

scale := int64(1)

var s any
if s, err = document.Get("scale"); err == nil {
if scale, err = commonparams.GetValidatedNumberParamWithMinValue(command, "scale", s, 1); err != nil {
return nil, err
}
}

db, err := h.b.Database(dbParam)
if err != nil {
if backends.ErrorCodeIs(err, backends.ErrorCodeDatabaseNameIsInvalid) {
msg := fmt.Sprintf("Invalid database specified '%s'", dbParam)
return nil, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrInvalidNamespace, msg, document.Command())
}

return nil, lazyerrors.Error(err)
}
defer db.Close()

stats, err := db.DBStats(ctx)
if err != nil {
return nil, lazyerrors.Error(err)
}

pairs := []any{
"db", db,
"collections", stats.CountCollections,
// TODO https://github.com/FerretDB/FerretDB/issues/176
"views", int32(0),
"objects", stats.CountObjects,
}

if stats.CountObjects > 0 {
pairs = append(pairs, "avgObjSize", stats.SizeCollections/stats.CountObjects)
}

pairs = append(pairs,
"dataSize", stats.SizeCollections/scale,
"storageSize", stats.SizeCollections/scale,
"indexes", stats.CountIndexes,
"indexSize", stats.SizeIndexes/scale,
"totalSize", stats.SizeTotal/scale,
"scaleFactor", float64(scale),
"ok", float64(1),
)

var reply wire.OpMsg
must.NoError(reply.SetSections(wire.OpMsgSection{
Documents: []*types.Document{must.NotFail(types.NewDocument(pairs...))},
}))

return &reply, nil
return nil, notImplemented(must.NotFail(msg.Document()).Command())
}