Пример #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
}