1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-01-11 18:13:52 +02:00

getBlocks store API with query options (#3755)

This commit is contained in:
Doug Lauder 2022-08-30 09:56:41 -04:00 committed by GitHub
parent e0439e1c42
commit 2035337049
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 133 additions and 66 deletions

View File

@ -168,6 +168,14 @@ func (p *BlockPatch) Patch(block *Block) *Block {
return block
}
type QueryBlocksOptions struct {
BoardID string // if not empty then filter for blocks belonging to specified board
ParentID string // if not empty then filter for blocks belonging to specified parent
BlockType BlockType // if not empty and not `TypeUnknown` then filter for records of specified block type
Page int // page number to select when paginating
PerPage int // number of blocks per page (default=-1, meaning unlimited)
}
// QuerySubtreeOptions are query options that can be passed to GetSubTree methods.
type QuerySubtreeOptions struct {
BeforeUpdateAt int64 // if non-zero then filter for records with update_at less than BeforeUpdateAt

View File

@ -457,6 +457,21 @@ func (mr *MockAPIMockRecorder) EnablePlugin(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePlugin", reflect.TypeOf((*MockAPI)(nil).EnablePlugin), arg0)
}
// EnsureBotUser mocks base method.
func (m *MockAPI) EnsureBotUser(arg0 *model.Bot) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EnsureBotUser", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EnsureBotUser indicates an expected call of EnsureBotUser.
func (mr *MockAPIMockRecorder) EnsureBotUser(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureBotUser", reflect.TypeOf((*MockAPI)(nil).EnsureBotUser), arg0)
}
// ExecuteSlashCommand mocks base method.
func (m *MockAPI) ExecuteSlashCommand(arg0 *model.CommandArgs) (*model.CommandResponse, error) {
m.ctrl.T.Helper()
@ -681,6 +696,21 @@ func (mr *MockAPIMockRecorder) GetChannelsForTeamForUser(arg0, arg1, arg2 interf
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannelsForTeamForUser", reflect.TypeOf((*MockAPI)(nil).GetChannelsForTeamForUser), arg0, arg1, arg2)
}
// GetCloudLimits mocks base method.
func (m *MockAPI) GetCloudLimits() (*model.ProductLimits, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCloudLimits")
ret0, _ := ret[0].(*model.ProductLimits)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCloudLimits indicates an expected call of GetCloudLimits.
func (mr *MockAPIMockRecorder) GetCloudLimits() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCloudLimits", reflect.TypeOf((*MockAPI)(nil).GetCloudLimits))
}
// GetCommand mocks base method.
func (m *MockAPI) GetCommand(arg0 string) (*model.Command, error) {
m.ctrl.T.Helper()

View File

@ -414,6 +414,21 @@ func (mr *MockStoreMockRecorder) GetBlockHistoryDescendants(arg0, arg1 interface
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHistoryDescendants", reflect.TypeOf((*MockStore)(nil).GetBlockHistoryDescendants), arg0, arg1)
}
// GetBlocks mocks base method.
func (m *MockStore) GetBlocks(arg0 model.QueryBlocksOptions) ([]model.Block, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBlocks", arg0)
ret0, _ := ret[0].([]model.Block)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBlocks indicates an expected call of GetBlocks.
func (mr *MockStoreMockRecorder) GetBlocks(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocks", reflect.TypeOf((*MockStore)(nil).GetBlocks), arg0)
}
// GetBlocksByIDs mocks base method.
func (m *MockStore) GetBlocksByIDs(arg0 []string) ([]model.Block, error) {
m.ctrl.T.Helper()

View File

@ -63,17 +63,34 @@ func (s *SQLStore) blockFields() []string {
}
}
func (s *SQLStore) getBlocksWithParentAndType(db sq.BaseRunner, boardID, parentID string, blockType string) ([]model.Block, error) {
func (s *SQLStore) getBlocks(db sq.BaseRunner, opts model.QueryBlocksOptions) ([]model.Block, error) {
query := s.getQueryBuilder(db).
Select(s.blockFields()...).
From(s.tablePrefix + "blocks").
Where(sq.Eq{"board_id": boardID}).
Where(sq.Eq{"parent_id": parentID}).
Where(sq.Eq{"type": blockType})
From(s.tablePrefix + "blocks")
if opts.BoardID != "" {
query = query.Where(sq.Eq{"board_id": opts.BoardID})
}
if opts.ParentID != "" {
query = query.Where(sq.Eq{"parent_id": opts.ParentID})
}
if opts.BlockType != "" && opts.BlockType != model.TypeUnknown {
query = query.Where(sq.Eq{"type": opts.BlockType})
}
if opts.Page != 0 {
query = query.Offset(uint64(opts.Page))
}
if opts.PerPage > 0 {
query = query.Limit(uint64(opts.PerPage))
}
rows, err := query.Query()
if err != nil {
s.logger.Error(`getBlocksWithParentAndType ERROR`, mlog.Err(err))
s.logger.Error(`getBlocks ERROR`, mlog.Err(err))
return nil, err
}
@ -82,22 +99,21 @@ func (s *SQLStore) getBlocksWithParentAndType(db sq.BaseRunner, boardID, parentI
return s.blocksFromRows(rows)
}
func (s *SQLStore) getBlocksWithParent(db sq.BaseRunner, boardID, parentID string) ([]model.Block, error) {
query := s.getQueryBuilder(db).
Select(s.blockFields()...).
From(s.tablePrefix + "blocks").
Where(sq.Eq{"parent_id": parentID}).
Where(sq.Eq{"board_id": boardID})
rows, err := query.Query()
if err != nil {
s.logger.Error(`getBlocksWithParent ERROR`, mlog.Err(err))
return nil, err
func (s *SQLStore) getBlocksWithParentAndType(db sq.BaseRunner, boardID, parentID string, blockType string) ([]model.Block, error) {
opts := model.QueryBlocksOptions{
BoardID: boardID,
ParentID: parentID,
BlockType: model.BlockType(blockType),
}
defer s.CloseRows(rows)
return s.getBlocks(db, opts)
}
return s.blocksFromRows(rows)
func (s *SQLStore) getBlocksWithParent(db sq.BaseRunner, boardID, parentID string) ([]model.Block, error) {
opts := model.QueryBlocksOptions{
BoardID: boardID,
ParentID: parentID,
}
return s.getBlocks(db, opts)
}
func (s *SQLStore) getBlocksByIDs(db sq.BaseRunner, ids []string) ([]model.Block, error) {
@ -127,21 +143,11 @@ func (s *SQLStore) getBlocksByIDs(db sq.BaseRunner, ids []string) ([]model.Block
}
func (s *SQLStore) getBlocksWithType(db sq.BaseRunner, boardID, blockType string) ([]model.Block, error) {
query := s.getQueryBuilder(db).
Select(s.blockFields()...).
From(s.tablePrefix + "blocks").
Where(sq.Eq{"type": blockType}).
Where(sq.Eq{"board_id": boardID})
rows, err := query.Query()
if err != nil {
s.logger.Error(`getBlocksWithParentAndType ERROR`, mlog.Err(err))
return nil, err
opts := model.QueryBlocksOptions{
BoardID: boardID,
BlockType: model.BlockType(blockType),
}
defer s.CloseRows(rows)
return s.blocksFromRows(rows)
return s.getBlocks(db, opts)
}
// getSubTree2 returns blocks within 2 levels of the given blockID.
@ -177,19 +183,10 @@ func (s *SQLStore) getSubTree2(db sq.BaseRunner, boardID string, blockID string,
}
func (s *SQLStore) getBlocksForBoard(db sq.BaseRunner, boardID string) ([]model.Block, error) {
query := s.getQueryBuilder(db).
Select(s.blockFields()...).
From(s.tablePrefix + "blocks").
Where(sq.Eq{"board_id": boardID})
rows, err := query.Query()
if err != nil {
s.logger.Error(`getAllBlocksForBoard ERROR`, mlog.Err(err))
return nil, err
opts := model.QueryBlocksOptions{
BoardID: boardID,
}
defer s.CloseRows(rows)
return s.blocksFromRows(rows)
return s.getBlocks(db, opts)
}
func (s *SQLStore) blocksFromRows(rows *sql.Rows) ([]model.Block, error) {

View File

@ -299,6 +299,11 @@ func (s *SQLStore) GetBlockHistoryDescendants(boardID string, opts model.QueryBl
}
func (s *SQLStore) GetBlocks(opts model.QueryBlocksOptions) ([]model.Block, error) {
return s.getBlocks(s.db, opts)
}
func (s *SQLStore) GetBlocksByIDs(ids []string) ([]model.Block, error) {
return s.getBlocksByIDs(s.db, ids)
@ -713,26 +718,7 @@ func (s *SQLStore) PatchBoardsAndBlocks(pbab *model.PatchBoardsAndBlocks, userID
}
func (s *SQLStore) PatchUserProps(userID string, patch model.UserPropPatch) error {
if s.dbType == model.SqliteDBType {
return s.patchUserProps(s.db, userID, patch)
}
tx, txErr := s.db.BeginTx(context.Background(), nil)
if txErr != nil {
return txErr
}
err := s.patchUserProps(tx, userID, patch)
if err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
s.logger.Error("transaction rollback error", mlog.Err(rollbackErr), mlog.String("methodName", "PatchUserProps"))
}
return err
}
if err := tx.Commit(); err != nil {
return err
}
return nil
return s.patchUserProps(s.db, userID, patch)
}

View File

@ -14,6 +14,7 @@ const CardLimitTimestampSystemKey = "card_limit_timestamp"
// Store represents the abstraction of the data storage.
type Store interface {
GetBlocks(opts model.QueryBlocksOptions) ([]model.Block, error)
GetBlocksWithParentAndType(boardID, parentID string, blockType string) ([]model.Block, error)
GetBlocksWithParent(boardID, parentID string) ([]model.Block, error)
GetBlocksByIDs(ids []string) ([]model.Block, error)

View File

@ -457,6 +457,21 @@ func (mr *MockAPIMockRecorder) EnablePlugin(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePlugin", reflect.TypeOf((*MockAPI)(nil).EnablePlugin), arg0)
}
// EnsureBotUser mocks base method.
func (m *MockAPI) EnsureBotUser(arg0 *model.Bot) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EnsureBotUser", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EnsureBotUser indicates an expected call of EnsureBotUser.
func (mr *MockAPIMockRecorder) EnsureBotUser(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureBotUser", reflect.TypeOf((*MockAPI)(nil).EnsureBotUser), arg0)
}
// ExecuteSlashCommand mocks base method.
func (m *MockAPI) ExecuteSlashCommand(arg0 *model.CommandArgs) (*model.CommandResponse, error) {
m.ctrl.T.Helper()
@ -681,6 +696,21 @@ func (mr *MockAPIMockRecorder) GetChannelsForTeamForUser(arg0, arg1, arg2 interf
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannelsForTeamForUser", reflect.TypeOf((*MockAPI)(nil).GetChannelsForTeamForUser), arg0, arg1, arg2)
}
// GetCloudLimits mocks base method.
func (m *MockAPI) GetCloudLimits() (*model.ProductLimits, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCloudLimits")
ret0, _ := ret[0].(*model.ProductLimits)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCloudLimits indicates an expected call of GetCloudLimits.
func (mr *MockAPIMockRecorder) GetCloudLimits() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCloudLimits", reflect.TypeOf((*MockAPI)(nil).GetCloudLimits))
}
// GetCommand mocks base method.
func (m *MockAPI) GetCommand(arg0 string) (*model.Command, error) {
m.ctrl.T.Helper()