volatiletech / sqlboiler

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

Update with join #254

Closed saulortega closed 5 years ago

saulortega commented 6 years ago

Hello.

sqlboiler is ignoring the qm.InnerJoin() when Update. there should be support for this: https://stackoverflow.com/questions/7869592/how-to-do-an-update-join-in-postgresql

I tried adding a few lines to query_builders.go.

I changed this:


func buildUpdateQuery(q *Query) (*bytes.Buffer, []interface{}) {
    buf := strmangle.GetBuffer()

    //Code ommited...
    fmt.Fprintf(buf, " SET %s", strings.Join(setSlice, ", "))

    where, whereArgs := whereClause(q, len(args)+1)
    //Code ommited...

    return buf, args
}

for this:


func buildUpdateQuery(q *Query) (*bytes.Buffer, []interface{}) {
    buf := strmangle.GetBuffer()

    //Code ommited...
    fmt.Fprintf(buf, " SET %s", strings.Join(setSlice, ", "))

    // --------------------- START NEW LINES -------------------
    if len(q.joins) > 0 {
        joinBuf := strmangle.GetBuffer()
        for _, j := range q.joins {
            fmt.Fprintf(joinBuf, " %s", j.clause)
            args = append(args, j.args...)
        }
        fmt.Fprintf(buf, " FROM %s", joinBuf.String())
    }
    // --------------------- END NEW LINES -------------------

    where, whereArgs := whereClause(q, len(args)+1)
    //Code ommited...

    return buf, args
}

That works like this:

models.VehicleAlerts(BDL,
    qm.InnerJoin("device_data"),
    qm.Where("vehicle_id=?", 44),
    qm.And("device_data.transmission_reason=?", 55),
).UpdateAll(models.M{
    "device_datum_end_id": 66,
})

Results:

UPDATE "vehicle_alerts" SET "device_datum_end_id" = $1 FROM  device_data WHERE (vehicle_id=$2) AND (device_data.transmission_reason=$3);

What do you think, @aarondl?

Oh, it's for Postgres. It's different on MySQL...

aarondl commented 6 years ago

Well, for starters thanks for experimenting with the code! Secondly, we -do- have to stay true to our lowest common denominator so we'd have to look at if/how this works in both mysql, mssql and it's good to look at sqlite as well.

If it is indeed different on all of these db engines, then we don't have a lot of choices if we want the functionality. But putting db specific parts in this section of the code will probably be a net negative (for maintainability etc, every feature has a cost, especially when DB support is so varied).

I'd push back a little and ask: Do we -really- need this functionality, is it used as frequently as update itself is? I'd say that's fairly unlikely. Thoughts?

aarondl commented 5 years ago

Probably not going to implement this. Also stale.