@@ -59,14 +59,15 @@ type Config struct {
5959 User string `yaml:"user"`
6060 Password string `yaml:"password"`
6161 SQLCommenter * bool `yaml:"sqlCommenter"`
62+ ReadOnly bool `yaml:"readonly"`
6263}
6364
6465func (r Config ) SourceConfigType () string {
6566 return SourceType
6667}
6768
6869func (r Config ) Initialize (ctx context.Context , tracer trace.Tracer ) (sources.Source , error ) {
69- pool , err := initCloudSQLPgConnectionPool (ctx , tracer , r .Name , r .Project , r .Region , r .Instance , r .IPType .String (), r .User , r .Password , r .Database )
70+ pool , err := initCloudSQLPgConnectionPool (ctx , tracer , r .Name , r .Project , r .Region , r .Instance , r .IPType .String (), r .User , r .Password , r .Database , r . ReadOnly )
7071 if err != nil {
7172 return nil , fmt .Errorf ("unable to create pool: %w" , err )
7273 }
@@ -106,6 +107,10 @@ func (s *Source) ToConfig() sources.SourceConfig {
106107 return s .Config
107108}
108109
110+ func (s * Source ) IsReadOnlyMode () bool {
111+ return s .ReadOnly
112+ }
113+
109114func (s * Source ) PostgresPool () * pgxpool.Pool {
110115 return s .Pool
111116}
@@ -138,7 +143,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an
138143 return out , nil
139144}
140145
141- func getConnectionConfig (ctx context.Context , user , pass , dbname string ) (string , bool , error ) {
146+ func getConnectionConfig (ctx context.Context , user , pass , dbname string , readOnly bool ) (string , bool , error ) {
142147 userAgent , err := util .UserAgentFromContext (ctx )
143148 if err != nil {
144149 userAgent = "genai-toolbox"
@@ -148,6 +153,9 @@ func getConnectionConfig(ctx context.Context, user, pass, dbname string) (string
148153 // If username and password both provided, use password authentication
149154 if user != "" && pass != "" {
150155 dsn := fmt .Sprintf ("user=%s password=%s dbname=%s sslmode=disable application_name=%s" , user , pass , dbname , userAgent )
156+ if readOnly {
157+ dsn += " options='-c cloudsql_session_read_only=locked'"
158+ }
151159 useIAM = false
152160 return dsn , useIAM , nil
153161 }
@@ -168,16 +176,19 @@ func getConnectionConfig(ctx context.Context, user, pass, dbname string) (string
168176
169177 // Construct IAM connection string with username
170178 dsn := fmt .Sprintf ("user=%s dbname=%s sslmode=disable application_name=%s" , user , dbname , userAgent )
179+ if readOnly {
180+ dsn += " options='-c cloudsql_session_read_only=locked'"
181+ }
171182 return dsn , useIAM , nil
172183}
173184
174- func initCloudSQLPgConnectionPool (ctx context.Context , tracer trace.Tracer , name , project , region , instance , ipType , user , pass , dbname string ) (* pgxpool.Pool , error ) {
185+ func initCloudSQLPgConnectionPool (ctx context.Context , tracer trace.Tracer , name , project , region , instance , ipType , user , pass , dbname string , readOnly bool ) (* pgxpool.Pool , error ) {
175186 //nolint:all // Reassigned ctx
176187 ctx , span := sources .InitConnectionSpan (ctx , tracer , SourceType , name )
177188 defer span .End ()
178189
179190 // Configure the driver to connect to the database
180- dsn , useIAM , err := getConnectionConfig (ctx , user , pass , dbname )
191+ dsn , useIAM , err := getConnectionConfig (ctx , user , pass , dbname , readOnly )
181192 if err != nil {
182193 return nil , fmt .Errorf ("unable to get Cloud SQL connection config: %w" , err )
183194 }
0 commit comments