Beispiel #1
1
func (c *sqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
	n, err := c.conn.Execute(query, paramsFromValues(nil, args)...)
	if err != nil {
		return nil, err
	}

	return driver.RowsAffected(n), nil
}
Beispiel #2
0
func (stmt *cypherStmt) Exec(args []driver.Value) (driver.Result, error) {
	if stmt.c.transaction != nil {
		err := stmt.c.transaction.query(stmt.query, args)
		// TODO add counts and error support
		return driver.RowsAffected(0), err
	}
	rows, err := stmt.Query(args)
	if rows != nil {
		defer rows.Close()
	}
	// TODO add counts and error support
	return driver.RowsAffected(0), err
}
Beispiel #3
0
func (c *conn) exec(stmt parser.Statement, args []driver.Value) (driver.Result, error) {
	rows, err := c.query(stmt, args)
	if err != nil {
		return nil, err
	}
	return driver.RowsAffected(len(rows.rows)), nil
}
func (s *fakeStmt) execInsert(args []driver.Value) (driver.Result, error) {
	db := s.c.db
	if len(args) != s.placeholders {
		panic("error in pkg db; should only get here if size is correct")
	}
	db.mu.Lock()
	t, ok := db.table(s.table)
	db.mu.Unlock()
	if !ok {
		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
	}

	t.mu.Lock()
	defer t.mu.Unlock()

	cols := make([]interface{}, len(t.colname))
	argPos := 0
	for n, colname := range s.colName {
		colidx := t.columnIndex(colname)
		if colidx == -1 {
			return nil, fmt.Errorf("fakedb: column %q doesn't exist or dropped since prepared statement was created", colname)
		}
		var val interface{}
		if strvalue, ok := s.colValue[n].(string); ok && strvalue == "?" {
			val = args[argPos]
			argPos++
		} else {
			val = s.colValue[n]
		}
		cols[colidx] = val
	}

	t.rows = append(t.rows, &row{cols: cols})
	return driver.RowsAffected(1), nil
}
Beispiel #5
0
func (c *conn) Exec(stmt string, args []driver.Value) (driver.Result, error) {
	rows, err := c.Query(stmt, args)
	if err != nil {
		return nil, err
	}
	return driver.RowsAffected(len(rows.rows)), nil
}
Beispiel #6
0
func (cn *Conn) Exec(query string, args []interface{}) (driver.Result, error) {
	if len(args) == 0 {
		err := cn.p.SimpleQuery(query)
		if err != nil {
			return nil, err
		}

		var serr error
		for {
			m, err := cn.p.Next()
			if err != nil {
				return nil, err
			}

			switch m.Type {
			case 'E':
				serr = m.Err
			case 'Z':
				return driver.RowsAffected(0), serr
			}
		}
	} else {
		stmt, err := cn.Prepare(query)
		if err != nil {
			return nil, err
		}

		return stmt.Exec(args)
	}

	panic("not reached")
}
Beispiel #7
0
Datei: copy.go Projekt: jpoz/pq
// Exec inserts values into the COPY stream. The insert is asynchronous
// and Exec can return errors from previous Exec calls to the same
// COPY stmt.
//
// You need to call Exec(nil) to sync the COPY stream and to get any
// errors from pending data, since Stmt.Close() doesn't return errors
// to the user.
func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
	defer errRecover(&err)

	if ci.closed {
		return nil, errCopyInClosed
	}

	if ci.isErrorSet() {
		return nil, ci.err
	}

	if len(v) == 0 {
		err = ci.Close()
		ci.closed = true
		return nil, err
	}

	numValues := len(v)
	for i, value := range v {
		ci.buffer = appendEncodedText(&ci.cn.parameterStatus, ci.buffer, value)
		if i < numValues-1 {
			ci.buffer = append(ci.buffer, '\t')
		}
	}

	ci.buffer = append(ci.buffer, '\n')

	if len(ci.buffer) > ciBufferFlushSize {
		ci.flush(ci.buffer)
		// reset buffer, keep bytes for message identifier and length
		ci.buffer = ci.buffer[:5]
	}

	return driver.RowsAffected(0), nil
}
Beispiel #8
0
func (c *conn) Exec(stmt string, args []driver.Value) (driver.Result, error) {
	result, err := c.internalQuery(stmt, args)
	if err != nil {
		return nil, err
	}
	switch t := result.GetUnion().(type) {
	case nil:
		return nil, nil
	case *Response_Result_DDL_:
		return driver.ResultNoRows, nil
	case *Response_Result_RowsAffected:
		return driver.RowsAffected(int(t.RowsAffected)), nil
	case *Response_Result_Rows_:
		return driver.RowsAffected(len(t.Rows.Rows)), nil
	default:
		return nil, util.Errorf("unexpected result %s of type %T", t, t)
	}
}
Beispiel #9
0
func (s *stmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.st.Execute(args); err != nil {
		return nil, err
	}

	rowsAffected, err := s.st.RowsAffected()
	r := driver.RowsAffected(rowsAffected)
	return r, err
}
Beispiel #10
0
func (c *Conn) Exec(query string, argsV []driver.Value) (driver.Result, error) {
	if !c.conn.IsAlive() {
		return nil, driver.ErrBadConn
	}

	args := valueToInterface(argsV)
	commandTag, err := c.conn.Exec(query, args...)
	return driver.RowsAffected(commandTag.RowsAffected()), err
}
Beispiel #11
0
// parseComplete parses the "command tag" from a CommandComplete message, and
// returns the number of rows affected (if applicable) and a string
// identifying only the command that was executed, e.g. "ALTER TABLE".  If the
// command tag could not be parsed, parseComplete panics.
func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
	commandsWithAffectedRows := []string{
		"SELECT ",
		// INSERT is handled below
		"UPDATE ",
		"DELETE ",
		"FETCH ",
		"MOVE ",
		"COPY ",
	}

	var affectedRows *string
	for _, tag := range commandsWithAffectedRows {
		if strings.HasPrefix(commandTag, tag) {
			t := commandTag[len(tag):]
			affectedRows = &t
			commandTag = tag[:len(tag)-1]
			break
		}
	}
	// INSERT also includes the oid of the inserted row in its command tag.
	// Oids in user tables are deprecated, and the oid is only returned when
	// exactly one row is inserted, so it's unlikely to be of value to any
	// real-world application and we can ignore it.
	if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") {
		parts := strings.Split(commandTag, " ")
		if len(parts) != 3 {
			cn.bad = true
			errorf("unexpected INSERT command tag %s", commandTag)
		}
		affectedRows = &parts[len(parts)-1]
		commandTag = "INSERT"
	}
	// There should be no affected rows attached to the tag, just return it
	if affectedRows == nil {
		return driver.RowsAffected(0), commandTag
	}
	n, err := strconv.ParseInt(*affectedRows, 10, 64)
	if err != nil {
		cn.bad = true
		errorf("could not parse commandTag: %s", err)
	}
	return driver.RowsAffected(n), commandTag
}
Beispiel #12
0
func (s *sqlStmt) Exec(args []driver.Value) (driver.Result, error) {
	s.stmt.params = paramsFromValues(s.stmt.params, args)

	n, err := s.stmt.Execute()
	if err != nil {
		return nil, err
	}

	return driver.RowsAffected(n), nil
}
Beispiel #13
0
// When doInsert is true, add the row to the table.
// When doInsert is false do prep-work and error checking, but don't
// actually add the row to the table.
func (s *fakeStmt) execInsert(args []driver.NamedValue, doInsert bool) (driver.Result, error) {
	db := s.c.db
	if len(args) != s.placeholders {
		panic("error in pkg db; should only get here if size is correct")
	}
	db.mu.Lock()
	t, ok := db.table(s.table)
	db.mu.Unlock()
	if !ok {
		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
	}

	t.mu.Lock()
	defer t.mu.Unlock()

	var cols []interface{}
	if doInsert {
		cols = make([]interface{}, len(t.colname))
	}
	argPos := 0
	for n, colname := range s.colName {
		colidx := t.columnIndex(colname)
		if colidx == -1 {
			return nil, fmt.Errorf("fakedb: column %q doesn't exist or dropped since prepared statement was created", colname)
		}
		var val interface{}
		if strvalue, ok := s.colValue[n].(string); ok && strings.HasPrefix(strvalue, "?") {
			if strvalue == "?" {
				val = args[argPos].Value
			} else {
				// Assign value from argument placeholder name.
				for _, a := range args {
					if a.Name == strvalue[1:] {
						val = a.Value
						break
					}
				}
			}
			argPos++
		} else {
			val = s.colValue[n]
		}
		if doInsert {
			cols[colidx] = val
		}
	}

	if doInsert {
		t.rows = append(t.rows, &row{cols: cols})
	}
	return driver.RowsAffected(1), nil
}
Beispiel #14
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
}
Beispiel #15
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
}
Beispiel #16
0
func (stmt *Stmt) Exec(args []interface{}) (driver.Result, error) {
	// NOTE: should return []drive.Result, because a PS can have more
	// than one statement and recv more than one tag.
	rows, err := stmt.Query(args)
	if err != nil {
		return nil, err
	}

	for err = rows.Next(nil); err == nil; err = rows.Next(nil) {
	}

	if err != io.EOF {
		// We got an error, now we need to read the rest of the messages
		for rows.Next(nil) != io.EOF {
		}

		return nil, err
	}

	// TODO: use the tag given by CommandComplete
	return driver.RowsAffected(0), nil
}
Beispiel #17
0
func (s *stmt) q(args []driver.Value) (driver.Rows, driver.Result, error) {
	cmd, err := ado.NewCommand()
	if err != nil {
		return nil, nil, err
	}
	defer cmd.Release()
	err = cmd.PutrefActiveADOConnection(s.c.db)
	if err != nil {
		return nil, nil, err
	}

	err = cmd.PutCommandText(s.query)
	if err != nil {
		return nil, nil, err
	}
	err = cmd.PutCommandType(1)
	if err != nil {
		return nil, nil, err
	}

	params, err := cmd.GetParameters()
	if err != nil {
		return nil, nil, err
	}
	defer params.Release()

	for _, a := range args {
		var param *ado.Parameter
		switch v := a.(type) {
		case int64:
			v32 := int32(v)
			if int64(v32) != v {
				return nil, nil, fmt.Errorf("integer too large to pass to FoxPro: %d", v)
			}
			param, err = cmd.CreateParameter("", ado.Integer, ado.ParamInput, 4, v32)
		case float64:
			param, err = cmd.CreateParameter("", ado.Double, ado.ParamInput, 8, v)
		case bool:
			param, err = cmd.CreateParameter("", ado.Boolean, ado.ParamInput, 1, v)
		case []byte:
			param, err = cmd.CreateParameter("", ado.BSTR, ado.ParamInput, uintptr(len(v)), string(v))
		case string:
			param, err = cmd.CreateParameter("", ado.BSTR, ado.ParamInput, uintptr(len(v)), v)
		case time.Time:
			param, err = cmd.CreateParameter("", ado.Date, ado.ParamInput, 8, v)
		default:
			err = fmt.Errorf("foxpro: parameters of type %T are not supported", a)
		}
		if err != nil {
			return nil, nil, err
		}
		defer param.Release()
		err = params.Append(param)
		if err != nil {
			return nil, nil, err
		}
	}

	var nRecords com.Variant
	recordset, err := cmd.Execute(&nRecords, nil, ado.OptionUnspecified)
	if err != nil {
		return nil, nil, err
	}
	return &rows{recordset}, driver.RowsAffected(nRecords.Val), nil
}
Beispiel #18
0
func parseComplete(s string) driver.Result {
	parts := strings.Split(s, " ")
	n, _ := strconv.ParseInt(parts[len(parts)-1], 10, 64)
	return driver.RowsAffected(n)
}