@@ -130,6 +130,10 @@ func (ac *AdminClient) authorizedViewPath(table, authorizedView string) string {
130130 return fmt .Sprintf ("%s/tables/%s/authorizedViews/%s" , ac .instancePrefix (), table , authorizedView )
131131}
132132
133+ func logicalViewPath (project , instance , logicalView string ) string {
134+ return fmt .Sprintf ("%s/logicalViews/%s" , instancePrefix (project , instance ), logicalView )
135+ }
136+
133137// EncryptionInfo represents the encryption info of a table.
134138type EncryptionInfo struct {
135139 Status * Status
@@ -2604,6 +2608,8 @@ func (s *SubsetViewConf) AddFamilySubsetQualifierPrefix(familyName string, quali
26042608 s .FamilySubsets [familyName ] = fs
26052609}
26062610
2611+ // Authorized Views
2612+
26072613// CreateAuthorizedView creates a new authorized view in a table.
26082614func (ac * AdminClient ) CreateAuthorizedView (ctx context.Context , conf * AuthorizedViewConf ) error {
26092615 if conf .TableID == "" || conf .AuthorizedViewID == "" {
@@ -2765,3 +2771,115 @@ func (ac *AdminClient) DeleteAuthorizedView(ctx context.Context, tableID, author
27652771 _ , err := ac .tClient .DeleteAuthorizedView (ctx , req )
27662772 return err
27672773}
2774+
2775+ // Logical Views
2776+
2777+ // CreateLogicalView creates a new logical view in an instance.
2778+ func (iac * InstanceAdminClient ) CreateLogicalView (ctx context.Context , instanceID string , conf * LogicalViewInfo ) error {
2779+ if conf .LogicalViewID == "" {
2780+ return errors .New ("LogicalViewID is required" )
2781+ }
2782+
2783+ ctx = mergeOutgoingMetadata (ctx , iac .md )
2784+ req := & btapb.CreateLogicalViewRequest {
2785+ Parent : instancePrefix (iac .project , instanceID ),
2786+ LogicalViewId : conf .LogicalViewID ,
2787+ LogicalView : & btapb.LogicalView {
2788+ Query : conf .Query ,
2789+ },
2790+ }
2791+ _ , err := iac .iClient .CreateLogicalView (ctx , req )
2792+ return err
2793+ }
2794+
2795+ // LogicalViewInfo contains logical view metadata. This struct is read-only.
2796+ type LogicalViewInfo struct {
2797+ LogicalViewID string
2798+
2799+ Query string
2800+ }
2801+
2802+ // LogicalViewInfo retrieves information about a logical view.
2803+ func (iac * InstanceAdminClient ) LogicalViewInfo (ctx context.Context , instanceID , logicalViewID string ) (* LogicalViewInfo , error ) {
2804+ ctx = mergeOutgoingMetadata (ctx , iac .md )
2805+ prefix := instancePrefix (iac .project , instanceID )
2806+ req := & btapb.GetLogicalViewRequest {
2807+ Name : logicalViewPath (iac .project , instanceID , logicalViewID ),
2808+ }
2809+ var res * btapb.LogicalView
2810+
2811+ err := gax .Invoke (ctx , func (ctx context.Context , _ gax.CallSettings ) error {
2812+ var err error
2813+ res , err = iac .iClient .GetLogicalView (ctx , req )
2814+ return err
2815+ }, retryOptions ... )
2816+
2817+ if err != nil {
2818+ return nil , err
2819+ }
2820+ return & LogicalViewInfo {LogicalViewID : strings .TrimPrefix (res .Name , prefix + "/logicalViews/" ), Query : res .Query }, nil
2821+ }
2822+
2823+ // LogicalViews returns a list of the logical views in the instance.
2824+ func (iac * InstanceAdminClient ) LogicalViews (ctx context.Context , instanceID string ) ([]LogicalViewInfo , error ) {
2825+ views := []LogicalViewInfo {}
2826+ prefix := instancePrefix (iac .project , instanceID )
2827+ req := & btapb.ListLogicalViewsRequest {
2828+ Parent : prefix ,
2829+ }
2830+ var res * btapb.ListLogicalViewsResponse
2831+ err := gax .Invoke (ctx , func (ctx context.Context , _ gax.CallSettings ) error {
2832+ var err error
2833+ res , err = iac .iClient .ListLogicalViews (ctx , req )
2834+ return err
2835+ }, retryOptions ... )
2836+ if err != nil {
2837+ return nil , err
2838+ }
2839+
2840+ for _ , lv := range res .LogicalViews {
2841+ views = append (views , LogicalViewInfo {LogicalViewID : strings .TrimPrefix (lv .Name , prefix + "/logicalViews/" ), Query : lv .Query })
2842+ }
2843+ return views , nil
2844+ }
2845+
2846+ // UpdateLogicalView updates a logical view in an instance according to the given configuration.
2847+ func (iac * InstanceAdminClient ) UpdateLogicalView (ctx context.Context , instanceID string , conf LogicalViewInfo ) error {
2848+ ctx = mergeOutgoingMetadata (ctx , iac .md )
2849+ if conf .LogicalViewID == "" {
2850+ return errors .New ("LogicalViewID is required" )
2851+ }
2852+ lv := & btapb.LogicalView {}
2853+ lv .Name = logicalViewPath (iac .project , instanceID , conf .LogicalViewID )
2854+
2855+ updateMask := & field_mask.FieldMask {
2856+ Paths : []string {},
2857+ }
2858+ if conf .Query != "" {
2859+ updateMask .Paths = append (updateMask .Paths , "query" )
2860+ }
2861+ req := & btapb.UpdateLogicalViewRequest {
2862+ LogicalView : lv ,
2863+ UpdateMask : updateMask ,
2864+ }
2865+ lro , err := iac .iClient .UpdateLogicalView (ctx , req )
2866+ if err != nil {
2867+ return fmt .Errorf ("error from update logical view: %w" , err )
2868+ }
2869+ var res btapb.LogicalView
2870+ op := longrunning .InternalNewOperation (iac .lroClient , lro )
2871+ if err = op .Wait (ctx , & res ); err != nil {
2872+ return fmt .Errorf ("error from operation: %v" , err )
2873+ }
2874+ return nil
2875+ }
2876+
2877+ // DeleteLogicalView deletes a logical view in an instance.
2878+ func (iac * InstanceAdminClient ) DeleteLogicalView (ctx context.Context , instanceID , logicalViewID string ) error {
2879+ ctx = mergeOutgoingMetadata (ctx , iac .md )
2880+ req := & btapb.DeleteLogicalViewRequest {
2881+ Name : logicalViewPath (iac .project , instanceID , logicalViewID ),
2882+ }
2883+ _ , err := iac .iClient .DeleteLogicalView (ctx , req )
2884+ return err
2885+ }
0 commit comments