@@ -984,7 +984,7 @@ private void RollbackTo(string? savepoint, bool noThrow)
984984 else
985985 {
986986 if ( IsInTransaction )
987- DoSavePointExecute ( savepoint ! , "rollback to " ) ;
987+ DoSavePointExecute ( savepoint ! , "rollback to " , true ) ;
988988 else
989989 transactionDepth = 0 ;
990990 }
@@ -1009,9 +1009,9 @@ private void RollbackTo(string? savepoint, bool noThrow)
10091009 /// All transactions methods creates a state in this connection. Be sure to not share it with other calls.
10101010 /// </remarks>
10111011 public void Release ( string savepoint )
1012- => DoSavePointExecute ( savepoint , "release " ) ;
1012+ => DoSavePointExecute ( savepoint , "release " , false ) ;
10131013
1014- private void DoSavePointExecute ( string savePoint , string cmd )
1014+ private void DoSavePointExecute ( string savePoint , string cmd , bool isRollback )
10151015 {
10161016 // Validate the savepoint
10171017 var firstLen = savePoint ? . IndexOf ( 'D' ) ?? 0 ;
@@ -1021,19 +1021,22 @@ private void DoSavePointExecute(string savePoint, string cmd)
10211021 if ( ! int . TryParse ( savePoint . Substring ( firstLen + 1 ) , out var depth ) || depth < 0 )
10221022 throw new ArgumentException ( $ "savePoint '{ savePoint } ' is not valid, and should be the result of a call to SaveTransactionPoint.", nameof ( savePoint ) ) ;
10231023
1024- if ( depth == 1 )
1025- {
1026- RollbackTo ( null , true ) ;
1027- return ;
1028- }
1024+ // if (depth == 1)
1025+ // {
1026+ // if (isRollback)
1027+ // {
1028+ // RollbackTo(null, true);
1029+ // }
1030+ // return;
1031+ // }
10291032
10301033 if ( depth > transactionDepth )
10311034 throw new ArgumentException ( $ "savePoint '{ savePoint } ' is not valid: depth ({ depth } ) >= transactionDepth ({ transactionDepth } )", nameof ( savePoint ) ) ;
10321035
10331036 try
10341037 {
1035- transactionDepth = depth - 1 ;
10361038 Execute ( cmd + savePoint ) ;
1039+ transactionDepth = depth - 1 ;
10371040 }
10381041 catch
10391042 {
@@ -1046,28 +1049,37 @@ private void DoSavePointExecute(string savePoint, string cmd)
10461049
10471050 /// <summary>
10481051 /// Executes
1049- /// <paramref name="action " />
1052+ /// <paramref name="writeAction " />
10501053 /// within a (possibly nested) transaction by wrapping it in a SAVEPOINT. If an
10511054 /// exception occurs the whole transaction is rolled back, not just the current savepoint. The exception
10521055 /// is rethrown.
10531056 /// </summary>
1054- /// <param name="action">
1055- /// The <see cref="Action" /> to perform within a transaction.
1056- /// <paramref name="action" />
1057- /// can contain any number
1058- /// of operations on the connection but should never call <see cref="BeginTransaction" /> or
1059- /// <see cref="Commit" />.
1057+ /// <param name="writeAction">
1058+ /// The <see cref="Action" /> to perform within a transaction.
1059+ /// <paramref name="writeAction" />
1060+ /// can contain any number of operations on the connection but should never call <see cref="BeginTransaction" /> or <see cref="Commit" />.
10601061 /// </param>
1062+ /// <param name="cloneConnection">clone the connection if not already in a transaction, to prevent sharing a transaction with other simultaneous calls that do not use a transaction.</param>
10611063 /// <remarks>
1064+ /// When not in a transaction, create a new connection to execute the write action so it is not shared with other calls.
1065+ ///
10621066 /// All transactions methods creates a state in this connection. Be sure to not share it with other calls.
10631067 /// </remarks>
1064- public void RunInTransaction ( Action action )
1068+ public void RunInTransaction ( Action < SQLiteConnection > writeAction , bool cloneConnection = true )
10651069 {
1070+ //When not in a transaction, create a new connection to execute the write action
1071+ if ( cloneConnection && ! IsInTransaction )
1072+ {
1073+ using var db = Clone ( ) ;
1074+ db . RunInTransaction ( writeAction , false ) ;
1075+ return ;
1076+ }
1077+
10661078 string ? savePoint = null ;
10671079 try
10681080 {
10691081 savePoint = SaveTransactionPoint ( ) ;
1070- action ( ) ;
1082+ writeAction ( this ) ;
10711083 Release ( savePoint ) ;
10721084 }
10731085 catch ( Exception e )
@@ -1096,11 +1108,9 @@ public int InsertAll(IEnumerable objects, bool runInTransaction = true)
10961108 var c = 0 ;
10971109 if ( runInTransaction )
10981110 {
1099- using var db = Clone ( ) ;
1100- db . RunInTransaction ( ( ) =>
1111+ RunInTransaction ( db =>
11011112 {
1102- foreach ( var r in objects )
1103- c += db . Insert ( r ) ;
1113+ c = db . InsertAll ( objects , false ) ;
11041114 } ) ;
11051115 }
11061116 else
@@ -1132,8 +1142,7 @@ public int InsertAll(IEnumerable objects, string extra, bool runInTransaction =
11321142 var c = 0 ;
11331143 if ( runInTransaction )
11341144 {
1135- using var db = Clone ( ) ;
1136- db . RunInTransaction ( ( ) =>
1145+ RunInTransaction ( db =>
11371146 {
11381147 foreach ( var r in objects )
11391148 c += db . Insert ( r , extra ) ;
@@ -1168,8 +1177,7 @@ public int InsertAll(IEnumerable objects, Type objType, bool runInTransaction =
11681177 var c = 0 ;
11691178 if ( runInTransaction )
11701179 {
1171- using var db = Clone ( ) ;
1172- db . RunInTransaction ( ( ) =>
1180+ RunInTransaction ( db =>
11731181 {
11741182 foreach ( var r in objects )
11751183 c += db . Insert ( r , objType ) ;
@@ -1240,8 +1248,7 @@ public int InsertOrReplace(object? obj)
12401248 public int InsertOrReplaceAll ( IEnumerable objects )
12411249 {
12421250 var c = 0 ;
1243- using var db = Clone ( ) ;
1244- db . RunInTransaction ( ( ) =>
1251+ RunInTransaction ( db =>
12451252 {
12461253 foreach ( var r in objects )
12471254 c += db . InsertOrReplace ( r ) ;
@@ -1306,8 +1313,7 @@ public int InsertOrReplace(object obj, Type objType)
13061313 public int InsertOrReplaceAll ( IEnumerable objects , Type objType )
13071314 {
13081315 var c = 0 ;
1309- using var db = Clone ( ) ;
1310- db . RunInTransaction ( ( ) =>
1316+ RunInTransaction ( db =>
13111317 {
13121318 foreach ( var r in objects )
13131319 c += db . InsertOrReplace ( r , objType ) ;
@@ -1492,10 +1498,13 @@ public int Update(object obj, Type objType)
14921498 throw new NotSupportedException ( "Cannot update " + map . TableName + ": it has no PK" ) ;
14931499 }
14941500
1495- var cols = from p in map . Columns
1501+ var cols = ( from p in map . Columns
14961502 where ! ( from pkey in map . PKs
14971503 select pkey ) . Contains ( p )
1498- select p ;
1504+ select p ) . ToList ( ) ;
1505+
1506+ if ( cols . Count == 0 )
1507+ return 0 ;
14991508
15001509 var vals = from c in cols
15011510 select c . GetValue ( obj ) ;
@@ -1515,9 +1524,9 @@ public int Update(object obj, Type objType)
15151524 }
15161525 else
15171526 {
1518- q = string . Format ( "update \" {0}\" set {1} where {2} = ? " , map . TableName ,
1527+ q = string . Format ( "update \" {0}\" set {1} where {2} " , map . TableName ,
15191528 string . Join ( "," , ( from c in cols select "\" " + c . Name + "\" = ? " ) . ToArray ( ) ) ,
1520- pk . Name ) ;
1529+ map . PkWhereSql ) ;
15211530 }
15221531
15231532 try
@@ -1556,8 +1565,7 @@ public int UpdateAll(IEnumerable objects, bool runInTransaction = true)
15561565 var c = 0 ;
15571566 if ( runInTransaction )
15581567 {
1559- using var db = Clone ( ) ;
1560- db . RunInTransaction ( ( ) =>
1568+ RunInTransaction ( db =>
15611569 {
15621570 foreach ( var r in objects )
15631571 c += db . Update ( r ) ;
0 commit comments