1
- using System ;
2
1
using System . Collections . Generic ;
3
2
using System . Data ;
4
3
using System . Data . Common ;
@@ -38,32 +37,46 @@ public SQLiteDialect()
38
37
39
38
protected virtual void RegisterColumnTypes ( )
40
39
{
40
+ // SQLite really has only five types, and a very lax typing system, see https://www.sqlite.org/datatype3.html
41
+ // Please do not map (again) fancy types that do not actually exist in SQLite, as this is kind of supported by
42
+ // SQLite but creates bugs in convert operations.
41
43
RegisterColumnType ( DbType . Binary , "BLOB" ) ;
42
- RegisterColumnType ( DbType . Byte , "TINYINT " ) ;
43
- RegisterColumnType ( DbType . Int16 , "SMALLINT " ) ;
44
- RegisterColumnType ( DbType . Int32 , "INT " ) ;
45
- RegisterColumnType ( DbType . Int64 , "BIGINT " ) ;
44
+ RegisterColumnType ( DbType . Byte , "INTEGER " ) ;
45
+ RegisterColumnType ( DbType . Int16 , "INTEGER " ) ;
46
+ RegisterColumnType ( DbType . Int32 , "INTEGER " ) ;
47
+ RegisterColumnType ( DbType . Int64 , "INTEGER " ) ;
46
48
RegisterColumnType ( DbType . SByte , "INTEGER" ) ;
47
49
RegisterColumnType ( DbType . UInt16 , "INTEGER" ) ;
48
50
RegisterColumnType ( DbType . UInt32 , "INTEGER" ) ;
49
51
RegisterColumnType ( DbType . UInt64 , "INTEGER" ) ;
52
+
53
+ // NUMERIC and REAL are almost the same, they are binary floating point numbers. There is only a slight difference
54
+ // for values without a floating part. They will be represented as integers with numeric, but still as floating
55
+ // values with real. The side-effect of this is numeric being able of storing exactly bigger integers than real.
50
56
RegisterColumnType ( DbType . Currency , "NUMERIC" ) ;
51
57
RegisterColumnType ( DbType . Decimal , "NUMERIC" ) ;
52
- RegisterColumnType ( DbType . Double , "DOUBLE " ) ;
53
- RegisterColumnType ( DbType . Single , "DOUBLE " ) ;
58
+ RegisterColumnType ( DbType . Double , "REAL " ) ;
59
+ RegisterColumnType ( DbType . Single , "REAL " ) ;
54
60
RegisterColumnType ( DbType . VarNumeric , "NUMERIC" ) ;
61
+
55
62
RegisterColumnType ( DbType . AnsiString , "TEXT" ) ;
56
63
RegisterColumnType ( DbType . String , "TEXT" ) ;
57
64
RegisterColumnType ( DbType . AnsiStringFixedLength , "TEXT" ) ;
58
65
RegisterColumnType ( DbType . StringFixedLength , "TEXT" ) ;
59
66
60
- RegisterColumnType ( DbType . Date , "DATE" ) ;
61
- RegisterColumnType ( DbType . DateTime , "DATETIME" ) ;
62
- RegisterColumnType ( DbType . Time , "TIME" ) ;
63
- RegisterColumnType ( DbType . Boolean , "BOOL" ) ;
64
- // UNIQUEIDENTIFIER is not a SQLite type, but SQLite does not care much, see
65
- // https://www.sqlite.org/datatype3.html
66
- RegisterColumnType ( DbType . Guid , "UNIQUEIDENTIFIER" ) ;
67
+ // https://www.sqlite.org/datatype3.html#boolean_datatype
68
+ RegisterColumnType ( DbType . Boolean , "INTEGER" ) ;
69
+
70
+ // See https://www.sqlite.org/datatype3.html#date_and_time_datatype, we have three choices for date and time
71
+ // The one causing the less issues in case of an explicit cast is text. Beware, System.Data.SQLite has an
72
+ // internal use only "DATETIME" type. Using it causes it to directly convert the text stored into SQLite to
73
+ // a .Net DateTime, but also causes columns in SQLite to have numeric affinity and convert to destroy the
74
+ // value. As said in their chm documentation, this "DATETIME" type is for System.Data.SQLite internal use only.
75
+ RegisterColumnType ( DbType . Date , "TEXT" ) ;
76
+ RegisterColumnType ( DbType . DateTime , "TEXT" ) ;
77
+ RegisterColumnType ( DbType . Time , "TEXT" ) ;
78
+
79
+ RegisterColumnType ( DbType . Guid , _binaryGuid ? "BLOB" : "TEXT" ) ;
67
80
}
68
81
69
82
protected virtual void RegisterFunctions ( )
@@ -98,8 +111,6 @@ protected virtual void RegisterFunctions()
98
111
99
112
RegisterFunction ( "iif" , new SQLFunctionTemplate ( null , "case when ?1 then ?2 else ?3 end" ) ) ;
100
113
101
- RegisterFunction ( "cast" , new SQLiteCastFunction ( ) ) ;
102
-
103
114
RegisterFunction ( "round" , new StandardSQLFunction ( "round" ) ) ;
104
115
105
116
// SQLite has no built-in support of bitwise xor, but can emulate it.
@@ -112,7 +123,7 @@ protected virtual void RegisterFunctions()
112
123
if ( _binaryGuid )
113
124
RegisterFunction ( "strguid" , new SQLFunctionTemplate ( NHibernateUtil . String , "substr(hex(?1), 7, 2) || substr(hex(?1), 5, 2) || substr(hex(?1), 3, 2) || substr(hex(?1), 1, 2) || '-' || substr(hex(?1), 11, 2) || substr(hex(?1), 9, 2) || '-' || substr(hex(?1), 15, 2) || substr(hex(?1), 13, 2) || '-' || substr(hex(?1), 17, 4) || '-' || substr(hex(?1), 21) " ) ) ;
114
125
else
115
- RegisterFunction ( "strguid" , new SQLFunctionTemplate ( NHibernateUtil . String , "cast(?1 as char )" ) ) ;
126
+ RegisterFunction ( "strguid" , new SQLFunctionTemplate ( NHibernateUtil . String , "cast(?1 as text )" ) ) ;
116
127
117
128
// SQLite random function yields a long, ranging form MinValue to MaxValue. (-9223372036854775808 to
118
129
// 9223372036854775807). HQL random requires a float from 0 inclusive to 1 exclusive, so we divide by
@@ -131,7 +142,8 @@ public override void Configure(IDictionary<string, string> settings)
131
142
132
143
ConfigureBinaryGuid ( settings ) ;
133
144
134
- // Re-register functions depending on settings.
145
+ // Re-register functions and types depending on settings.
146
+ RegisterColumnTypes ( ) ;
135
147
RegisterFunctions ( ) ;
136
148
}
137
149
@@ -484,17 +496,5 @@ public override bool SupportsForeignKeyConstraintInAlterTable
484
496
// Said to be unlimited. http://sqlite.1065341.n5.nabble.com/Max-limits-on-the-following-td37859.html
485
497
/// <inheritdoc />
486
498
public override int MaxAliasLength => 128 ;
487
-
488
- [ Serializable ]
489
- protected class SQLiteCastFunction : CastFunction
490
- {
491
- protected override bool CastingIsRequired ( string sqlType )
492
- {
493
- // SQLite doesn't support casting to datetime types. It assumes you want an integer and destroys the date string.
494
- if ( StringHelper . ContainsCaseInsensitive ( sqlType , "date" ) || StringHelper . ContainsCaseInsensitive ( sqlType , "time" ) )
495
- return false ;
496
- return true ;
497
- }
498
- }
499
499
}
500
500
}
0 commit comments