예제 #1
0
func (c *driverConn) Prepare(query string) (driver.Stmt, error) {
	// Generate unique statement name.
	stmtname := strconv.Itoa(c.stmtNum)
	cstmtname := C.CString(stmtname)
	c.stmtNum++
	defer C.free(unsafe.Pointer(cstmtname))
	stmtstr := C.CString(query)
	defer C.free(unsafe.Pointer(stmtstr))
	res := C.PQprepare(c.db, cstmtname, stmtstr, 0, nil)
	err := resultError(res)
	if err != nil {
		C.PQclear(res)
		return nil, err
	}
	stmtinfo := C.PQdescribePrepared(c.db, cstmtname)
	err = resultError(stmtinfo)
	if err != nil {
		C.PQclear(stmtinfo)
		return nil, err
	}
	defer C.PQclear(stmtinfo)
	nparams := int(C.PQnparams(stmtinfo))
	statement := &driverStmt{stmtname, c.db, res, nparams}
	runtime.SetFinalizer(statement, (*driverStmt).Close)
	return statement, nil
}
예제 #2
0
func (c *libpqConn) Prepare(query string) (driver.Stmt, error) {
	// check our connection's query cache to see if we've already prepared this
	cached, ok := c.stmtCache[query]
	if ok {
		return cached, nil
	}

	// create unique statement name
	// NOTE: do NOT free cname here because it is cached in c.stmtCache;
	//       all cached statement names are freed in c.Close()
	cname := C.CString(strconv.Itoa(c.stmtNum))
	c.stmtNum++
	cquery := C.CString(query)
	defer C.free(unsafe.Pointer(cquery))

	// initial query preparation
	cres := C.PQprepare(c.db, cname, cquery, 0, nil)
	defer C.PQclear(cres)
	if err := resultError(cres); err != nil {
		return nil, err
	}

	// get number of parameters in this query
	cinfo := C.PQdescribePrepared(c.db, cname)
	defer C.PQclear(cinfo)
	if err := resultError(cinfo); err != nil {
		return nil, err
	}
	nparams := int(C.PQnparams(cinfo))

	// save statement in cache
	stmt := &libpqStmt{c: c, name: cname, query: query, nparams: nparams}
	c.stmtCache[query] = stmt
	return stmt, nil
}
예제 #3
0
func (s *libpqStmt) exec(args []driver.Value) (*C.PGresult, error) {
	// if we have no arguments, use plain exec instead of more complicated PQexecPrepared
	if len(args) == 0 {
		if s.cquery == nil {
			s.cquery = C.CString(s.query)
		}
		cres := C.PQexec(s.c.db, s.cquery)
		if err := resultError(cres); err != nil {
			C.PQclear(cres)
			return nil, err
		}
		return cres, nil
	}

	// convert args into C array-of-strings
	cargs, err := buildCArgs(args)
	if err != nil {
		return nil, err
	}
	defer returnCharArrayToPool(len(args), cargs)

	// execute
	cres := C.PQexecPrepared(s.c.db, s.name, C.int(len(args)), cargs, nil, nil, 0)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return nil, err
	}
	return cres, nil
}
예제 #4
0
func (s *driverStmt) Exec(args []driver.Value) (res driver.Result, err error) {
	cres := s.exec(args)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return
	}
	defer C.PQclear(cres)
	rowsAffected, err := strconv.ParseInt(C.GoString(C.PQcmdTuples(cres)), 10, 64)
	if err != nil {
		return
	}
	return driver.RowsAffected(rowsAffected), nil
}
예제 #5
0
// Clear frees the memory associated with the result.  Cleared results should
// not be subsequently used.
func (r *Result) Clear() {
	if r.res != nil {
		C.PQclear(r.res)
		r.res = nil
		runtime.SetFinalizer(r, nil)
	}
}
예제 #6
0
func (s *driverStmt) Close() error {
	if s != nil && s.res != nil {
		C.PQclear(s.res)
		runtime.SetFinalizer(s, nil)
	}
	return nil
}
예제 #7
0
// Execute a query with 1 or more parameters.
func (c *libpqConn) execParams(cmd string, args []driver.Value) (driver.Result, error) {
	// convert args into C array-of-strings
	cargs, err := buildCArgs(args)
	if err != nil {
		return nil, err
	}
	defer returnCharArrayToPool(len(args), cargs)

	ccmd := C.CString(cmd)
	defer C.free(unsafe.Pointer(ccmd))

	// execute
	cres := C.PQexecParams(c.db, ccmd, C.int(len(args)), nil, cargs, nil, nil, 0)
	defer C.PQclear(cres)
	if err = resultError(cres); err != nil {
		return nil, err
	}

	// get modified rows
	nrows, err := getNumRows(cres)
	if err != nil {
		return nil, err
	}

	return libpqResult(nrows), nil
}
예제 #8
0
// Query executes the prepared statement with the given parameters, returning a
// Result on successful execution.
func (s *Statement) Query(params ...interface{}) (res *Result, err os.Error) {
	cres := s.exec(params...)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return
	}
	return newResult(cres), nil
}
예제 #9
0
// Query executes the given SQL query with the given parameters, returning a
// Result on successful execution.
func (c *Conn) Query(query string, params ...interface{}) (res *Result, err os.Error) {
	cres := c.exec(query, params...)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return
	}
	return newResult(cres), nil
}
예제 #10
0
func (r *driverRows) Close() error {
	if r.res != nil {
		C.PQclear(r.res)
		r.res = nil
		runtime.SetFinalizer(r, nil)
	}
	return nil
}
예제 #11
0
func (c *driverConn) Exec(query string, args []driver.Value) (res driver.Result, err error) {
	cres := c.exec(query, args)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return
	}
	defer C.PQclear(cres)
	ns := C.GoString(C.PQcmdTuples(cres))
	if ns == "" {
		return driver.ResultNoRows, nil
	}
	rowsAffected, err := strconv.ParseInt(ns, 10, 64)
	if err != nil {
		return
	}
	return driver.RowsAffected(rowsAffected), nil
}
예제 #12
0
func (s *driverStmt) Query(args []driver.Value) (driver.Rows, error) {
	cres := s.exec(args)
	if err := resultError(cres); err != nil {
		C.PQclear(cres)
		return nil, err
	}
	return newResult(cres), nil
}
예제 #13
0
func (s *libpqStmt) Exec(args []driver.Value) (driver.Result, error) {
	// execute prepared statement
	cres, err := s.exec(args)
	if err != nil {
		return nil, err
	}
	defer C.PQclear(cres)

	nrows, err := getNumRows(cres)
	if err != nil {
		return nil, err
	}

	return libpqResult(nrows), nil
}
예제 #14
0
func (s *libpqStmt) exec(args []driver.Value) (*C.PGresult, error) {
	// convert args into C array-of-strings
	cargs, err := buildCArgs(args)
	if err != nil {
		return nil, err
	}
	defer returnCharArrayToPool(len(args), cargs)

	// execute
	cres := C.PQexecPrepared(s.c.db, s.name, C.int(len(args)), cargs, nil, nil, 0)
	if err = resultError(cres); err != nil {
		C.PQclear(cres)
		return nil, err
	}
	return cres, nil
}
예제 #15
0
func (d *libpqDriver) getOids(db *C.PGconn, dsn string) (*pqoid, error) {
	var err error
	d.Lock()
	defer d.Unlock()

	// check cache
	if oids, ok := d.oids[dsn]; ok {
		return oids, nil
	}

	// not in cache - query the database
	oids := &pqoid{}
	names := []struct {
		kind string
		dest *int
	}{
		{"'bytea'", &oids.Bytea},
		{"'date'", &oids.Date},
		{"'timestamp'", &oids.Timestamp},
		{"'timestamp with time zone'", &oids.TimestampTz},
		{"'time'", &oids.Time},
		{"'time with time zone'", &oids.TimeTz},
	}

	// fetch all the OIDs we care about
	for _, n := range names {
		ccmd := C.CString("SELECT " + n.kind + "::regtype::oid")
		defer C.free(unsafe.Pointer(ccmd))
		cres := C.PQexec(db, ccmd)
		defer C.PQclear(cres)
		if err := resultError(cres); err != nil {
			return nil, err
		}
		sval := C.GoString(C.PQgetvalue(cres, 0, 0))
		*n.dest, err = strconv.Atoi(sval)
		if err != nil {
			return nil, ErrFetchingOids
		}
	}

	// save in cache for next time
	d.oids[dsn] = oids

	return oids, nil
}
예제 #16
0
// Prepare creates and returns a prepared statement with the given SQL statement.
func (c *Conn) Prepare(stmt string) (*Statement, os.Error) {
	// Generate unique statement name.
	stmtname := strconv.Itoa(c.stmtNum)
	stmtnamestr := C.CString(stmtname)
	c.stmtNum++
	defer C.free(unsafe.Pointer(stmtnamestr))
	stmtstr := C.CString(stmt)
	defer C.free(unsafe.Pointer(stmtstr))
	res := C.PQprepare(c.db, stmtnamestr, stmtstr, 0, nil)
	err := resultError(res)
	if err != nil {
		C.PQclear(res)
		return nil, err
	}
	statement := &Statement{stmtname, c.db, res}
	runtime.SetFinalizer(statement, (*Statement).Clear)
	return statement, nil
}
예제 #17
0
// Execute a query, possibly getting a result object (unless the caller doesn't
// want it, as in the case of BEGIN/COMMIT/ROLLBACK).
// the caller doesn't care about that (e.g., Begin(), Commit(), Rollback()).
//func (c *libpqConn) exec(cmd string, res *libpqResult) error {
func (c *libpqConn) exec(cmd string, wantResult bool) (driver.Result, error) {
	ccmd := C.CString(cmd)
	defer C.free(unsafe.Pointer(ccmd))
	cres := C.PQexec(c.db, ccmd)
	defer C.PQclear(cres)
	if err := resultError(cres); err != nil {
		return nil, err
	}

	if !wantResult {
		return nil, nil
	}

	nrows, err := getNumRows(cres)
	if err != nil {
		return nil, err
	}

	return libpqResult(nrows), nil
}
예제 #18
0
func (s *libpqStmt) Query(args []driver.Value) (driver.Rows, error) {
	// execute prepared statement
	cres, err := s.exec(args)
	if err != nil {
		return nil, err
	}

	// check to see if this was a "LISTEN"
	if C.GoString(C.PQcmdStatus(cres)) == "LISTEN" {
		C.PQclear(cres)
		return &libpqListenRows{s.c}, nil
	}

	return &libpqRows{
		s:       s,
		res:     cres,
		ncols:   int(C.PQnfields(cres)),
		nrows:   int(C.PQntuples(cres)),
		currRow: 0,
		cols:    nil,
	}, nil
}
예제 #19
0
// Exec executes the given SQL query with the given parameters.
func (c *Conn) Exec(cmd string, params ...interface{}) os.Error {
	cres := c.exec(cmd, params...)
	defer C.PQclear(cres)
	return resultError(cres)
}
예제 #20
0
// Exec executes the prepared statement with the given parameters.
func (s *Statement) Exec(params ...interface{}) os.Error {
	cres := s.exec(params...)
	defer C.PQclear(cres)
	return resultError(cres)
}
예제 #21
0
파일: pq.go 프로젝트: dvarrazzo/pger
func pqclear(res *C.PGresult) {
	C.PQclear(res)
}
예제 #22
0
func (r *libpqRows) Close() error {
	C.PQclear(r.res)
	return nil
}
예제 #23
0
// Clear frees the memory associated with the statement.  Cleared statements should
// not be subsequently used.
func (s *Statement) Clear() {
	if s != nil && s.res != nil {
		C.PQclear(s.res)
		runtime.SetFinalizer(s, nil)
	}
}