-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Having thought over sqlx.In
and the way it interacts with sqlx.BindNamed
for a while, I've started to also explore other ways that sqlx can help people with their queries. Besides IN
queries, one of the sticking points in SQL has been JOIN queries, especially when you've already "modeled" your tables appropriately.
@andybons asked me in IRC today if there was any better way of dealing with joins, and I said no, because the info you get from Columns()
doesn't include fully qualified names. However, that's just for SELECT *
; obviously, I think something like this should be possible:
type Person struct {
Name string
}
type Place struct {
Name string
}
// ...
func etc(db *sqlx.DB) {
var pp struct {
Person `db:"person,prefix=person."`
Place `db:",prefix=place."` // uses default Mapper
}
db.Get(&pp, `SELECT
person.name "person.name",
place.name "place.name"
FROM person, place LIMIT 1;`)
}
You could use _
or some such so you wouldn't have to quote the names in the aliases as well. If the repetition is bothersome, you could always:
func qualify(name string) string {
return fmt.Sprintf(`%v "%v"`, name, name)
}
Or even a simple parser similar to how sqlx.In
and sqlx.BindNamed
work:
query := qualify("SELECT q:person.name, q:place.name FROM person, place;")
The actual missing piece is a way to tell sqlx that an embedded struct should provide a prefix for its members. I have to think this out a bit more; the straightforward uses of this seem pretty useful, but multiple levels of prefixed embeds sounds complex and confusing.