1 // Copyright 2015 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package mysql adds a 'cloudsql' network to use when you want to access a 16 // Cloud SQL Database via the mysql driver found at 17 // github.com/go-sql-driver/mysql. It also exposes helper functions for 18 // dialing. 19 package mysql 20 21 import ( 22 "database/sql" 23 "errors" 24 25 "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/proxy" 26 "github.com/go-sql-driver/mysql" 27 ) 28 29 func init() { 30 mysql.RegisterDialContext("cloudsql", proxy.DialContext) 31 } 32 33 // Dial logs into the specified Cloud SQL Instance using the given user and no 34 // password. To set more options, consider calling DialCfg instead. 35 // 36 // The provided instance should be in the form project-name:region:instance-name. 37 // 38 // The returned *sql.DB may be valid even if there's also an error returned 39 // (e.g. if there was a transient connection error). 40 func Dial(instance, user string) (*sql.DB, error) { 41 cfg := mysql.NewConfig() 42 cfg.User = user 43 cfg.Addr = instance 44 return DialCfg(cfg) 45 } 46 47 // DialPassword is similar to Dial, but allows you to specify a password. 48 // 49 // Note that using a password with the proxy is not necessary as long as the 50 // user's hostname in the mysql.user table is 'cloudsqlproxy~'. For more 51 // information, see: 52 // https://cloud.google.com/sql/docs/sql-proxy#user 53 func DialPassword(instance, user, password string) (*sql.DB, error) { 54 cfg := mysql.NewConfig() 55 cfg.User = user 56 cfg.Passwd = password 57 cfg.Addr = instance 58 return DialCfg(cfg) 59 } 60 61 // Cfg returns the effective *mysql.Config to represent connectivity to the 62 // provided instance via the given user and password. The config can be 63 // modified and passed to DialCfg to connect. If you don't modify the returned 64 // config before dialing, consider using Dial or DialPassword. 65 func Cfg(instance, user, password string) *mysql.Config { 66 cfg := mysql.NewConfig() 67 cfg.User = user 68 cfg.Passwd = password 69 cfg.Addr = instance 70 cfg.Net = "cloudsql" 71 return cfg 72 } 73 74 // DialCfg opens up a SQL connection to a Cloud SQL Instance specified by the 75 // provided configuration. It is otherwise the same as Dial. 76 // 77 // The cfg.Addr should be the instance's connection string, in the format of: 78 // project-name:region:instance-name. 79 func DialCfg(cfg *mysql.Config) (*sql.DB, error) { 80 if cfg.TLSConfig != "" { 81 return nil, errors.New("do not specify TLS when using the Proxy") 82 } 83 84 // Copy the config so that we can modify it without feeling bad. 85 c := *cfg 86 c.Net = "cloudsql" 87 dsn := c.FormatDSN() 88 89 db, err := sql.Open("mysql", dsn) 90 if err == nil { 91 err = db.Ping() 92 } 93 return db, err 94 } 95