How to implement a generic function for any struct (model) for a database API?

I’m implementing a database API. I have several models (structs). I need to implement basic CRUD operations. Now I’m implementing for each struct its own set of functions and methods but the code doesn’t differ much so it’s worth not to implement 20+ GetAllStructName functions but only one. I don’t understand right now how to do that.

Need to say I use sqlx in my code if it matters.

Here is the pattern I use:

type City struct {
    Attr1 string
    Attr2 string
}

type Country struct {
    Attr1 string
    Attr2 string
}

func GetAllCities(db *sqlx.DB) ([]*City, error) {
    items := []*City{}
    err := db.Select(&items, "SELECT * FROM cities")
    // check err
    return items, nil
}

func (m *City) Get(db *sqlx.DB, id string) error {
    if err := db.Get(m, "SELECT FROM cities WHERE id = ?", id); err != nil {
        return err
    }
    return nil
}

func GetAllCountries(db *sqlx.DB) ([]*Country, error) {
    items := []*Country{}
    err := db.Select(&items, "SELECT * FROM countries")
    // check err
    return items, nil
}

func (m *Country) Get(db *sqlx.DB, id string) error {
    if err := db.Get(m, "SELECT FROM countries WHERE id = ?", id); err != nil {
        return err
    }
    return nil
}

What actually changes is query string and type of values in a slice. How to make these GetAll universal, for example?

nit: you can make this function exactly one line. Can you see how?

Well, at least we could get rid of checking the error here and return it instead either an error or nil, do you mean that?

func (m *City) Get(db *sqlx.DB, id string) error {
    return db.Get(m, "SELECT FROM cities WHERE id = ?", id)
}

That example works. Yes, that’s cleaner. Nice. Thank you.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.