@@ -16,7 +16,7 @@ const defaultPingInterval = 30 * time.Second
1616const pingTimout = 5 * time .Second
1717const authTimeout = 10 * time .Second
1818const maxReconnectSleep = time .Minute
19- const defaultReconnectionAttempts = 0 // 0 = infinite reconnect attempts
19+ const defaultReconnectionAttempts = 0 // 0 = infinite reconnect attempts
2020
2121type LogLevelType int8
2222
@@ -61,15 +61,14 @@ type Conn struct {
6161//
6262// Example:
6363//
64- // thingsdb.NewConn("localhost", 9200, nil)
64+ // thingsdb.NewConn("localhost", 9200, nil)
6565//
6666// Or, with TLS (SSL) config enabled
6767//
68- // config := &tls.Config{
69- // InsecureSkipVerify: false,
70- // }
71- // thingsdb.NewConn("localhost", 9200, config)
72- //
68+ // config := &tls.Config{
69+ // InsecureSkipVerify: false,
70+ // }
71+ // thingsdb.NewConn("localhost", 9200, config)
7372func NewConn (host string , port uint16 , config * tls.Config ) * Conn {
7473 return & Conn {
7574 // Private
@@ -111,10 +110,9 @@ func NewConn(host string, port uint16, config *tls.Config) *Conn {
111110//
112111// Example:
113112//
114- // conn := thingsdb.NewConn("node1.local", 9200, nil)
115- // conn.AddNode("node2.local", 9200)
116- // conn.AddNode("node3.local", 9200)
117- //
113+ // conn := thingsdb.NewConn("node1.local", 9200, nil)
114+ // conn.AddNode("node2.local", 9200)
115+ // conn.AddNode("node3.local", 9200)
118116func (conn * Conn ) AddNode (host string , port uint16 ) {
119117 conn .nodes = append (conn .nodes , node {host : host , port : port })
120118}
@@ -123,8 +121,7 @@ func (conn *Conn) AddNode(host string, port uint16) {
123121//
124122// Example:
125123//
126- // thingsdb.NewConn("localhost", 9200, nil).ToString() // "localhost:9200"
127- //
124+ // thingsdb.NewConn("localhost", 9200, nil).ToString() // "localhost:9200"
128125func (conn * Conn ) ToString () string {
129126 node := conn .node ()
130127 if strings .Count (node .host , ":" ) > 0 {
@@ -189,70 +186,96 @@ func (conn *Conn) IsConnected() bool {
189186//
190187// Example:
191188//
192- // if res, err := conn.Query("/t", "'Hello Go Connector for ThingsDB!!';", nil); err == nil {
193- // fmt.Println(res) // "Hello Go Connector for ThingsDB!!"
194- // }
189+ // if res, err := conn.Query("/t", "'Hello Go Connector for ThingsDB!!';", nil); err == nil {
190+ // fmt.Println(res) // "Hello Go Connector for ThingsDB!!"
191+ // }
195192//
196193// Arguments can be provided using a `map[string]interface{}`, for example:
197194//
198- // vars := map[string]interface{}{
199- // "name": "Alice",
200- // }
201- //
202- // if res, err := conn.Query("/t", "`Hello {name}!!`;", vars); err == nil {
203- // fmt.Println(res) // "Hello Alice!!"
204- // }
195+ // vars := map[string]interface{}{
196+ // "name": "Alice",
197+ // }
205198//
199+ // if res, err := conn.Query("/t", "`Hello {name}!!`;", vars); err == nil {
200+ // fmt.Println(res) // "Hello Alice!!"
201+ // }
206202func (conn * Conn ) Query (scope string , code string , vars map [string ]interface {}) (interface {}, error ) {
203+ var result interface {}
207204 data := []interface {}{scope , code }
208205 if vars != nil {
209206 data = append (data , vars )
210207 }
208+ res , err := conn .ensureWrite (ProtoReqQuery , data )
209+ if err == nil {
210+ err = msgpack .Unmarshal (res , & result )
211+ }
212+ return result , err
213+ }
211214
215+ // QueryRaw is like Query except a raw []byte array is returned
216+ func (conn * Conn ) QueryRaw (scope string , code string , vars map [string ]interface {}) ([]byte , error ) {
217+ data := []interface {}{scope , code }
218+ if vars != nil {
219+ data = append (data , vars )
220+ }
212221 return conn .ensureWrite (ProtoReqQuery , data )
213222}
214223
215224// Run a procedure in ThingsDB. Arguments are optional and may be either positional `[]interface{}` or by map `map[string]interface{}`.
216225//
217226// Example without arguments:
218227//
219- // // Suppose collection `stuff` has the following procedure:
220- // // new_procedure('greet', || 'Hi');
228+ // // Suppose collection `stuff` has the following procedure:
229+ // // new_procedure('greet', || 'Hi');
221230//
222- // if res, err := conn.Run("//stuff", "greet", nil); err == nil {
223- // fmt.Println(res) // "Hi"
224- // }
231+ // if res, err := conn.Run("//stuff", "greet", nil); err == nil {
232+ // fmt.Println(res) // "Hi"
233+ // }
225234//
226235// Example using positional arguments:
227236//
228- // // Suppose collection `stuff` has the following procedure:
229- // // new_procedure('subtract', |a, b| a - b);
237+ // // Suppose collection `stuff` has the following procedure:
238+ // // new_procedure('subtract', |a, b| a - b);
230239//
231- // args := []interface{}{40, 10}
240+ // args := []interface{}{40, 10}
232241//
233- // if res, err := conn.Run("//stuff", "subtract", args); err == nil {
234- // fmt.Println(res) // 30
235- // }
242+ // if res, err := conn.Run("//stuff", "subtract", args); err == nil {
243+ // fmt.Println(res) // 30
244+ // }
236245//
237246// Example using mapped arguments:
238247//
239- // // Suppose collection `stuff` has the following procedure:
240- // // new_procedure('subtract', |a, b| a - b);
248+ // // Suppose collection `stuff` has the following procedure:
249+ // // new_procedure('subtract', |a, b| a - b);
250+ //
251+ // args := map[string]interface{}{
252+ // "a": 15,
253+ // "b": 5,
254+ // }
255+ // if res, err := conn.Run("//stuff", "subtract", args); err == nil {
256+ // fmt.Println(res) // 10
257+ // }
241258//
242- // args := map[string]interface{}{
243- // "a": 15,
244- // "b": 5,
245- // }
246- // if res, err := conn.Run("//stuff", "subtract", args); err == nil {
247- // fmt.Println(res) // 10
248- // }
249259// ```
250260func (conn * Conn ) Run (scope string , procedure string , args interface {}) (interface {}, error ) {
261+ var result interface {}
251262 data := []interface {}{scope , procedure }
252263 if args != nil {
253264 data = append (data , args )
254265 }
266+ res , err := conn .ensureWrite (ProtoReqRun , data )
267+ if err == nil {
268+ err = msgpack .Unmarshal (res , & result )
269+ }
270+ return result , err
271+ }
255272
273+ // RunRaw is like Query except a raw []byte array is returned
274+ func (conn * Conn ) RunRaw (scope string , procedure string , args interface {}) ([]byte , error ) {
275+ data := []interface {}{scope , procedure }
276+ if args != nil {
277+ data = append (data , args )
278+ }
256279 return conn .ensureWrite (ProtoReqRun , data )
257280}
258281
@@ -263,15 +286,14 @@ func (conn *Conn) Run(scope string, procedure string, args interface{}) (interfa
263286//
264287// Example:
265288//
266- // args := []interface{}{"This is a message"}
267- //
268- // err := conn.Emit(
269- // "//stuff", // scope of the Room
270- // 123, // Room Id
271- // "new-message", // Event to emit
272- // args // Arguments (may be nil)
273- // );
289+ // args := []interface{}{"This is a message"}
274290//
291+ // err := conn.Emit(
292+ // "//stuff", // scope of the Room
293+ // 123, // Room Id
294+ // "new-message", // Event to emit
295+ // args // Arguments (may be nil)
296+ // );
275297func (conn * Conn ) Emit (scope string , roomId uint64 , event string , args []interface {}) error {
276298 data := []interface {}{scope , roomId , event }
277299 if args != nil {
@@ -345,17 +367,20 @@ func (conn *Conn) connect() error {
345367}
346368
347369func (conn * Conn ) joinOrLeave (proto Proto , scope string , ids []* uint64 ) error {
370+ var result interface {}
348371 data := make ([]interface {}, 1 + len (ids ))
349372 data [0 ] = scope
350373 for i , v := range ids {
351374 data [1 + i ] = v
352375 }
353376 res , err := conn .ensureWrite (proto , data )
354-
355377 if err == nil {
356- arr , ok := res .([]interface {})
378+ err = msgpack .Unmarshal (res , & result )
379+ }
380+ if err == nil {
381+ arr , ok := result .([]interface {})
357382 if ! ok {
358- return fmt .Errorf ("unexpected Join response: %v" , res )
383+ return fmt .Errorf ("unexpected Join response: %v" , result )
359384 }
360385 for i , val := range arr {
361386 switch val .(type ) {
@@ -375,8 +400,8 @@ func (conn *Conn) leave(scope string, ids []*uint64) error {
375400 return conn .joinOrLeave (ProtoReqLeave , scope , ids )
376401}
377402
378- func getResult (respCh chan * pkg , timeoutCh chan bool ) (interface {} , error ) {
379- var result interface {}
403+ func getResult (respCh chan * pkg , timeoutCh chan bool ) ([] byte , error ) {
404+ var result [] byte
380405 var err error
381406
382407 select {
@@ -386,7 +411,8 @@ func getResult(respCh chan *pkg, timeoutCh chan bool) (interface{}, error) {
386411 } else {
387412 switch Proto (pkg .tp ) {
388413 case ProtoResData :
389- err = msgpack .Unmarshal (pkg .data , & result )
414+ result = pkg .data
415+ pkg .data = nil
390416 case ProtoResPong , ProtoResOk :
391417 result = nil
392418 case ProtoResError :
@@ -410,7 +436,7 @@ func (conn *Conn) nextPid() uint16 {
410436 return pid
411437}
412438
413- func (conn * Conn ) getRespCh (pid uint16 , b []byte , timeout time.Duration ) (interface {} , error ) {
439+ func (conn * Conn ) getRespCh (pid uint16 , b []byte , timeout time.Duration ) ([] byte , error ) {
414440 var err error
415441 respCh := make (chan * pkg , 1 )
416442
@@ -445,7 +471,7 @@ func (conn *Conn) getRespCh(pid uint16, b []byte, timeout time.Duration) (interf
445471 return result , err
446472}
447473
448- func (conn * Conn ) ensureWrite (tp Proto , data interface {}) (interface {} , error ) {
474+ func (conn * Conn ) ensureWrite (tp Proto , data interface {}) ([] byte , error ) {
449475
450476 pid := conn .nextPid ()
451477 b , err := pkgPack (pid , tp , data )
0 commit comments