80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
|
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
|
||
|
}
|