diff --git a/src/Runtime/XSharp.SQLRdd/Classes/Command.prg b/src/Runtime/XSharp.SQLRdd/Classes/Command.prg
index 5aad8a2cce..9cb2b4800f 100644
--- a/src/Runtime/XSharp.SQLRdd/Classes/Command.prg
+++ b/src/Runtime/XSharp.SQLRdd/Classes/Command.prg
@@ -128,6 +128,13 @@ class SqlDbCommand inherit SqlDbHandleObject implements IDisposable
return
end constructor
+ /// Apply the connection's CommandTimeout (when set) to the command.
+ private method _ApplyTimeout() as VOID
+ if SELF:Connection:CommandTimeout >= 0 .and. SELF:DbCommand != null
+ SELF:DbCommand:CommandTimeout := SELF:Connection:CommandTimeout
+ endif
+ RETURN
+
private method CallBack(cTable as STRING) as VOID
if withEvents
self:CommandText := SELF:Connection:RaiseStringEvent(self, SqlRDDEventReason.CommandText, cTable, self:CommandText)
@@ -158,6 +165,7 @@ class SqlDbCommand inherit SqlDbHandleObject implements IDisposable
method GetSchemaTable() as DataTable
try
self:Connection:ForceOpen()
+ SELF:_ApplyTimeout()
if ! SELF:_TryBindParameters()
return null
endif
@@ -310,6 +318,7 @@ class SqlDbCommand inherit SqlDbHandleObject implements IDisposable
if self:Connection:DbTransaction != null
self:DbTransaction := self:Connection:DbTransaction
endif
+ SELF:_ApplyTimeout()
if ! SELF:_TryBindParameters()
return null
endif
@@ -348,6 +357,7 @@ class SqlDbCommand inherit SqlDbHandleObject implements IDisposable
if self:Connection:DbTransaction != null
self:DbTransaction := self:Connection:DbTransaction
endif
+ SELF:_ApplyTimeout()
if ! SELF:_TryBindParameters()
return null
endif
@@ -376,6 +386,7 @@ class SqlDbCommand inherit SqlDbHandleObject implements IDisposable
if self:Connection:DbTransaction != null
self:DbTransaction := self:Connection:DbTransaction
endif
+ SELF:_ApplyTimeout()
if ! SELF:_TryBindParameters()
return false
endif
diff --git a/src/Runtime/XSharp.SQLRdd/Classes/Connection.prg b/src/Runtime/XSharp.SQLRdd/Classes/Connection.prg
index 9dc87680fd..862bdd5bc7 100644
--- a/src/Runtime/XSharp.SQLRdd/Classes/Connection.prg
+++ b/src/Runtime/XSharp.SQLRdd/Classes/Connection.prg
@@ -151,6 +151,14 @@ class SqlDbConnection inherit SqlDbHandleObject implements IDisposable
end get
end property
+ ///
+ /// Time in seconds a statement may run before it is cancelled (0 = no limit, default -1 = the
+ /// ADO.NET provider's default, 30 seconds for SQL Server).
+ ///
+ /// A count or an index on a table with millions of rows can take longer than the default. A
+ /// statement that times out is reported like any other error, which for a read means no rows.
+ property CommandTimeout as long auto
+
/// Identifier Case as returned by the Ado.Net provider in the DataSourceInformation metadata collection.
property IdentifierCase as System.Data.Common.IdentifierCase auto get private set
/// Quoted Identifier Case as returned by the Ado.Net provider in the DataSourceInformation metadata collection.
@@ -266,6 +274,10 @@ class SqlDbConnection inherit SqlDbHandleObject implements IDisposable
if Int32.TryParse(strValue, out var cacheMs)
self:ResultCacheMs := cacheMs
endif
+ case "commandtimeout"
+ if Int32.TryParse(strValue, out var timeout)
+ self:CommandTimeout := timeout
+ endif
otherwise
builder:Add(key, strValue)
end switch
@@ -332,6 +344,7 @@ class SqlDbConnection inherit SqlDbHandleObject implements IDisposable
LegacyFieldTypes := DEFAULT_LEGACYFIELDTYPES
UseNulls := DEFAULT_USENULLS
UseLocks := DEFAULT_USELOCKS
+ CommandTimeout := -1
LongFieldNames := DEFAULT_LONGFIELDNAMES
TrimTrailingSpaces := DEFAULT_TRIMTRAILINGSPACES
PageSize := DEFAULT_PAGESIZE