From d306d42afb42480ef491ec06144c6b4ae28a8e69 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Tue, 16 Apr 2013 20:13:06 -0500 Subject: [PATCH] Added conn.Execute to run arbitrary SQL without a result set fixed #13 --- conn.go | 31 +++++++++++++++++++++++++++++++ conn_test.go | 29 +++++++++++++++++++++++++++++ messages.go | 1 + 3 files changed, 61 insertions(+) diff --git a/conn.go b/conn.go index 6b210043..1e705571 100644 --- a/conn.go +++ b/conn.go @@ -280,6 +280,35 @@ func (c *conn) sendSimpleQuery(sql string) (err error) { return err } +func (c *conn) Execute(sql string) (commandTag string, err error) { + if err = c.sendSimpleQuery(sql); err != nil { + return + } + + for { + var t byte + var r *messageReader + if t, r, err = c.rxMsg(); err == nil { + switch t { + case readyForQuery: + return + case rowDescription: + case dataRow: + case commandComplete: + commandTag = r.readString() + default: + if err = c.processContextFreeMsg(t, r); err != nil { + return + } + } + } else { + return + } + } + + panic("Unreachable") +} + // Processes messages that are not exclusive to one context such as // authentication or query response. The response to these messages // is the same regardless of when they occur. @@ -290,6 +319,8 @@ func (c *conn) processContextFreeMsg(t byte, r *messageReader) (err error) { return nil case errorResponse: return c.rxErrorResponse(r) + case noticeResponse: + return nil default: return fmt.Errorf("Received unknown message type: %c", t) } diff --git a/conn_test.go b/conn_test.go index 4fc4ea9a..c638c39c 100644 --- a/conn_test.go +++ b/conn_test.go @@ -86,6 +86,35 @@ func TestConnectWithMD5Password(t *testing.T) { } } +func TestExecute(t *testing.T) { + conn := getSharedConn() + + results, err := conn.Execute("create temporary table foo(id serial primary key);") + if err != nil { + t.Fatal("Execute failed: " + err.Error()) + } + if results != "CREATE TABLE" { + t.Error("Unexpected results from Execute") + } + + results, err = conn.Execute("drop table foo;") + if err != nil { + t.Fatal("Execute failed: " + err.Error()) + } + if results != "DROP TABLE" { + t.Error("Unexpected results from Execute") + } + + // Multiple statements can be executed -- last command tag is returned + results, err = conn.Execute("create temporary table foo(id serial primary key); drop table foo;") + if err != nil { + t.Fatal("Execute failed: " + err.Error()) + } + if results != "DROP TABLE" { + t.Error("Unexpected results from Execute") + } +} + func TestQuery(t *testing.T) { conn := getSharedConn() diff --git a/messages.go b/messages.go index 78a626c1..53aa0369 100644 --- a/messages.go +++ b/messages.go @@ -16,6 +16,7 @@ const ( dataRow = 'D' commandComplete = 'C' errorResponse = 'E' + noticeResponse = 'N' ) type startupMessage struct {