aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/jackc/pgx/fastpath.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jackc/pgx/fastpath.go')
-rw-r--r--vendor/github.com/jackc/pgx/fastpath.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/github.com/jackc/pgx/fastpath.go b/vendor/github.com/jackc/pgx/fastpath.go
new file mode 100644
index 0000000..19b9878
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/fastpath.go
@@ -0,0 +1,108 @@
+package pgx
+
+import (
+ "encoding/binary"
+)
+
+func newFastpath(cn *Conn) *fastpath {
+ return &fastpath{cn: cn, fns: make(map[string]Oid)}
+}
+
+type fastpath struct {
+ cn *Conn
+ fns map[string]Oid
+}
+
+func (f *fastpath) functionOID(name string) Oid {
+ return f.fns[name]
+}
+
+func (f *fastpath) addFunction(name string, oid Oid) {
+ f.fns[name] = oid
+}
+
+func (f *fastpath) addFunctions(rows *Rows) error {
+ for rows.Next() {
+ var name string
+ var oid Oid
+ if err := rows.Scan(&name, &oid); err != nil {
+ return err
+ }
+ f.addFunction(name, oid)
+ }
+ return rows.Err()
+}
+
+type fpArg []byte
+
+func fpIntArg(n int32) fpArg {
+ res := make([]byte, 4)
+ binary.BigEndian.PutUint32(res, uint32(n))
+ return res
+}
+
+func fpInt64Arg(n int64) fpArg {
+ res := make([]byte, 8)
+ binary.BigEndian.PutUint64(res, uint64(n))
+ return res
+}
+
+func (f *fastpath) Call(oid Oid, args []fpArg) (res []byte, err error) {
+ wbuf := newWriteBuf(f.cn, 'F') // function call
+ wbuf.WriteInt32(int32(oid)) // function object id
+ wbuf.WriteInt16(1) // # of argument format codes
+ wbuf.WriteInt16(1) // format code: binary
+ wbuf.WriteInt16(int16(len(args))) // # of arguments
+ for _, arg := range args {
+ wbuf.WriteInt32(int32(len(arg))) // length of argument
+ wbuf.WriteBytes(arg) // argument value
+ }
+ wbuf.WriteInt16(1) // response format code (binary)
+ wbuf.closeMsg()
+
+ if _, err := f.cn.conn.Write(wbuf.buf); err != nil {
+ return nil, err
+ }
+
+ for {
+ var t byte
+ var r *msgReader
+ t, r, err = f.cn.rxMsg()
+ if err != nil {
+ return nil, err
+ }
+ switch t {
+ case 'V': // FunctionCallResponse
+ data := r.readBytes(r.readInt32())
+ res = make([]byte, len(data))
+ copy(res, data)
+ case 'Z': // Ready for query
+ f.cn.rxReadyForQuery(r)
+ // done
+ return
+ default:
+ if err := f.cn.processContextFreeMsg(t, r); err != nil {
+ return nil, err
+ }
+ }
+ }
+}
+
+func (f *fastpath) CallFn(fn string, args []fpArg) ([]byte, error) {
+ return f.Call(f.functionOID(fn), args)
+}
+
+func fpInt32(data []byte, err error) (int32, error) {
+ if err != nil {
+ return 0, err
+ }
+ n := int32(binary.BigEndian.Uint32(data))
+ return n, nil
+}
+
+func fpInt64(data []byte, err error) (int64, error) {
+ if err != nil {
+ return 0, err
+ }
+ return int64(binary.BigEndian.Uint64(data)), nil
+}