diff --git a/join_table_handler.go b/join_table_handler.go index a036d46d25..2e2df2838d 100644 --- a/join_table_handler.go +++ b/join_table_handler.go @@ -122,22 +122,30 @@ func (s JoinTableHandler) Add(handler JoinTableHandlerInterface, db *DB, source values = append(values, value) } - for _, value := range values { - values = append(values, value) - } - quotedTable := scope.Quote(handler.Table(db)) sql := fmt.Sprintf( - "INSERT INTO %v (%v) SELECT %v %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v)", + "INSERT INTO %v (%v) VALUES(%v)", quotedTable, strings.Join(assignColumns, ","), strings.Join(binVars, ","), - scope.Dialect().SelectFromDummyTable(), - quotedTable, - strings.Join(conditions, " AND "), ) - - return db.Exec(sql, values...).Error + checkSql := fmt.Sprintf("SELECT COUNT(1) FROM %v WHERE %v FOR UPDATE", quotedTable, strings.Join(conditions, " AND ")) + if db.Dialect().GetName() == "sqlite3" { + // sqlite does not support SELECT FOR UPDATE. But it is single thread concurrency, safe here. + checkSql = fmt.Sprintf("SELECT COUNT(1) FROM %v WHERE %v", quotedTable, strings.Join(conditions, " AND ")) + } + checkCount := 0 + rows, err := db.db.Query(checkSql, values...) + if err != nil { + return err + } + rows.Next() + rows.Scan(&checkCount) + rows.Close() + if checkCount == 0 { + return db.Exec(sql, values...).Error + } + return nil } // Delete delete relationship in join table for sources