func (qr *QueryResult) Columns() []string {
	return qr.columns
}
these are done as getters rather than as public
variables to prevent monkey business by the user
that would put us in an inconsistent state
/* *****************************************************************

method: QueryResult.Columns()

****************************************************************
/*
Columns returns a list of the column names for this QueryResult.
package gorqlite
import "errors"
import "fmt"
import "encoding/json"
func (conn *Connection) QueryOne(sqlStatement string) (qr QueryResult, err error) {
  if ( conn.hasBeenClosed) {
		qr.Err = errClosed
		return qr, errClosed
  }
	sqlStatements := make([]string,0)
	sqlStatements = append(sqlStatements,sqlStatement)
	qra, err := conn.Query(sqlStatements)
	return qra[0], err
}	
func (conn *Connection) Query(sqlStatements []string) (results []QueryResult, err error) {
	results = make([]QueryResult,0)
  if ( conn.hasBeenClosed) {
		var errResult QueryResult
		errResult.Err = errClosed
		results = append(results,errResult)
    return results, errClosed
  }
	trace("%s: Query() for %d statements",conn.ID,len(sqlStatements))
	response, err := conn.rqliteApiPost(api_QUERY,sqlStatements)
	if ( err != nil ) { 
		trace("%s: rqliteApiCall() ERROR: %s",conn.ID,err.Error())
		var errResult QueryResult
		errResult.Err = err
		results = append(results,errResult)
		return results, err
	}
	trace("%s: rqliteApiCall() OK",conn.ID)
	var sections map[string]interface{}
	err = json.Unmarshal(response,&sections)
	if ( err != nil ) { 
		trace("%s: json.Unmarshal() ERROR: %s",conn.ID,err.Error())
		var errResult QueryResult
		errResult.Err = err
		results = append(results,errResult)
		return results, err
	}
	resultsArray := sections["results"].([]interface{})
	trace("%s: I have %d result(s) to parse",conn.ID,len(resultsArray))
	numStatementErrors := 0
	for n, r := range resultsArray {
		trace("%s: parsing result %d",conn.ID,n)
		var thisQR QueryResult
		thisQR.conn = conn 
		thisResult := r.(map[string]interface{})
		_, ok := thisResult["error"]
		if ok {
			trace("%s: have an error on this result: %s",conn.ID,thisResult["error"].(string))
			thisQR.Err = errors.New(thisResult["error"].(string))
			results = append(results,thisQR)
			numStatementErrors++
			continue
		}
		thisQR.Timing = thisResult["time"].(float64)
		c := thisResult["columns"].([]interface{})
		t := thisResult["types"].([]interface{})
		for i := 0; i < len(c) ; i++ {
			thisQR.columns = append(thisQR.columns,c[i].(string))
			thisQR.types = append(thisQR.types,t[i].(string))
		}
		if ( thisResult["values"] != nil ) {
			thisQR.values = thisResult["values"].([]interface{})
		} else {
			trace("%s: fyi, no values this query",conn.ID)
		}
		thisQR.rowNumber = -1
		trace("%s: this result (#col,time) %d %f",conn.ID,len(thisQR.columns),thisQR.Timing)
		results = append(results,thisQR)
	}
	trace("%s: finished parsing, returning %d results",conn.ID,len(results))
	if ( numStatementErrors > 0 ) {
		return results, errors.New(fmt.Sprintf("there were %d statement errors",numStatementErrors))
	} else {
		return results, nil
	}
}
type QueryResult struct {
	conn *Connection
	Err error
	columns []string
	types []string
	Timing float64
	values []interface{}
	rowNumber int64
}