volatiletech / sqlboiler

Generate a Go ORM tailored to your database schema.
BSD 3-Clause "New" or "Revised" License
6.56k stars 533 forks source link

sqlboiler auto-generates replaced and unused (enum) type into boil_types.go #1355

Closed MJacred closed 4 months ago

MJacred commented 4 months ago

If you're having a generation problem please answer these questions before submitting your issue. Thanks!

What version of SQLBoiler are you using (sqlboiler --version)?

v4.14.2

What is your database and version (eg. Postgresql 10)

MariaDB v10.11.2

If this happened at generation time what was the full SQLBoiler command you used to generate your models? (if not applicable leave blank)

If this happened at runtime what code produced the issue? (if not applicable leave blank)

What is the output of the command above with the -d flag added to it? (Provided you are comfortable sharing this, it contains a blueprint of your schema)

Please provide a relevant database schema so we can replicate your issue (Provided you are comfortable sharing this)

CREATE TABLE IF NOT EXISTS TableA (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,

  my_enum ENUM('A', 'B', 'C') NOT NULL,

  PRIMARY KEY (id)
);

sqlboiler.toml

add-enum-types = true

[[types]]
  [[types.match]]
    name = "my_enum"
    # tables = ["TableA"]

  [[types.replace]]
    type = "models_types.MyEnumOverride"

  [[types.imports]]
    third_party = ['"test.com/test/models_types"']

auto-generated go struct:

type TableA struct {
    ID     uint        
    MyEnum TableAMyEnum // Is autogenerated into boil_types.go

    R *tableAR
    L tableAL 
}

test/test.go

package models_types

import "github.com/friendsofgo/errors"

type MyEnumOverride string

// Enum values for MyEnumOverride
const (
    MyEnumOverrideA MyEnumOverride = "A"
    MyEnumOverrideB MyEnumOverride = "B"
    MyEnumOverrideC MyEnumOverride = "C"
)

func AllMyEnumOverride() []MyEnumOverride {
    return []MyEnumOverride{
        MyEnumOverrideA,
        MyEnumOverrideB,
        MyEnumOverrideC,
    }
}

func (e MyEnumOverride) IsValid() error {
    switch e {
    case MyEnumOverrideA, MyEnumOverrideB, MyEnumOverrideC:
        return nil
    default:
        return errors.New("enum is not valid")
    }
}

func (e MyEnumOverride) String() string {
    return string(e)
}

Further information. What did you do, what did you expect?

https://github.com/volatiletech/sqlboiler?tab=readme-ov-file#types suggests, you can replace a type used in the autogenerated code.
This seems to not work with enums. At least the setup I provided in the previous chapter had no effect.

The reason to replace the autogenerated type is because we have 2 tables, which need the same enum values. It would be a cleaner experience to replace their types with 1 self-created one…

stephenafamo commented 4 months ago

What does the generated model look like?

MJacred commented 4 months ago

@stephenafamo: I updated the example for better clarity and added the generated model

stephenafamo commented 4 months ago

The issue is your config. You're missing something with the TOML syntax and you're using double square brackets where single square brackets should be used.

add-enum-types = true

[[types]]
  [types.match]
    name = "my_enum"
    # tables = ["TableA"]

  [types.replace]
    type = "models_types.MyEnumOverride"

  [types.imports]
    third_party = ['"test.com/test/models_types"']

It would be a cleaner experience to replace their types with 1 self-created one…

Side note, you can just replace one of the enums with the second auto generated one so that you don't have to maintain the values yourself 🤷🏾‍♂️

MJacred commented 4 months ago

you're using double square brackets where single square brackets should be used

That's it. Thanks!

One problem left, though: sqlboiler still auto-generates type TableAMyEnum string into boil_types.go

you can just replace one of the enums with the second auto generated one

Indeed

stephenafamo commented 4 months ago

One problem left, though: sqlboiler still auto-generates type TableAMyEnum string into boil_types.go

Not really an issue since there is no way for SQLBoiler to be sure that you do not intend to use the type somewhere else.

MJacred commented 4 months ago

Not really an issue since there is no way for SQLBoiler to be sure that you do not intend to use the type somewhere else.

If sqlboiler creates a type specifically for that field in that table and I tell sqlboiler to replace it in the generated model, then it makes no sense to keep it.
So that reasoning makes little sense to me. But if you must insist, I propose to add a flag to "skip fully replaced (enum) types"

stephenafamo commented 4 months ago

I can see why this would be useful.

If you can send in a PR with this flag, I'll be happy to review and merge.

MJacred commented 4 months ago

Thank you. I'll see to it. If you have some useful pointers (like where the replacement takes place), I'd appreciate it a lot!