numerus/pkg/pgtypes.go

163 lines
4.6 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 {
var productId interface{} = form.ProductId.Val
if form.ProductId.Val == "" {
productId = nil
}
values = append(values, []interface{}{
productId,
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)
}
type EditedInvoiceProductArray []*invoiceProductForm
func (src EditedInvoiceProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
typeName := "edited_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 {
var invoiceProductId interface{} = nil
if form.InvoiceProductId.Val != "" {
if id := form.InvoiceProductId.Integer(); id > 0 {
invoiceProductId = id
}
}
values = append(values, []interface{}{
invoiceProductId,
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 {
if _, err := conn.Exec(ctx, "set role to admin"); err != nil {
return err
}
tagNameOID, err := registerPgType(ctx, conn, &pgtype.Text{}, "tag_name")
if err != nil {
return err
}
tagNameArray := pgtype.NewArrayType("tag_name[]", tagNameOID, func() pgtype.ValueTranscoder {
return &pgtype.Text{}
})
if _, err := registerPgType(ctx, conn, tagNameArray, tagNameArray.TypeName()); err != nil {
return err
}
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
}
editedInvoiceProduct, err := pgtype.NewCompositeType(
"edited_invoice_product",
[]pgtype.CompositeTypeField{
{"invoice_product_id", pgtype.Int4OID},
{"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
}
editedInvoiceProductOID, err := registerPgType(ctx, conn, editedInvoiceProduct, editedInvoiceProduct.TypeName())
if err != nil {
return err
}
editedInvoiceProductArray := pgtype.NewArrayType("edited_invoice_product[]", editedInvoiceProductOID, func() pgtype.ValueTranscoder {
value := editedInvoiceProduct.NewTypeValue()
return value.(pgtype.ValueTranscoder)
})
_, err = registerPgType(ctx, conn, editedInvoiceProductArray, editedInvoiceProductArray.TypeName())
if err != nil {
return err
}
_, err = conn.Exec(ctx, "reset role")
return err
}
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
}