Skip to content

Commit

Permalink
Postgres ignore + replace (#298)
Browse files Browse the repository at this point in the history
* Add replace and ignore
* Test insert ignore
* fix insert and add back replace
* Pg replace (#2)
Make pg replace only use primary keys
  • Loading branch information
AllanWang authored and Tapac committed May 9, 2018
1 parent 9ca1bbc commit 2331213
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,33 @@ internal object PostgreSQLFunctionProvider : FunctionProvider() {
if (limit != null) transaction.throwUnsupportedException("PostgreSQL doesn't support LIMIT in UPDATE clause.")
return super.update(targets, columnsAndValues, limit, where, transaction)
}

override fun replace(table: Table, data: List<Pair<Column<*>, Any?>>, transaction: Transaction): String {

val builder = QueryBuilder(true)
val sql = if (data.isEmpty()) ""
else data.joinToString(prefix = "VALUES (", postfix = ")") { (col, value) ->
builder.registerArgument(col, value)
}

val columns = data.map { it.first }

val def = super.insert(false, table, columns, sql, transaction)

val uniqueCols = columns.filter { it.indexInPK != null }.sortedBy { it.indexInPK }
if (uniqueCols.isEmpty())
transaction.throwUnsupportedException("Postgres replace table must supply at least one primary key")
val conflictKey = uniqueCols.joinToString { transaction.identity(it) }
return def + "ON CONFLICT ($conflictKey) DO UPDATE SET " + columns.joinToString { "${transaction.identity(it)}=EXCLUDED.${transaction.identity(it)}" }
}

override fun insert(ignore: Boolean, table: Table, columns: List<Column<*>>, expr: String, transaction: Transaction): String {
val def = super.insert(false, table, columns, expr, transaction)
return if (ignore) "$def $onConflictIgnore" else def
}

private const val onConflictIgnore = "ON CONFLICT DO NOTHING"

}

internal class PostgreSQLDialect : VendorDialect(dialectName, PostgreSQLDataTypeProvider, PostgreSQLFunctionProvider) {
Expand Down

0 comments on commit 2331213

Please sign in to comment.