Closed bojanz closed 3 years ago
This would allow users on Postgres to define a composite type for prices, and scan it directly into currency.Amount.
Example composite type:
CREATE TYPE price AS ( number NUMERIC, currency_code CHAR(3) );
Example usage in a table:
CREATE TABLE products ( id CHAR(26) PRIMARY KEY, name TEXT NOT NULL, price price NOT NULL, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ );
Example scan:
p := Product{} row := tx.QueryRow(ctx, `SELECT id, name, price, created_at, updated_at FROM products WHERE id = $1`, id) err := row.Scan(&p.ID, &p.Name, &p.Price, &p.CreatedAt, &p.UpdatedAt)
The two interface implementations would look something like this:
// Value implements the database/driver.Valuer interface. func (a Amount) Value() (driver.Value, error) { return fmt.Sprintf("(%v,%v)", a.Number(), a.CurrencyCode()), nil } // Scan implements the database/sql.Scanner interface. func (a *Amount) Scan(src interface{}) error { // Wire format: "(9.99,USD)". input := strings.Trim(src.(string), "()") values := strings.Split(input, ",") n := values[0] currencyCode := values[1] // Do something with the two strings. return nil }
This would allow users on Postgres to define a composite type for prices, and scan it directly into currency.Amount.
Example composite type:
Example usage in a table:
Example scan:
The two interface implementations would look something like this: