jackc / jackc/pgx

Generic Quick Type Conversion between pgtype and pointers

Open
#2,375 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
14.3k
Forks
1.1k
Avg merge
6d 9h
Merged PRs (30d)
11

Description

Is your feature request related to a problem? Please describe.

I have to write a lot of helper functions when I use pgtype.Text or pgtype.Int64 if I have nullable fields to convert them back and forth between pointers.

  1. When converting from pgtype to pointer, I don't want to check whether field is Valid, I just want a valid or null pointer
  2. When converting to pgtype, I don't want to write whether pgtype is valid, just mark as valid if pointer is not null.

Describe the solution you'd like
I would like if we can add a GetValue() and ToValue() function for this.

// 1. pgtype to pointer

// Current Value function for pgtype.Text
func (src Text) Value() (driver.Value, error) {
	if !src.Valid {
		return nil, nil
	}
	return src.String, nil
}

// Proposed New Methods
func (src Text) GetValue() (*string) {
    if src.Valid {
		return &val.String
	}
	return nil
}

// So that I can easily do 

return &MyResponse{
 optional_name_ptr : db_user_obj.Name_String.GetValue(),
 optional_age_ptr    : db_user_obj.Age_Int64.GetValue(),
}

// Instead of writing a lot of checks to set it to nil if it is not Valid, instead of returning default values (empty string or 0 )

//2. Pointer to pgtype. I don't know the syntax to handle this
// This should be generic and typesafe somehow to convert pointer of a particular type to it's respective pgtype.
func ToValue(val *string) (pgtype.Text){
     if(val==nil){
          return pgtype.Text{Valid:False, String: nil}
     }
     return pgType.Text{Valid:True, String: val}
} 

// So that I can do such statements:-

db_query(ctx, pgtype.ToValue(req.optional_name_ptr), pgtype.ToValue(req.optional_age_ptr))

// instead of manually converting them to pgtype.Int8 or pgtype.Text
// I don't know how to do this in Golang. But in Typescript for example, you can define a mapping between the types, and ensure you get the correct output type for a particular input type.

Why do I want this? Because it is type safe (not driver.Value which is any).

Describe alternatives you've considered
I have considered writing such helper functions myself for every type I use, but it would be better if it was in the source.

I also tried my own generic approach but I didn't like it

package utils

import "github.com/jackc/pgx/v5/pgtype"

// Constraint for supported pgtypes
type PgNullable interface {
	pgtype.Text | pgtype.Int8
}

// DbNull converts a pgtype value into *T (nil if not valid)
func DbNull[T any, P PgNullable](val P) *T {
	switch v := any(val).(type) {
	case pgtype.Text:
		if v.Valid {
			s := v.String
			return any(&s).(*T)
		}
	case pgtype.Int8:
		if v.Valid {
			i := v.Int64
			return any(&i).(*T)
		}
	}
	return nil
}


txt := pgtype.Text{String: "hello", Valid: true}
s := utils.DbNull[string](txt) // *string → "hello"

i8 := pgtype.Int8{Int64: 42, Valid: true}
n := utils.DbNull[int64](i8)   // *int64 → 42

This above DbNull is GPT generated code. Looks ugly and type unsafe (accidentally cast incorrect type to string).

Additional context
NA.

Let me know if this is feasible, then we can plan to write the code.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the pgtype.Text and pgtype.Int64 types and their existing Value methods. Define whether the requested conversions can provide type-safe behavior in both directions, then identify the API and tests needed to cover valid and null pointers; done means the supported conversions are specified and verified without per-type helper functions.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, postgresql
Domain
database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.