@@ -13,6 +13,16 @@ final _logger = Logger('database_access');
13
13
const whereIsNull = Object ();
14
14
const whereIsNotNull = Object ();
15
15
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
+
16
26
class DatabaseTransactionBase <TABLES extends TablesBase > {
17
27
DatabaseTransactionBase (this ._conn, this .tables);
18
28
@@ -31,13 +41,32 @@ class DatabaseTransactionBase<TABLES extends TablesBase> {
31
41
})());
32
42
}
33
43
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 {
35
49
_assertColumnNames (values);
36
50
final entries = values.entries.toList ();
37
51
final columnList = entries.map ((e) => e.key).join (',' );
38
52
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
+ }
39
68
return await execute (
40
- 'INSERT INTO $table ($columnList ) VALUES ($bindList )' ,
69
+ 'INSERT INTO $table ($columnList ) VALUES ($bindList ) $ onConflictSql ' ,
41
70
values: values.map ((key, value) =>
42
71
MapEntry (key, value is CustomBind ? value.value : value)),
43
72
expectedResultCount: 1 ,
0 commit comments