numerus/pkg/pgtypes.go

342 lines
9.3 KiB
Go

package pkg
import (
"context"
"fmt"
"github.com/jackc/pgtype"
"github.com/jackc/pgx/v4"
)
var (
oidCache = make(map[string]uint32)
)
type CustomerTaxDetails struct {
BusinessName string
VATIN string
Address string
City string
Province string
PostalCode string
CountryCode string
}
func (src CustomerTaxDetails) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
typeName := "tax_details"
dt, ok := ci.DataTypeForName(typeName)
if !ok {
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
}
values := []interface{}{
src.BusinessName,
src.VATIN,
src.Address,
src.City,
src.Province,
src.PostalCode,
src.CountryCode,
}
ct := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
if err := ct.Set(values); err != nil {
return nil, err
}
return ct.EncodeBinary(ci, buf)
}
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 {
values = append(values, []interface{}{
form.InvoiceProductId.IntegerOrNil(),
form.ProductId.IntegerOrNil(),
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 NewQuoteProductArray []*quoteProductForm
func (src NewQuoteProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
typeName := "new_quote_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 EditedQuoteProductArray []*quoteProductForm
func (src EditedQuoteProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
typeName := "edited_quote_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.QuoteProductId.IntegerOrNil(),
form.ProductId.IntegerOrNil(),
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
}
newQuoteProduct, err := pgtype.NewCompositeType(
"new_quote_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
}
newQuoteProductOID, err := registerPgType(ctx, conn, newQuoteProduct, newQuoteProduct.TypeName())
if err != nil {
return err
}
newQuoteProductArray := pgtype.NewArrayType("new_quote_product[]", newQuoteProductOID, func() pgtype.ValueTranscoder {
value := newQuoteProduct.NewTypeValue()
return value.(pgtype.ValueTranscoder)
})
_, err = registerPgType(ctx, conn, newQuoteProductArray, newQuoteProductArray.TypeName())
if err != nil {
return err
}
editedQuoteProduct, err := pgtype.NewCompositeType(
"edited_quote_product",
[]pgtype.CompositeTypeField{
{"quote_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
}
editedQuoteProductOID, err := registerPgType(ctx, conn, editedQuoteProduct, editedQuoteProduct.TypeName())
if err != nil {
return err
}
editedQuoteProductArray := pgtype.NewArrayType("edited_quote_product[]", editedQuoteProductOID, func() pgtype.ValueTranscoder {
value := editedQuoteProduct.NewTypeValue()
return value.(pgtype.ValueTranscoder)
})
_, err = registerPgType(ctx, conn, editedQuoteProductArray, editedQuoteProductArray.TypeName())
if err != nil {
return err
}
countryCodeOID, err := registerPgType(ctx, conn, &pgtype.Text{}, "country_code")
if err != nil {
return err
}
taxDetailsType, err := pgtype.NewCompositeType(
"tax_details",
[]pgtype.CompositeTypeField{
{"business_name", pgtype.TextOID},
{"vatin", pgtype.TextOID},
{"address", pgtype.TextOID},
{"city", pgtype.TextOID},
{"province", pgtype.TextOID},
{"postal_code", pgtype.TextOID},
{"discount_rate", countryCodeOID},
},
conn.ConnInfo(),
)
if err != nil {
return err
}
_, err = registerPgType(ctx, conn, taxDetailsType, taxDetailsType.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) {
var found bool
if oid, found = oidCache[name]; !found {
if err = conn.QueryRow(ctx, "select $1::regtype::oid", name).Scan(&oid); err != nil {
return
}
oidCache[name] = oid
}
conn.ConnInfo().RegisterDataType(pgtype.DataType{Value: value, Name: name, OID: oid})
return
}