lunemec / go-clean-architecture

13 stars 1 forks source link

Model duplicity for DB specific types #1

Open lunemec opened 6 years ago

lunemec commented 6 years ago

Each model is duplicated at least twice. In generic model that is used to pass data between layers and DB specific model containing sql.Null* types or mysql.NullTime or such.

Also this forces us to write ToModel() and FromModel methods to convert into "generic" model. This is terrible code smell. It leads to duplicits and having to write conversions manually. Breaks DRY principle.

Every model change requires change in several places which leads to bugs.

model/organization.go model/mysql/organization.go

thfre commented 6 years ago

Depending on how performant you need to be, you could use Gorm which disperses of the need for sql null types.

lunemec commented 6 years ago

We are using gorm, and it has its own set of problems. For example:

// db is gorm.DB
var out mysql.Organization
err := db.Where(mysql.Organization{ID: someID}).Assign(mysql.Organization{Name: "NewName"}).FirstOrCreate(&out).Error
if err != nil {
    return err
}

Problem with this is that if your someID variable is 0 - zero value for int, this query produces this SQL:

SELECT * FROM organization LIMIT 1;  // FirstOrSelect part to select if record exists
UPDATE organization SET .... WHERE id=1;  // Update first record. ALWAYS.

With incorrect WHERE clause, because the mysql.Organization structure passed to Where() is indistinguishable from its zero value. We found out and fixed this bug by using it like this:

err := db.Assign(mysql.Organization{Name: "NewName"}).FirstOrCreate(&out, someID).Error

It was bug in our code. We misunderstood how it is supposed to be used, but the more we use it, the more we wish we'd use simple SQL without ORM.

the-destro commented 6 years ago

have you tried sqlx? It has a nice StructScan function but you get to write real SQL

lunemec commented 6 years ago

@the-destro yes, I know of sqlx. It is a great library, but I don't think it would help here much.