Beispiel #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
}
Beispiel #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
}
Beispiel #3
0
func prepare(conn *PgConn, query string) (*PgStmt, error) {
	name := C.CString("")
	defer C.free(unsafe.Pointer(name))
	cquery := C.CString(query)
	defer C.free(unsafe.Pointer(cquery))
	res := C.PQprepare(conn.conn, name, cquery, 0, nil)

	if err := errorFromPGresult(res); err != nil {
		pqclear(res)
		return &PgStmt{}, err
	}

	stmt := PgStmt{conn: conn, result: res, name: ""}
	return &stmt, nil
}
Beispiel #4
0
func (self *pqConnection) pqPrepare(query string, types ...interface{}) *pqStatement {
	res := new(pqStatement)
	// TODO: is the current system time goog enough?
	secs, _, _ := os.Time()
	res.stmtName = strconv.Itoa64(secs)

	nameC := C.CString(res.stmtName)
	queryC := C.CString(query)

	// TODO: error check here :| yikes
	_ = C.PQprepare(self.handle, nameC, queryC, 0, nil)

	C.free(unsafe.Pointer(nameC))
	C.free(unsafe.Pointer(queryC))
	return res
}
Beispiel #5
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
}