pg icon indicating copy to clipboard operation
pg copied to clipboard

How to implement an own Array Type?

Open vorlif opened this issue 5 years ago • 1 comments

Hi, which interface should be implemented if I want to create my own array type? I have already tested various interfaces and always failed.

As an example I want to save the keys of a map as an array:

CREATE TABLE IF NOT EXISTS my_tables
(
    test    TEXT[]    NOT NULL
)
type MyType map[string]interface{}

type MyTable struct {
    Test        MyType     `pg:",array,use_zero"`
}

vorlif avatar Jun 02 '20 10:06 vorlif

Update: I have found a way, but I do not think it is a good one.

type MyTable struct {
    Test        MyType     `pg:",use_zero"`
}

type MyType map[string]*otherStruct{}

var _ types.ValueAppender = (*MyType)(nil)
var _ types.ValueScanner = (*MyType)(nil)

func (m *MyType) Init() error {
	*m = make(map[string]*otherStruct)
	return nil
}

func (m MyType) AppendValue(dst []byte, quote int) ([]byte, error) {
	return types.NewArray(m.Keys()).AppendValue(dst, quote)
}

func (m *MyType) ScanValue(rd types.Reader, n int) error {
	m.Init()
	var keys []string
	if err := types.NewArray(&keys).ScanValue(rd, n); err != nil {
		return err
	}

	for _, key := range keys {
		value, ok := GetValue(key)
		if ok {
			(*m)[key] = value
		}
	}

	return nil
}

func (m *MyType) Keys() []string {
	keys := make([]string, 0, len(*m))
	for key := range *m {
		keys = append(keys, key)
	}

	return keys
}

vorlif avatar Jun 08 '20 19:06 vorlif