Issue 24: Added read-only mode (#27)

- Added settings to workspace, and added the read-only mode
- Added the `-ro` field which will launch Dynamo-Browse in read-only mode
- Added the `set ro` to enable read-only mode, and `set rw` to enable read-write mode
This commit is contained in:
Leon Mika 2022-09-29 22:10:18 +10:00 committed by GitHub
parent a1717572c5
commit 93ec519127
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 623 additions and 315 deletions

View file

@ -17,3 +17,7 @@ type TableProvider interface {
PutItem(ctx context.Context, name string, item models.Item) error
PutItems(ctx context.Context, name string, items []models.Item) error
}
type ROProvider interface {
IsReadOnly() (bool, error)
}

View file

@ -12,12 +12,14 @@ import (
)
type Service struct {
provider TableProvider
provider TableProvider
roProvider ROProvider
}
func NewService(provider TableProvider) *Service {
func NewService(provider TableProvider, roProvider ROProvider) *Service {
return &Service{
provider: provider,
provider: provider,
roProvider: roProvider,
}
}
@ -75,10 +77,18 @@ func (s *Service) doScan(ctx context.Context, tableInfo *models.TableInfo, expr
}
func (s *Service) Put(ctx context.Context, tableInfo *models.TableInfo, item models.Item) error {
if err := s.assertReadWrite(); err != nil {
return err
}
return s.provider.PutItem(ctx, tableInfo.Name, item)
}
func (s *Service) PutItemAt(ctx context.Context, resultSet *models.ResultSet, index int) error {
if err := s.assertReadWrite(); err != nil {
return err
}
item := resultSet.Items()[index]
if err := s.provider.PutItem(ctx, resultSet.TableInfo.Name, item); err != nil {
return err
@ -90,6 +100,10 @@ func (s *Service) PutItemAt(ctx context.Context, resultSet *models.ResultSet, in
}
func (s *Service) PutSelectedItems(ctx context.Context, resultSet *models.ResultSet, markedItems []models.ItemIndex) error {
if err := s.assertReadWrite(); err != nil {
return err
}
if len(markedItems) == 0 {
return nil
}
@ -108,6 +122,10 @@ func (s *Service) PutSelectedItems(ctx context.Context, resultSet *models.Result
}
func (s *Service) Delete(ctx context.Context, tableInfo *models.TableInfo, items []models.Item) error {
if err := s.assertReadWrite(); err != nil {
return err
}
for _, item := range items {
if err := s.provider.DeleteItem(ctx, tableInfo.Name, item.KeyValue(tableInfo)); err != nil {
return errors.Wrapf(err, "cannot delete item")
@ -120,6 +138,16 @@ func (s *Service) ScanOrQuery(ctx context.Context, tableInfo *models.TableInfo,
return s.doScan(ctx, tableInfo, expr)
}
func (s *Service) assertReadWrite() error {
b, err := s.roProvider.IsReadOnly()
if err != nil {
return err
} else if b {
return models.ErrReadOnly
}
return nil
}
// TODO: move into a new service
func (s *Service) Filter(resultSet *models.ResultSet, filter string) *models.ResultSet {
for i, item := range resultSet.Items() {

View file

@ -19,7 +19,7 @@ func TestService_Describe(t *testing.T) {
t.Run("return details of the table", func(t *testing.T) {
ctx := context.Background()
service := tables.NewService(provider)
service := tables.NewService(provider, mockedReadOnlyProvider{readOnly: false})
ti, err := service.Describe(ctx, tableName)
assert.NoError(t, err)
@ -40,7 +40,7 @@ func TestService_Scan(t *testing.T) {
t.Run("return all columns and fields in sorted order", func(t *testing.T) {
ctx := context.Background()
service := tables.NewService(provider)
service := tables.NewService(provider, mockedReadOnlyProvider{readOnly: false})
ti, err := service.Describe(ctx, tableName)
assert.NoError(t, err)
@ -77,3 +77,11 @@ var testData = []testdynamo.TestData{
},
},
}
type mockedReadOnlyProvider struct {
readOnly bool
}
func (m mockedReadOnlyProvider) IsReadOnly() (bool, error) {
return m.readOnly, nil
}