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

Model duplicity for DB specific types #1

Open
lunemec opened this issue Mar 1, 2018 · 4 comments
Open

Model duplicity for DB specific types #1

lunemec opened this issue Mar 1, 2018 · 4 comments

Comments

@lunemec
Copy link
Owner

lunemec commented Mar 1, 2018

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
Copy link

thfre commented Mar 1, 2018

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

@lunemec
Copy link
Owner Author

lunemec commented Mar 1, 2018

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
Copy link

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

@lunemec
Copy link
Owner Author

lunemec commented Mar 5, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants