Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct Overrides (proposal) #1176

Open
nkev opened this issue Sep 11, 2021 · 2 comments
Open

Struct Overrides (proposal) #1176

nkev opened this issue Sep 11, 2021 · 2 comments
Labels
enhancement New feature or request proposal

Comments

@nkev
Copy link

nkev commented Sep 11, 2021

I can see quite a few unresolved issues related to the customization of sqlc generated structs.

I'm in a similar position where I have several custom struct tags and embedded structs in my product model that flattens out to a single Postgres table, e.g.:

package models

//Product is a Postgres table, parts of which are imported from the remote ERP and another remote website.
//All fields of ERPProduct and WebProduct are contained in the Postgres table
type Product struct {
	ERPProduct   //note: embedded ERPProduct.ProductCode is primary key!
	WebProduct
	Culture      string  `json:"culture" pg:"culture"` 
	IsEnabled    bool   `json:"isEnabled,omitempty" pg:"is_enabled"`
}

//ERPProduct represents an ERP product record from the remote SQL Server
type ERPProduct struct {
	ProductCode  string   `json:"productCode" db:"ProductCode" pg:"product_code"` //db tag is for ERP  SQL Server
	Category     string   `json:"categoryCode,omitempty" db:"Category" pg:"category"`
	//...other columns...
}

//Import will connect to the ERP and import an ERPProduct from an SQL Server
func (p *ERPProduct) Import() (error) {
   //code to import and populate p using sqlx
   return nil
}

//WebProduct represents a web product 
type WebProduct struct {
	WebCode         string  `json:"webcode,omitempty" pg:"web_code"`
	WebDescription  string  `json:"webDescription,omitempty" pg:"web_description"`
	Slug            string  `json:"slug,omitempty" pg:"slug"`
	//...other columns...
}

//Import will connect to another remote website and import a WebProduct via an API
func (p *WebProduct) Import() (error) {
   //code to import and populate p 
   return nil
}

As you can see, there are too many issues with this product model to port across to sqlc.

However, I have an idea that might solve all of those issues in one foul swoop.. :)

We can currently override fields like this:

version: "1"
packages: [...]
overrides:
  - go_type: "github.com/gofrs/uuid.UUID"
    db_type: "uuid"

Could we not do the same for structs? i.e. override the generation of the 'product' struct with my custom product struct like this:

version: "1"
packages: [...]
overrides:
  - go_struct: "github.com/me/myproj/models.Product"
    db_struct: "Product"

The flattenned out 'product' definition would still be required in the sqlc schema file (only for validation in sqlc generated queries):

create table products
(
    product_code text primary key,
    category     text,
    ...
    webcode      text,
    ...
    culture	 text,
    is_enabled   boolean default true  not null
);

sqlc would then generate the struct of the 'product' schema but comment it out with an 'overriden by..' comment above it.

sqlc would then import github.com/me/myproj/models in the query.sql.go file and use the Product struct in there.

Any product related query errors thereafter will be the responsibility of the developer...

@nkev nkev changed the title Struct Overrides Struct Overrides (proposal) Sep 11, 2021
@kyleconroy kyleconroy added the enhancement New feature or request label Sep 11, 2021
@kyleconroy
Copy link
Collaborator

See a similar issue here: #755

@nkev
Copy link
Author

nkev commented Sep 13, 2021

Yes, I saw that and others too related to custom tags. I'm sure there will also be other issues in future related to customization of structs. For example, in my scenario above I thought about omitting product in the schema file so the struct does not get generated by sqlc. But then I realized the product table gets referenced in many queries so this means I cannot use sqlc at all, even though I would so love to.

To be fair, sqlc cannot possibly cater for all struct use cases, so I think allowing user overriden structs is the most flexible solution, don't you agree?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request proposal
Projects
None yet
Development

No branches or pull requests

2 participants