tursodatabase/go-libsql

Bound parameter support

penberg opened this issue · 4 comments

Was playing whit this yesterday in a project and seems like it's not using args passed to query. So for example WHERE id = 1 would works but 'WHERE id = ?', id would return nothing

I looked through the code as best I could. I don't have the skill to fix this issue, but I think I've traced where the problem is coming from.

The following two functions accept the args from the db query functions:

func (c *conn) ExecContext(ctx context.Context, query string, args []sqldriver.NamedValue) (sqldriver.Result, error) {
	rows, err := c.execute(query)
	if err != nil {
		return nil, err
	}
	if rows != nil {
		C.libsql_free_rows(rows)
	}
	return nil, nil
}
...
func (c *conn) QueryContext(ctx context.Context, query string, args []sqldriver.NamedValue) (sqldriver.Rows, error) {
	rowsNativePtr, err := c.execute(query)
	if err != nil {
		return nil, err
	}
	return newRows(rowsNativePtr)
}

The args are not used within the functions, but I did test that they were received.

I believe the c.execute function also needs to accept the args and then the C.libsql_execute function needs to accept them/bind them when executing the query in the db.

func (c *conn) execute(query string) (C.libsql_rows_t, error) {
	queryCString := C.CString(query)
	defer C.free(unsafe.Pointer(queryCString))

	var rows C.libsql_rows_t
	var errMsg *C.char
	statusCode := C.libsql_execute(c.nativePtr, queryCString, &rows, &errMsg)
	if statusCode != 0 {
		return nil, libsqlError(fmt.Sprint("failed to execute query ", query), statusCode, errMsg)
	}
	return rows, nil
}

I'd be more than happy to work on this further, but I'm not sure where to go from here. Obviously, replacing the ? in the queries with the args is a very easy solution, but does nothing to prevent sql injection.

If someone want to give me some pointers on how to further help (if this is a problem I can help with), I'd appreciate it.

also very interested in this. I don't think I can use tursodb without support here

Positional parameters work already. We will work on named parameters in the near future.

yup, nevermind; I think there was a bug relating to scanning timestamp fields that was throwing me off. Every field scanned after a timestamp seems to be null.