From 3659894162c51506a03e4855905091cfd645a99f Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Tue, 24 Sep 2019 12:46:50 -0700 Subject: [PATCH 1/7] Add godocs for SetQueryNotification --- doc/mssql_examples_test.go | 61 ++++++++++++++++++++++++++++++++++++++ mssql.go | 4 +++ 2 files changed, 65 insertions(+) create mode 100644 doc/mssql_examples_test.go diff --git a/doc/mssql_examples_test.go b/doc/mssql_examples_test.go new file mode 100644 index 00000000..bdec8030 --- /dev/null +++ b/doc/mssql_examples_test.go @@ -0,0 +1,61 @@ +package main + +import ( + "flag" + "fmt" + "log" + "time" + + mssql "github.com/denisenkom/go-mssqldb" +) + +var ( + debug = flag.Bool("debug", false, "enable debugging") + password = flag.String("password", "", "the database password") + port *int = flag.Int("port", 1433, "the database port") + server = flag.String("server", "", "the database server") + user = flag.String("user", "", "the database user") + database = flag.String("database", "", "the database name") +) + +func ExampleSetQueryNotification() { + flag.Parse() + + if *debug { + fmt.Printf(" password:%s\n", *password) + fmt.Printf(" port:%d\n", *port) + fmt.Printf(" server:%s\n", *server) + fmt.Printf(" user:%s\n", *user) + fmt.Printf(" database:%s\n", *database) + } + + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", *server, *user, *password, *port, *database) + if *debug { + fmt.Printf(" connString:%s\n", connString) + } + mssqldriver := &mssql.Driver{} + cn, err := mssqldriver.Open(connString) + if err != nil { + log.Fatal("Open connection failed:", err.Error()) + } + defer cn.Close() + conn, _ := cn.(*mssql.Conn) + + // Supported SELECT statements: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105) + stmt, err := conn.Prepare("SELECT [myColumn] FROM [mySchema].[myTable];") + if err != nil { + log.Fatal("Prepare failed:", err.Error()) + } + defer stmt.Close() + + sqlstmt, _ := stmt.(*mssql.Stmt) + defer sqlstmt.Close() + sqlstmt.SetQueryNotification("Message", "service=myService", time.Hour) + + rows, err := sqlstmt.Query(nil) + if err != nil { + log.Fatal("Query failed:", err.Error()) + } else { + rows.Close() + } +} \ No newline at end of file diff --git a/mssql.go b/mssql.go index e37109cd..f968f479 100644 --- a/mssql.go +++ b/mssql.go @@ -396,6 +396,10 @@ func (s *Stmt) Close() error { return nil } +// Sets a Query Notification for the query in Stmt. +// Options must be in the format: +// service=[;(local database= | broker instance=)] +// https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105) func (s *Stmt) SetQueryNotification(id, options string, timeout time.Duration) { to := uint32(timeout / time.Second) if to < 1 { From df965eea03857491c6ecd74c0c277354222e1c3c Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Tue, 29 Oct 2019 17:29:05 -0700 Subject: [PATCH 2/7] add readme on setting up query notifications --- doc/how-to-use-setquerynotification.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 doc/how-to-use-setquerynotification.md diff --git a/doc/how-to-use-setquerynotification.md b/doc/how-to-use-setquerynotification.md new file mode 100644 index 00000000..7102ef59 --- /dev/null +++ b/doc/how-to-use-setquerynotification.md @@ -0,0 +1,25 @@ +# How create a Query Notification + +Query notifications subscriptions can be set on queries to request that the application be notified when the results of the query change. After using the driver's `Conn` type to `Prepare` a query, call `SetQueryNotification()` method to set the contents of the query notification header. + +```go + sqlstmt.SetQueryNotification("Message", "service=myService", time.Hour) +``` + +The parameters of the `SetQueryNotification()` method are: `message`, `options`, and `timeout`. The `options` parameter takes a string containing the service name as well as the database or broker instance. `options` must be in the following format: + +`service=[;(local database= | broker instance=)]` + +The time unit for the `timeout` parameter is milliseconds. +The query for notification must be in the correct [format](https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms175110(v=sql.105)) or the subscription will fail on the server. + +## Example + +[Query Notification Example](..\setquerynotification_example_test.go) + +## Useful Links + +- [Using Query Notifications](https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms175110(v=sql.105)) +- [Working with Query Notifications](https://docs.microsoft.com/en-us/sql/relational-databases/native-client/features/working-with-query-notifications?view=sql-server-2017) +- [Creating a Query for Notification](https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105)) +- [Query Notifications Header](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/e168d373-a7b7-41aa-b6ca-25985466a7e0) \ No newline at end of file From 947a6d7ea5850ae98a13bd4ee17c1e45552a984f Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Wed, 30 Oct 2019 15:21:52 -0700 Subject: [PATCH 3/7] update query notification example --- setquerynotification_example_test.go | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 setquerynotification_example_test.go diff --git a/setquerynotification_example_test.go b/setquerynotification_example_test.go new file mode 100644 index 00000000..12641b6f --- /dev/null +++ b/setquerynotification_example_test.go @@ -0,0 +1,45 @@ +package mssql_test + +import ( + "flag" + "fmt" + "log" + "time" + + mssql "github.com/denisenkom/go-mssqldb" +) + +var ( + database = flag.String("database", "", "the database name") +) + +// This example shows the how to set query notifications +func ExampleStmt_SetQueryNotification() { + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", *server, *user, *password, *port, *database) + + mssqldriver := &mssql.Driver{} + cn, err := mssqldriver.Open(connString) + if err != nil { + log.Fatal("Open connection failed:", err.Error()) + } + defer cn.Close() + conn, _ := cn.(*mssql.Conn) + + // Supported SELECT statements: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105) + stmt, err := conn.Prepare("SELECT [myColumn] FROM [mySchema].[myTable];") + if err != nil { + log.Fatal("Prepare failed:", err.Error()) + } + defer stmt.Close() + + sqlstmt, _ := stmt.(*mssql.Stmt) + defer sqlstmt.Close() + sqlstmt.SetQueryNotification("Message", "service=myService", time.Hour) + + rows, err := sqlstmt.Query(nil) + if err != nil { + log.Fatal("Query failed:", err.Error()) + } else { + rows.Close() + } +} From 47f1070e994b62ed4613014e9d4a11d74708be77 Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Wed, 30 Oct 2019 15:22:50 -0700 Subject: [PATCH 4/7] update comment --- setquerynotification_example_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setquerynotification_example_test.go b/setquerynotification_example_test.go index 12641b6f..2275801b 100644 --- a/setquerynotification_example_test.go +++ b/setquerynotification_example_test.go @@ -13,7 +13,7 @@ var ( database = flag.String("database", "", "the database name") ) -// This example shows the how to set query notifications +// This example shows the how to set query notifications on a pre-existing table func ExampleStmt_SetQueryNotification() { connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", *server, *user, *password, *port, *database) @@ -36,6 +36,7 @@ func ExampleStmt_SetQueryNotification() { defer sqlstmt.Close() sqlstmt.SetQueryNotification("Message", "service=myService", time.Hour) + // Query will return the result of the above select statement and subscription for the query notification will be created. rows, err := sqlstmt.Query(nil) if err != nil { log.Fatal("Query failed:", err.Error()) From ebae1790d2066b7d911587b5c3f39deb94702968 Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Wed, 30 Oct 2019 15:25:50 -0700 Subject: [PATCH 5/7] remove old example --- doc/mssql_examples_test.go | 61 -------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 doc/mssql_examples_test.go diff --git a/doc/mssql_examples_test.go b/doc/mssql_examples_test.go deleted file mode 100644 index bdec8030..00000000 --- a/doc/mssql_examples_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "log" - "time" - - mssql "github.com/denisenkom/go-mssqldb" -) - -var ( - debug = flag.Bool("debug", false, "enable debugging") - password = flag.String("password", "", "the database password") - port *int = flag.Int("port", 1433, "the database port") - server = flag.String("server", "", "the database server") - user = flag.String("user", "", "the database user") - database = flag.String("database", "", "the database name") -) - -func ExampleSetQueryNotification() { - flag.Parse() - - if *debug { - fmt.Printf(" password:%s\n", *password) - fmt.Printf(" port:%d\n", *port) - fmt.Printf(" server:%s\n", *server) - fmt.Printf(" user:%s\n", *user) - fmt.Printf(" database:%s\n", *database) - } - - connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", *server, *user, *password, *port, *database) - if *debug { - fmt.Printf(" connString:%s\n", connString) - } - mssqldriver := &mssql.Driver{} - cn, err := mssqldriver.Open(connString) - if err != nil { - log.Fatal("Open connection failed:", err.Error()) - } - defer cn.Close() - conn, _ := cn.(*mssql.Conn) - - // Supported SELECT statements: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105) - stmt, err := conn.Prepare("SELECT [myColumn] FROM [mySchema].[myTable];") - if err != nil { - log.Fatal("Prepare failed:", err.Error()) - } - defer stmt.Close() - - sqlstmt, _ := stmt.(*mssql.Stmt) - defer sqlstmt.Close() - sqlstmt.SetQueryNotification("Message", "service=myService", time.Hour) - - rows, err := sqlstmt.Query(nil) - if err != nil { - log.Fatal("Query failed:", err.Error()) - } else { - rows.Close() - } -} \ No newline at end of file From 6f7b03e3158a83b73afd97c52cc2af2b73b40e5c Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Wed, 6 Nov 2019 17:32:34 -0800 Subject: [PATCH 6/7] add initialization variables to allow compile --- setquerynotification_example_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setquerynotification_example_test.go b/setquerynotification_example_test.go index 2275801b..987cd4bb 100644 --- a/setquerynotification_example_test.go +++ b/setquerynotification_example_test.go @@ -10,7 +10,11 @@ import ( ) var ( - database = flag.String("database", "", "the database name") + password = flag.String("password", "", "the database password") + port *int = flag.Int("port", 1433, "the database port") + server = flag.String("server", "", "the database server") + user = flag.String("user", "", "the database user") + database = flag.String("database", "", "the database name") ) // This example shows the how to set query notifications on a pre-existing table From 8638508394a1b876e582e7824c1cea2e13957321 Mon Sep 17 00:00:00 2001 From: Christopher Hamilton Date: Wed, 6 Nov 2019 17:52:18 -0800 Subject: [PATCH 7/7] change parameter declaration --- setquerynotification_example_test.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/setquerynotification_example_test.go b/setquerynotification_example_test.go index 987cd4bb..3c73d7bb 100644 --- a/setquerynotification_example_test.go +++ b/setquerynotification_example_test.go @@ -1,7 +1,6 @@ package mssql_test import ( - "flag" "fmt" "log" "time" @@ -9,17 +8,15 @@ import ( mssql "github.com/denisenkom/go-mssqldb" ) -var ( - password = flag.String("password", "", "the database password") - port *int = flag.Int("port", 1433, "the database port") - server = flag.String("server", "", "the database server") - user = flag.String("user", "", "the database user") - database = flag.String("database", "", "the database name") -) - // This example shows the how to set query notifications on a pre-existing table func ExampleStmt_SetQueryNotification() { - connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", *server, *user, *password, *port, *database) + password := "" + port := 1433 + server := "" + user := "" + database := "" + + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", server, user, password, port, database) mssqldriver := &mssql.Driver{} cn, err := mssqldriver.Open(connString)