@@ -210,6 +210,11 @@ public partial class SQLiteConnection : IDisposable
210210 /// </summary>
211211 public bool StoreDateTimeAsTicks { get ; private set ; }
212212
213+ /// <summary>
214+ /// Whether to store TimeSpan properties as ticks (true) or strings (false).
215+ /// </summary>
216+ public bool StoreTimeSpanAsTicks { get ; private set ; }
217+
213218 /// <summary>
214219 /// The format to use when storing DateTime properties as strings. Ignored if StoreDateTimeAsTicks is true.
215220 /// </summary>
@@ -560,7 +565,7 @@ public CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateF
560565
561566 // Build query.
562567 var query = "create " + @virtual + "table if not exists \" " + map . TableName + "\" " + @using + "(\n " ;
563- var decls = map . Columns . Select ( p => Orm . SqlDecl ( p , StoreDateTimeAsTicks ) ) ;
568+ var decls = map . Columns . Select ( p => Orm . SqlDecl ( p , StoreDateTimeAsTicks , StoreTimeSpanAsTicks ) ) ;
564569 var decl = string . Join ( ",\n " , decls . ToArray ( ) ) ;
565570 query += decl ;
566571 query += ")" ;
@@ -826,7 +831,7 @@ void MigrateTable (TableMapping map, List<ColumnInfo> existingCols)
826831 }
827832
828833 foreach ( var p in toBeAdded ) {
829- var addCol = "alter table \" " + map . TableName + "\" add column " + Orm . SqlDecl ( p , StoreDateTimeAsTicks ) ;
834+ var addCol = "alter table \" " + map . TableName + "\" add column " + Orm . SqlDecl ( p , StoreDateTimeAsTicks , StoreTimeSpanAsTicks ) ;
830835 Execute ( addCol ) ;
831836 }
832837 }
@@ -2110,6 +2115,7 @@ public class SQLiteConnectionString
21102115 public string UniqueKey { get ; }
21112116 public string DatabasePath { get ; }
21122117 public bool StoreDateTimeAsTicks { get ; }
2118+ public bool StoreTimeSpanAsTicks { get ; }
21132119 public string DateTimeStringFormat { get ; }
21142120 public System . Globalization . DateTimeStyles DateTimeStyle { get ; }
21152121 public object Key { get ; }
@@ -2219,13 +2225,20 @@ public SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks, o
22192225 /// <param name="dateTimeStringFormat">
22202226 /// Specifies the format to use when storing DateTime properties as strings.
22212227 /// </param>
2222- public SQLiteConnectionString ( string databasePath , SQLiteOpenFlags openFlags , bool storeDateTimeAsTicks , object key = null , Action < SQLiteConnection > preKeyAction = null , Action < SQLiteConnection > postKeyAction = null , string vfsName = null , string dateTimeStringFormat = DateTimeSqliteDefaultFormat )
2228+ /// <param name="storeTimeSpanAsTicks">
2229+ /// Specifies whether to store TimeSpan properties as ticks (true) or strings (false). You
2230+ /// absolutely do want to store them as Ticks in all new projects. The value of false is
2231+ /// only here for backwards compatibility. There is a *significant* speed advantage, with no
2232+ /// down sides, when setting storeTimeSpanAsTicks = true.
2233+ /// </param>
2234+ public SQLiteConnectionString ( string databasePath , SQLiteOpenFlags openFlags , bool storeDateTimeAsTicks , object key = null , Action < SQLiteConnection > preKeyAction = null , Action < SQLiteConnection > postKeyAction = null , string vfsName = null , string dateTimeStringFormat = DateTimeSqliteDefaultFormat , bool storeTimeSpanAsTicks = true )
22232235 {
22242236 if ( key != null && ! ( ( key is byte [ ] ) || ( key is string ) ) )
22252237 throw new ArgumentException ( "Encryption keys must be strings or byte arrays" , nameof ( key ) ) ;
22262238
22272239 UniqueKey = string . Format ( "{0}_{1:X8}" , databasePath , ( uint ) openFlags ) ;
22282240 StoreDateTimeAsTicks = storeDateTimeAsTicks ;
2241+ StoreTimeSpanAsTicks = storeTimeSpanAsTicks ;
22292242 DateTimeStringFormat = dateTimeStringFormat ;
22302243 DateTimeStyle = "o" . Equals ( DateTimeStringFormat , StringComparison . OrdinalIgnoreCase ) || "r" . Equals ( DateTimeStringFormat , StringComparison . OrdinalIgnoreCase ) ? System . Globalization . DateTimeStyles . RoundtripKind : System . Globalization . DateTimeStyles . None ;
22312244 Key = key ;
@@ -2623,9 +2636,9 @@ public static Type GetType (object obj)
26232636 return obj . GetType ( ) ;
26242637 }
26252638
2626- public static string SqlDecl ( TableMapping . Column p , bool storeDateTimeAsTicks )
2639+ public static string SqlDecl ( TableMapping . Column p , bool storeDateTimeAsTicks , bool storeTimeSpanAsTicks )
26272640 {
2628- string decl = "\" " + p . Name + "\" " + SqlType ( p , storeDateTimeAsTicks ) + " " ;
2641+ string decl = "\" " + p . Name + "\" " + SqlType ( p , storeDateTimeAsTicks , storeTimeSpanAsTicks ) + " " ;
26292642
26302643 if ( p . IsPK ) {
26312644 decl += "primary key " ;
@@ -2643,7 +2656,7 @@ public static string SqlDecl (TableMapping.Column p, bool storeDateTimeAsTicks)
26432656 return decl ;
26442657 }
26452658
2646- public static string SqlType ( TableMapping . Column p , bool storeDateTimeAsTicks )
2659+ public static string SqlType ( TableMapping . Column p , bool storeDateTimeAsTicks , bool storeTimeSpanAsTicks )
26472660 {
26482661 var clrType = p . ColumnType ;
26492662 if ( clrType == typeof ( Boolean ) || clrType == typeof ( Byte ) || clrType == typeof ( UInt16 ) || clrType == typeof ( SByte ) || clrType == typeof ( Int16 ) || clrType == typeof ( Int32 ) || clrType == typeof ( UInt32 ) || clrType == typeof ( Int64 ) ) {
@@ -2661,7 +2674,7 @@ public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks)
26612674 return "varchar" ;
26622675 }
26632676 else if ( clrType == typeof ( TimeSpan ) ) {
2664- return "bigint" ;
2677+ return storeTimeSpanAsTicks ? "bigint" : "time ";
26652678 }
26662679 else if ( clrType == typeof ( DateTime ) ) {
26672680 return storeDateTimeAsTicks ? "bigint" : "datetime" ;
@@ -2947,13 +2960,13 @@ void BindAll (Sqlite3Statement stmt)
29472960 b . Index = nextIdx ++ ;
29482961 }
29492962
2950- BindParameter ( stmt , b . Index , b . Value , _conn . StoreDateTimeAsTicks , _conn . DateTimeStringFormat ) ;
2963+ BindParameter ( stmt , b . Index , b . Value , _conn . StoreDateTimeAsTicks , _conn . DateTimeStringFormat , _conn . StoreTimeSpanAsTicks ) ;
29512964 }
29522965 }
29532966
29542967 static IntPtr NegativePointer = new IntPtr ( - 1 ) ;
29552968
2956- internal static void BindParameter ( Sqlite3Statement stmt , int index , object value , bool storeDateTimeAsTicks , string dateTimeStringFormat )
2969+ internal static void BindParameter ( Sqlite3Statement stmt , int index , object value , bool storeDateTimeAsTicks , string dateTimeStringFormat , bool storeTimeSpanAsTicks )
29572970 {
29582971 if ( value == null ) {
29592972 SQLite3 . BindNull ( stmt , index ) ;
@@ -2978,7 +2991,12 @@ internal static void BindParameter (Sqlite3Statement stmt, int index, object val
29782991 SQLite3 . BindDouble ( stmt , index , Convert . ToDouble ( value ) ) ;
29792992 }
29802993 else if ( value is TimeSpan ) {
2981- SQLite3 . BindInt64 ( stmt , index , ( ( TimeSpan ) value ) . Ticks ) ;
2994+ if ( storeTimeSpanAsTicks ) {
2995+ SQLite3 . BindInt64 ( stmt , index , ( ( TimeSpan ) value ) . Ticks ) ;
2996+ }
2997+ else {
2998+ SQLite3 . BindText ( stmt , index , ( ( TimeSpan ) value ) . ToString ( ) , - 1 , NegativePointer ) ;
2999+ }
29823000 }
29833001 else if ( value is DateTime ) {
29843002 if ( storeDateTimeAsTicks ) {
@@ -3061,7 +3079,17 @@ object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clr
30613079 return ( float ) SQLite3 . ColumnDouble ( stmt , index ) ;
30623080 }
30633081 else if ( clrType == typeof ( TimeSpan ) ) {
3064- return new TimeSpan ( SQLite3 . ColumnInt64 ( stmt , index ) ) ;
3082+ if ( _conn . StoreTimeSpanAsTicks ) {
3083+ return new TimeSpan ( SQLite3 . ColumnInt64 ( stmt , index ) ) ;
3084+ }
3085+ else {
3086+ var text = SQLite3 . ColumnString ( stmt , index ) ;
3087+ TimeSpan resultTime ;
3088+ if ( ! TimeSpan . TryParseExact ( text , "c" , System . Globalization . CultureInfo . InvariantCulture , System . Globalization . TimeSpanStyles . None , out resultTime ) ) {
3089+ resultTime = TimeSpan . Parse ( text ) ;
3090+ }
3091+ return resultTime ;
3092+ }
30653093 }
30663094 else if ( clrType == typeof ( DateTime ) ) {
30673095 if ( _conn . StoreDateTimeAsTicks ) {
@@ -3174,7 +3202,7 @@ public int ExecuteNonQuery (object[] source)
31743202 //bind the values.
31753203 if ( source != null ) {
31763204 for ( int i = 0 ; i < source . Length ; i ++ ) {
3177- SQLiteCommand . BindParameter ( Statement , i + 1 , source [ i ] , Connection . StoreDateTimeAsTicks , Connection . DateTimeStringFormat ) ;
3205+ SQLiteCommand . BindParameter ( Statement , i + 1 , source [ i ] , Connection . StoreDateTimeAsTicks , Connection . DateTimeStringFormat , Connection . StoreTimeSpanAsTicks ) ;
31783206 }
31793207 }
31803208 r = SQLite3 . Step ( Statement ) ;
0 commit comments