Skip to content

Commit 8fba7d9

Browse files
committed
[MySQL] Add connection attribute example for Go
See - Pull Request: go-sql-driver/mysql#1389 - Release: https://github.com/go-sql-driver/mysql/releases/tag/v1.8.0
1 parent 4f2b470 commit 8fba7d9

File tree

5 files changed

+173
-1
lines changed

5 files changed

+173
-1
lines changed

mysql/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Programmming languages:
88

99
- [Python (with PyMySQL)](./python-PyMySQL)
1010
- [Python (with mysql-connector-python)](./python-mysql-connector-python)
11-
- Go: Not supported yet, see [Support for sending connection attributes #737 @ go-sql-driver/mysql](https://github.com/go-sql-driver/mysql/pull/737)
11+
- [Go](./go)
1212
- PHP: Not supported yet, see [Add possibility to add MySQL Connection Attributes (incl. custom ones) @ PHP Bugtracker](https://bugs.php.net/bug.php?id=81314)
1313

1414
## How it works

mysql/go/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
![MySQL logo](../../images/mysql-logo.png)
2+
3+
# your _MySQL_ connection deserves a name: Go edition (with github.com/go-sql-driver/mysql)
4+
5+
An example on how to assign a name to a [MySQL](https://www.mysql.com/) connection in Go.
6+
7+
## Get it running
8+
9+
1. Start the MySQL docker container:
10+
```sh
11+
$ docker run --rm \
12+
--publish 3306:3306 \
13+
--env MYSQL_ROOT_PASSWORD=secret \
14+
--env MYSQL_DATABASE=dummy \
15+
--name ycdan-mysql \
16+
--detach \
17+
mysql:8.0.36 mysqld --default-authentication-plugin=mysql_native_password
18+
```
19+
20+
2. Compile the example program:
21+
```sh
22+
$ go build -o your-connection-deserves-a-name
23+
```
24+
25+
3. Start the example program:
26+
```sh
27+
$ ./your-connection-deserves-a-name
28+
```
29+
30+
You should see something like
31+
32+
```
33+
2024/03/17 09:04:05 Connecting to MySQL on root:secret@tcp(127.0.0.1:3306)/dummy?connectionAttributes=program_name:currency-conversion-app
34+
2024/03/17 09:04:05 Connecting to MySQL on root:secret@tcp(127.0.0.1:3306)/dummy?connectionAttributes=program_name:currency-conversion-app ... Successful
35+
2024/03/17 09:04:05
36+
2024/03/17 09:04:05 Keeping the connection open ...
37+
2024/03/17 09:04:05 You can connect to the MySQL database and execute the query:
38+
2024/03/17 09:04:05 SELECT
39+
2024/03/17 09:04:05 session_connect_attrs.ATTR_VALUE AS program_name,
40+
2024/03/17 09:04:05 processlist.*
41+
2024/03/17 09:04:05 FROM information_schema.processlist
42+
2024/03/17 09:04:05 LEFT JOIN performance_schema.session_connect_attrs ON (
43+
2024/03/17 09:04:05 processlist.ID = session_connect_attrs.PROCESSLIST_ID
44+
2024/03/17 09:04:05 AND session_connect_attrs.ATTR_NAME = "program_name"
45+
2024/03/17 09:04:05 )
46+
2024/03/17 09:04:05 Hit CTRL + C or cancel the process to stop.
47+
2024/03/17 09:04:05
48+
```
49+
50+
4. Login into your database and execute the query:
51+
```sql
52+
SELECT
53+
session_connect_attrs.ATTR_VALUE AS program_name,
54+
processlist.*
55+
FROM information_schema.processlist
56+
LEFT JOIN performance_schema.session_connect_attrs ON (
57+
processlist.ID = session_connect_attrs.PROCESSLIST_ID
58+
AND session_connect_attrs.ATTR_NAME = "program_name"
59+
)
60+
```
61+
62+
The result should look similar to:
63+
64+
```
65+
program_name | ID | USER | HOST | DB | [...]
66+
--------------------+----+------+------------------+-------+------
67+
unit-conversion-app | 11 | root | 172.17.0.1:56382 | dummy | [...]
68+
```
69+
70+
## Don't know what this is all about?
71+
72+
Read the original blog post [_your database connection deserves a name @ andygrunwald.com_](https://andygrunwald.com/blog/your-database-connection-deserves-a-name/ "Article your database connection deserves a name at Andy Grunwalds blog").
73+
74+
Additionally, you can check out the [projects README](https://github.com/andygrunwald/your-connection-deserves-a-name#readme).

mysql/go/go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/andygrunwald/your-connection-deserves-a-name/mysql/go
2+
3+
go 1.22.1
4+
5+
require (
6+
filippo.io/edwards25519 v1.1.0 // indirect
7+
github.com/go-sql-driver/mysql v1.8.0 // indirect
8+
)

mysql/go/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
2+
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
3+
github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4=
4+
github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=

mysql/go/main.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package main
2+
3+
import (
4+
"database/sql"
5+
"fmt"
6+
"log"
7+
"net/url"
8+
"time"
9+
10+
_ "github.com/go-sql-driver/mysql"
11+
)
12+
13+
const (
14+
MySQLUsername = "root"
15+
MySQLPassword = "secret"
16+
MySQLHostname = "127.0.0.1"
17+
MySQLPort = 3306
18+
MySQLDatabase = "dummy"
19+
ConnectionAttributeName = "program_name"
20+
ConnectionName = "currency-conversion-app"
21+
)
22+
23+
func main() {
24+
// Doing all the magic: Setting a proper connection/application name.
25+
//
26+
// Connection attributes are key-value pairs that application programs can pass to the server at connect time.
27+
// This property can be added to the connection string.
28+
//
29+
// The application name will be maintained in the `session_connect_attrs` table of your MySQL-Server.
30+
//
31+
// MySQL docs:
32+
// - Performance Schema Connection Attribute Tables: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html
33+
// - Connection Attribute Limits: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html#performance-schema-connection-attribute-limits
34+
35+
dsn := fmt.Sprintf("%s@tcp(%s:%d)/%s?connectionAttributes=%s:%s", url.UserPassword(MySQLUsername, MySQLPassword), MySQLHostname, MySQLPort, MySQLDatabase, ConnectionAttributeName, ConnectionName)
36+
37+
// Building the connection
38+
log.Printf("Connecting to MySQL on %s\n", dsn)
39+
client, err := sql.Open("mysql", dsn)
40+
if err != nil {
41+
panic(err)
42+
}
43+
defer func() {
44+
if err = client.Close(); err != nil {
45+
panic(err)
46+
}
47+
}()
48+
49+
// Dummy values for demo purpose
50+
client.SetConnMaxLifetime(time.Minute * 3)
51+
client.SetMaxOpenConns(10)
52+
client.SetMaxIdleConns(10)
53+
54+
// Establish the connection, because depending on the DB driver, we might only
55+
// validate the credentials, but don't built up a connection.
56+
err = client.Ping()
57+
if err != nil {
58+
panic(err)
59+
}
60+
log.Printf("Connecting to MySQL on %s ... Successful\n", dsn)
61+
62+
log.Println("")
63+
log.Println("Keeping the connection open ...")
64+
log.Println("You can connect to the MySQL database and execute the query:")
65+
log.Println(" SELECT")
66+
log.Println(" session_connect_attrs.ATTR_VALUE AS program_name,")
67+
log.Println(" processlist.*")
68+
log.Println(" FROM information_schema.processlist")
69+
log.Println(" LEFT JOIN performance_schema.session_connect_attrs ON (")
70+
log.Println(" processlist.ID = session_connect_attrs.PROCESSLIST_ID")
71+
log.Println(" AND session_connect_attrs.ATTR_NAME = \"program_name\"")
72+
log.Println(" )")
73+
log.Println("Hit CTRL + C or cancel the process to stop.")
74+
log.Println("")
75+
76+
// Just looping to keep the process running.
77+
// In detail we do not keep the connection active, but rely on the standard timeout.
78+
// This way we provide time for the user to check the connection name behaviour.
79+
for {
80+
err = client.Ping()
81+
if err != nil {
82+
panic(err)
83+
}
84+
time.Sleep(5 * time.Second)
85+
}
86+
}

0 commit comments

Comments
 (0)