@@ -13,6 +13,16 @@ final _logger = Logger('database_access');
1313const whereIsNull = Object ();
1414const whereIsNotNull = Object ();
1515
16+ class OnConflictActionDoUpdate extends OnConflictAction {
17+ OnConflictActionDoUpdate ({required this .indexColumns});
18+
19+ final List <String > indexColumns;
20+ }
21+
22+ abstract class OnConflictAction {
23+ // doUpdate,
24+ }
25+
1626class DatabaseTransactionBase <TABLES extends TablesBase > {
1727 DatabaseTransactionBase (this ._conn, this .tables);
1828
@@ -31,13 +41,32 @@ class DatabaseTransactionBase<TABLES extends TablesBase> {
3141 })());
3242 }
3343
34- Future <int > executeInsert (String table, Map <String , Object ?> values) async {
44+ Future <int > executeInsert (
45+ String table,
46+ Map <String , Object ?> values, {
47+ final OnConflictAction ? onConflict,
48+ }) async {
3549 _assertColumnNames (values);
3650 final entries = values.entries.toList ();
3751 final columnList = entries.map ((e) => e.key).join (',' );
3852 final bindList = entries.map ((e) => _bindForEntry (e)).join (',' );
53+ final String onConflictSql;
54+ if (onConflict is OnConflictActionDoUpdate ) {
55+ final set = entries
56+ .where ((element) => ! onConflict.indexColumns.contains (element.key))
57+ .map ((e) => '${e .key } = EXCLUDED.${e .key }' )
58+ .join (', ' );
59+ final where = entries
60+ .where ((element) => onConflict.indexColumns.contains (element.key))
61+ .map ((e) => '$table .${e .key } = EXCLUDED.${e .key }' )
62+ .join (' AND ' );
63+ onConflictSql = ' ON CONFLICT (${onConflict .indexColumns .join (', ' )}) '
64+ ' DO UPDATE SET $set WHERE $where ' ;
65+ } else {
66+ onConflictSql = '' ;
67+ }
3968 return await execute (
40- 'INSERT INTO $table ($columnList ) VALUES ($bindList )' ,
69+ 'INSERT INTO $table ($columnList ) VALUES ($bindList ) $ onConflictSql ' ,
4170 values: values.map ((key, value) =>
4271 MapEntry (key, value is CustomBind ? value.value : value)),
4372 expectedResultCount: 1 ,
0 commit comments