numerus/pkg/pgtypes.go

80 lines
2.2 KiB
Go
Raw Normal View History

package pkg
import (
"context"
"fmt"
"github.com/jackc/pgtype"
"github.com/jackc/pgx/v4"
)
type NewInvoiceProductArray []*invoiceProductForm
func (src NewInvoiceProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
typeName := "new_invoice_product[]"
dt, ok := ci.DataTypeForName(typeName)
if !ok {
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
}
var values [][]interface{}
for _, form := range src {
values = append(values, []interface{}{
form.ProductId.Val,
form.Name.Val,
form.Description.Val,
form.Price.Val,
form.Quantity.Val,
form.Discount.Float64() / 100.0,
form.Tax.Selected,
})
}
array := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
if err := array.Set(values); err != nil {
return nil, err
}
return array.EncodeBinary(ci, buf)
}
func registerPgTypes(ctx context.Context, conn *pgx.Conn) error {
discountRateOID, err := registerPgType(ctx, conn, &pgtype.Numeric{}, "discount_rate")
if err != nil {
return err
}
newInvoiceProduct, err := pgtype.NewCompositeType(
"new_invoice_product",
[]pgtype.CompositeTypeField{
{"product_id", pgtype.Int4OID},
{"name", pgtype.TextOID},
{"description", pgtype.TextOID},
{"price", pgtype.TextOID},
{"quantity", pgtype.Int4OID},
{"discount_rate", discountRateOID},
{"tax", pgtype.Int4ArrayOID},
},
conn.ConnInfo(),
)
if err != nil {
return err
}
newInvoiceProductOID, err := registerPgType(ctx, conn, newInvoiceProduct, newInvoiceProduct.TypeName())
if err != nil {
return err
}
newInvoiceProductArray := pgtype.NewArrayType("new_invoice_product[]", newInvoiceProductOID, func() pgtype.ValueTranscoder {
value := newInvoiceProduct.NewTypeValue()
return value.(pgtype.ValueTranscoder)
})
_, err = registerPgType(ctx, conn, newInvoiceProductArray, newInvoiceProductArray.TypeName())
if err != nil {
return err
}
return nil
}
func registerPgType(ctx context.Context, conn *pgx.Conn, value pgtype.Value, name string) (oid uint32, err error) {
if err = conn.QueryRow(ctx, "select $1::regtype::oid", name).Scan(&oid); err != nil {
return
}
conn.ConnInfo().RegisterDataType(pgtype.DataType{Value: value, Name: name, OID: oid})
return
}