MCPcopy Index your code
hub / github.com/bytebase/bytebase / AddDataSource

Method AddDataSource

backend/api/v1/instance_service.go:804–886  ·  view source on GitHub ↗

AddDataSource adds a data source to an instance.

(ctx context.Context, req *connect.Request[v1pb.AddDataSourceRequest])

Source from the content-addressed store, hash-verified

802
803// AddDataSource adds a data source to an instance.
804func (s *InstanceService) AddDataSource(ctx context.Context, req *connect.Request[v1pb.AddDataSourceRequest]) (*connect.Response[v1pb.Instance], error) {
805 if req.Msg.DataSource == nil {
806 return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("data sources is required"))
807 }
808 // We only support add RO type datasouce to instance now, see more details in instance_service.proto.
809 if req.Msg.DataSource.Type != v1pb.DataSourceType_READ_ONLY {
810 return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("only support adding read-only data source"))
811 }
812
813 dataSource, err := convertV1DataSource(req.Msg.DataSource)
814 if err != nil {
815 return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("failed to convert data source"))
816 }
817
818 instance, err := getInstanceMessage(ctx, s.store, req.Msg.Name)
819 if err != nil {
820 return nil, err
821 }
822 if instance.Deleted {
823 return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("instance %q has been deleted", req.Msg.Name))
824 }
825 for _, ds := range instance.Metadata.GetDataSources() {
826 if ds.GetId() == req.Msg.DataSource.Id {
827 return nil, connect.NewError(connect.CodeNotFound, errors.New("data source already exists with the same name"))
828 }
829 }
830 if err := s.checkDataSource(ctx, instance, dataSource); err != nil {
831 return nil, err
832 }
833 if err := validateAndSanitizeDataSourceTLS(dataSource); err != nil {
834 return nil, connect.NewError(connect.CodeInvalidArgument, err)
835 }
836 metadata := proto.CloneOf(instance.Metadata)
837 metadata.DataSources = append(metadata.DataSources, dataSource)
838 if err := s.checkInstanceDataSources(ctx, instance, metadata.GetDataSources()); err != nil {
839 return nil, err
840 }
841
842 if err := s.licenseService.IsFeatureEnabledForInstance(ctx, common.GetWorkspaceIDFromContext(ctx), v1pb.PlanFeature_FEATURE_INSTANCE_READ_ONLY_CONNECTION, instance); err != nil {
843 return nil, connect.NewError(connect.CodePermissionDenied, err)
844 }
845
846 // Test connection.
847 if req.Msg.ValidateOnly {
848 err := func() error {
849 driver, err := s.dbFactory.GetDataSourceDriver(
850 ctx, instance, dataSource,
851 db.ConnectionContext{
852 ReadOnly: dataSource.GetType() == storepb.DataSourceType_READ_ONLY,
853 },
854 )
855 if err != nil {
856 return connect.NewError(connect.CodeInternal, errors.Wrapf(err, "failed to get database driver"))
857 }
858 defer driver.Close(ctx)
859 if err := driver.Ping(ctx); err != nil {
860 return connect.NewError(connect.CodeInvalidArgument, errors.Wrapf(err, "invalid datasource %s", dataSource.GetType()))
861 }

Callers 1

UpdateDataSourceMethod · 0.95

Calls 15

checkDataSourceMethod · 0.95
convertToV1InstanceMethod · 0.95
convertV1DataSourceFunction · 0.85
getInstanceMessageFunction · 0.85
instanceWithMetadataFunction · 0.85
ErrorfMethod · 0.80
GetDataSourceDriverMethod · 0.80
CloseMethod · 0.65

Tested by

no test coverage detected