pgsql.go icon indicating copy to clipboard operation
pgsql.go copied to clipboard

COPY from stdin?

Open bd4k opened this issue 14 years ago • 0 comments

may be add few lines of code like:

    func resultStatus(res *C.PGresult) (int) {
    return  int(C.PQresultStatus(res))
    }


func (c *Conn) CopyFrom(stmt string, reader io.Reader) os.Error {
       // buffer
    sb := [1024]byte{}

    stmtstr := C.CString(stmt)
    defer C.free(unsafe.Pointer(stmtstr))
    cres := C.PQexec(c.db, stmtstr)
    defer C.PQclear(cres)
       // check for ready
    if resultStatus(cres) != C.PGRES_COPY_IN {
        return resultError(cres)
    }
L:     // main loop
    for {

        n, e := reader.Read(sb[:]) 
        if n > 0 {
            switch C.PQputCopyData(c.db, (*C.char)(unsafe.Pointer(&sb[0])), C.int(n)) {
                        // block send ok
            case 1:
                continue L
                        // in manual for nonblocking connection , may be not need
            case 0:
                return os.NewError("COPY: connection blocked")
                        //  error
            case -1:
                return connError(c.db)
            }
        } else {
            if e != os.EOF {
                return e
            }
                        //  send "EOF" marker
            switch C.PQputCopyEnd(c.db, nil) {
                        // in manual for nonblocking connection , may be not need
            case 0:
                return os.NewError("COPY: connection blocked")
                        //  error
            case -1:
                return connError(c.db)
            }

                        //  read summary of COPY
            cres = C.PQgetResult(c.db)
            println(resultStatus(cres))
            defer C.PQclear(cres)
            return resultError(cres)
        }
    }
    return nil
}

use that expromt like:

  func bye(e os.Error) {
    if e != nil {
        println(e.String())
        os.Exit(1)
    }
  }
  func main(){
    c, e := pgsql.Connect("....")
    defer c.Close()
    bye(e)
    e=c.Exec("begin")
    bye(e)
    e=c.Exec("create temp table a( b text, c text)on commit drop;")
    bye(e)
    e=c.Exec("create temp table b( d text, e text)on commit drop;")
    bye(e)
        // prepare test reader data
    testfile := bytes.NewBufferString(" row11\trow12\nrow21\trow22\n") 
       // send data to pg server
    e = c.CopyFrom("copy b(d,e) from stdin;\n", testfile)
    bye(e)
        // any commands after copy
    e=c.Exec("insert into a select d,e from b except select b,c from a;")
    bye(e)
    e=c.Exec("end;")
    bye(e)
    println("complete")
  }

this badcode work well) But, need some rewrites )))

bd4k avatar Feb 09 '12 12:02 bd4k