Beispiel #1
0
// send sends the call to the server.
func (c *conn) send(args Request) (*rows, error) {
	resp, err := c.sender.Send(args)
	if err != nil {
		return nil, err
	}
	// Set the session state even if the server returns an application error.
	// The server is responsible for constructing the correct session state
	// and sending it back.
	if c.session != nil {
		panic("connection has lingering session state")
	}
	c.session = resp.Session
	// Translate into rows
	r := &rows{}
	// Only use the last result to populate the response
	index := len(resp.Results) - 1
	if index < 0 {
		return r, nil
	}
	// Check for any application errors.
	// TODO(vivek): We might want to bunch all errors found here into
	// a single error.
	for _, result := range resp.Results {
		if result.Error != nil {
			return nil, result.Error
		}
	}
	result := resp.Results[index]
	r.columns = make([]string, len(result.Columns))
	for i, column := range result.Columns {
		r.columns[i] = column
	}
	r.rows = make([]row, len(result.Rows))
	for i, p := range result.Rows {
		t := make(row, len(p.Values))
		for j, datum := range p.Values {
			if datum.BoolVal != nil {
				t[j] = *datum.BoolVal
			} else if datum.IntVal != nil {
				t[j] = *datum.IntVal
			} else if datum.FloatVal != nil {
				t[j] = *datum.FloatVal
			} else if datum.BytesVal != nil {
				t[j] = datum.BytesVal
			} else if datum.StringVal != nil {
				t[j] = []byte(*datum.StringVal)
			} else if datum.TimeVal != nil {
				t[j] = time.Unix((*datum.TimeVal).Sec, int64((*datum.TimeVal).Nsec)).UTC()
			}
			if !driver.IsScanValue(t[j]) {
				panic(fmt.Sprintf("unsupported type %T returned by database", t[j]))
			}
		}
		r.rows[i] = t
	}
	return r, nil
}
Beispiel #2
0
// Send sends the call to the server.
func (c *conn) send(args sqlwire.Request) (*rows, error) {
	resp, err := c.sender.Send(args)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		return nil, resp.Error
	}
	c.session = resp.Session
	// Translate into rows
	r := &rows{}
	// Only use the last result to populate the response
	index := len(resp.Results) - 1
	if index < 0 {
		return r, nil
	}
	result := resp.Results[index]
	r.columns = make([]string, len(result.Columns))
	for i, column := range result.Columns {
		r.columns[i] = column
	}
	r.rows = make([]row, len(result.Rows))
	for i, p := range result.Rows {
		t := make(row, len(p.Values))
		for j, datum := range p.Values {
			if datum.BoolVal != nil {
				t[j] = *datum.BoolVal
			} else if datum.IntVal != nil {
				t[j] = *datum.IntVal
			} else if datum.UintVal != nil {
				// uint64 not supported by the driver.Value interface.
				if *datum.UintVal >= math.MaxInt64 {
					return &rows{}, fmt.Errorf("cannot convert very large uint64 %d returned by database", *datum.UintVal)
				}
				t[j] = int64(*datum.UintVal)
			} else if datum.FloatVal != nil {
				t[j] = *datum.FloatVal
			} else if datum.BytesVal != nil {
				t[j] = datum.BytesVal
			} else if datum.StringVal != nil {
				t[j] = []byte(*datum.StringVal)
			}
			if !driver.IsScanValue(t[j]) {
				panic(fmt.Sprintf("unsupported type %T returned by database", t[j]))
			}
		}
		r.rows[i] = t
	}
	return r, nil
}