Skip to content

Commit

Permalink
if the CancelToken was set during a Prepare() call, a SQLite3Exceptio…
Browse files Browse the repository at this point in the history
…n was thrown instead of a OperationCanceledException
  • Loading branch information
carlosirna committed Sep 22, 2023
1 parent cba2f7e commit e1e4d5f
Showing 1 changed file with 112 additions and 64 deletions.
176 changes: 112 additions & 64 deletions src/SQLite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3309,6 +3309,7 @@ public static bool IsMarkedNotNull (MemberInfo p)
}
}


public partial class SQLiteCommand
{
SQLiteConnection _conn;
Expand All @@ -3329,11 +3330,17 @@ public int ExecuteNonQuery (CancellationToken? cancTok = null)
}
cancTok?.ThrowIfCancellationRequested ();
using (var interruptCallbackRegistration = cancTok?.Register (() => SQLite3.Interrupt (_conn.Handle))) {

var r = SQLite3.Result.OK;
var stmt = Prepare ();
r = SQLite3.Step (stmt);
Finalize (stmt);
SQLite3.Result r = SQLite3.Result.OK;
try {
var stmt = Prepare ();
r = SQLite3.Step (stmt);
Finalize (stmt);
}
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}
if (r == SQLite3.Result.Done) {
int rowsAffected = SQLite3.Changes (_conn.Handle);
return rowsAffected;
Expand Down Expand Up @@ -3410,66 +3417,85 @@ public IEnumerable<T> CancelableExecuteDeferredQuery<T> (CancellationToken? canc

cancTok?.ThrowIfCancellationRequested ();
using (var interruptCallbackRegistration = cancTok?.Register (() => SQLite3.Interrupt (_conn.Handle))) {
var stmt = Prepare ();
try {

var cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)];
var fastColumnSetters = new Action<object, Sqlite3Statement, int>[SQLite3.ColumnCount (stmt)];
Sqlite3Statement stmt = default;
TableMapping.Column[] cols = null;
Action<object, Sqlite3Statement, int>[] fastColumnSetters = null;
try {
try {
stmt = Prepare ();
cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)];
fastColumnSetters = new Action<object, Sqlite3Statement, int>[SQLite3.ColumnCount (stmt)];

if (map.Method == TableMapping.MapMethod.ByPosition) {
Array.Copy (map.Columns, cols, Math.Min (cols.Length, map.Columns.Length));
}
else if (map.Method == TableMapping.MapMethod.ByName) {
MethodInfo getSetter = null;
if (typeof (T) != map.MappedType) {
getSetter = typeof (FastColumnSetter)
.GetMethod (nameof (FastColumnSetter.GetFastSetter),
BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod (map.MappedType);
if (map.Method == TableMapping.MapMethod.ByPosition) {
Array.Copy (map.Columns, cols, Math.Min (cols.Length, map.Columns.Length));
}
else if (map.Method == TableMapping.MapMethod.ByName) {
MethodInfo getSetter = null;
if (typeof (T) != map.MappedType) {
getSetter = typeof (FastColumnSetter)
.GetMethod (nameof (FastColumnSetter.GetFastSetter),
BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod (map.MappedType);
}

for (int i = 0; i < cols.Length; i++) {
var name = SQLite3.ColumnName16 (stmt, i);
cols[i] = map.FindColumn (name);
if (cols[i] != null)
if (getSetter != null) {
fastColumnSetters[i] = (Action<object, Sqlite3Statement, int>)getSetter.Invoke (null, new object[] { _conn, cols[i] });
}
else {
fastColumnSetters[i] = FastColumnSetter.GetFastSetter<T> (_conn, cols[i]);
}
for (int i = 0; i < cols.Length; i++) {
var name = SQLite3.ColumnName16 (stmt, i);
cols[i] = map.FindColumn (name);
if (cols[i] != null)
if (getSetter != null) {
fastColumnSetters[i] = (Action<object, Sqlite3Statement, int>)getSetter.Invoke (null, new object[] { _conn, cols[i] });
}
else {
fastColumnSetters[i] = FastColumnSetter.GetFastSetter<T> (_conn, cols[i]);
}
}
}
}
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}

while (true) {
var r = SQLite3.Step (stmt);
if (r == SQLite3.Result.Done)
break;
object obj = null;
try {
var r = SQLite3.Step (stmt);
if (r == SQLite3.Result.Done)
break;

cancTok?.ThrowIfCancellationRequested ();
cancTok?.ThrowIfCancellationRequested ();

if (r != SQLite3.Result.Row)
throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));
if (r != SQLite3.Result.Row)
throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));

var obj = Activator.CreateInstance (map.MappedType);
for (int i = 0; i < cols.Length; i++) {
if (cols[i] == null)
continue;
obj = Activator.CreateInstance (map.MappedType);
for (int i = 0; i < cols.Length; i++) {
if (cols[i] == null)
continue;

if (fastColumnSetters[i] != null) {
fastColumnSetters[i].Invoke (obj, stmt, i);
}
else {
var colType = SQLite3.ColumnType (stmt, i);
var val = ReadCol (stmt, i, colType, cols[i].ColumnType);
cols[i].SetValue (obj, val);
if (fastColumnSetters[i] != null) {
fastColumnSetters[i].Invoke (obj, stmt, i);
}
else {
var colType = SQLite3.ColumnType (stmt, i);
var val = ReadCol (stmt, i, colType, cols[i].ColumnType);
cols[i].SetValue (obj, val);
}
}
OnInstanceCreated (obj);
}
OnInstanceCreated (obj);
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}

yield return (T)obj;
}
}
finally {
SQLite3.Finalize (stmt);
if (stmt != default)
SQLite3.Finalize (stmt);
}
}
}
Expand All @@ -3482,10 +3508,9 @@ public T ExecuteScalar<T> (CancellationToken? cancTok = null)

cancTok?.ThrowIfCancellationRequested ();
using (var interruptCallbackRegistration = cancTok?.Register (() => SQLite3.Interrupt (_conn.Handle))) {

var stmt = Prepare ();
Sqlite3Statement stmt = default;
try {

stmt = Prepare ();
var r = SQLite3.Step (stmt);
if (r == SQLite3.Result.Done)
return default (T);
Expand All @@ -3503,8 +3528,14 @@ public T ExecuteScalar<T> (CancellationToken? cancTok = null)
throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));

}
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}
finally {
Finalize (stmt);
if (stmt != default)
Finalize (stmt);
}
}
}
Expand All @@ -3516,22 +3547,38 @@ public IEnumerable<T> ExecuteQueryScalars<T> (CancellationToken? cancTok)
}
cancTok?.ThrowIfCancellationRequested ();
using (var interruptCallbackRegistration = cancTok?.Register (() => SQLite3.Interrupt (_conn.Handle))) {
var stmt = Prepare ();
Sqlite3Statement stmt = default;
try {
if (SQLite3.ColumnCount (stmt) < 1) {
throw new InvalidOperationException ("QueryScalars should return at least one column");
try {
stmt = Prepare ();
if (SQLite3.ColumnCount (stmt) < 1) {
throw new InvalidOperationException ("QueryScalars should return at least one column");
}
}
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}

while (true) {
var r = SQLite3.Step (stmt);
if (r == SQLite3.Result.Done)
break;
cancTok?.ThrowIfCancellationRequested ();
if (r != SQLite3.Result.Row)
throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));
object val = null;
try {
var r = SQLite3.Step (stmt);
if (r == SQLite3.Result.Done)
break;
cancTok?.ThrowIfCancellationRequested ();
if (r != SQLite3.Result.Row)
throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));

var colType = SQLite3.ColumnType (stmt, 0);
var val = ReadCol (stmt, 0, colType, typeof (T));
var colType = SQLite3.ColumnType (stmt, 0);
val = ReadCol (stmt, 0, colType, typeof (T));
}
catch (SQLiteException ex) {
if (ex.Result == SQLite3.Result.Interrupt && cancTok?.IsCancellationRequested == true)
throw new OperationCanceledException (cancTok.Value);
throw;
}
if (val == null) {
yield return default (T);
}
Expand All @@ -3541,7 +3588,8 @@ public IEnumerable<T> ExecuteQueryScalars<T> (CancellationToken? cancTok)
}
}
finally {
Finalize (stmt);
if (stmt != default)
Finalize (stmt);
}
}
}
Expand Down

0 comments on commit e1e4d5f

Please sign in to comment.