Skip to content

Commit c1c1017

Browse files
committed
#568 Add support for SQLite (not yet complete, but getting close)
1 parent a56a599 commit c1c1017

File tree

3 files changed

+194
-268
lines changed

3 files changed

+194
-268
lines changed

EntityFramework.Reverse.POCO.Generator/EF.Reverse.POCO.v3.ttinclude

Lines changed: 64 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -14719,12 +14719,11 @@ SELECT 'main' AS SchemaName,
1471914719
ColumnName,
1472014720
IsNullable,
1472114721
REPLACE(type, '(' || length || ')', '') AS TypeName,
14722-
type as XXXXX,
1472314722
CASE WHEN INSTR(type, ',') > 0 THEN 0 ELSE length END AS [MaxLength],
14724-
CASE WHEN INSTR(type, ',') > 0 THEN SUBSTR(type, INSTR(type, ',') - 1) ELSE 0 END AS Precision,
14723+
Precision,
1472514724
dflt_value AS [Default],
1472614725
0 AS DateTimePrecision,
14727-
CASE WHEN INSTR(type, ',') > 0 THEN SUBSTR(type, 1, INSTR(type, ',') - 1) ELSE 0 END AS Scale,
14726+
Scale,
1472814727
pk AS IsIdentity,
1472914728
0 AS IsRowGuid,
1473014729
0 AS IsComputed,
@@ -14741,7 +14740,9 @@ FROM (SELECT m.tbl_name,
1474114740
1 - c.""notnull"" AS IsNullable,
1474214741
c.dflt_value,
1474314742
c.pk,
14744-
SUBSTR(c.type, INSTR(c.type, '(') + 1, INSTR(c.type, ')') - INSTR(c.type, '(') - 1) AS length
14743+
SUBSTR(c.type, INSTR(c.type, '(') + 1, INSTR(c.type, ')') - INSTR(c.type, '(') - 1) AS length,
14744+
CAST(SUBSTR(c.type, INSTR(c.type, '(') + 1, INSTR(c.type, ',') - INSTR(c.type, '(') - 1) AS INTEGER) AS Precision,
14745+
CAST(SUBSTR(c.type, INSTR(c.type, ',') + 1, INSTR(c.type, ')') - INSTR(c.type, ',') - 1) AS INTEGER) AS Scale
1474514746
FROM sqlite_master m
1474614747
JOIN PRAGMA_TABLE_INFO(m.name) c
1474714748
WHERE m.type IN ('table', 'view')
@@ -14752,67 +14753,26 @@ ORDER BY tbl_name, cid;";
1475214753
protected override string ForeignKeySQL()
1475314754
{
1475414755
return @"
14755-
SELECT fkData.FK_Table,
14756-
fkData.FK_Column,
14757-
fkData.PK_Table,
14758-
fkData.PK_Column,
14759-
fkData.Constraint_Name,
14760-
fkData.fkSchema,
14761-
fkData.pkSchema,
14762-
fkData.primarykey,
14763-
fkData.ORDINAL_POSITION,
14764-
fkData.CascadeOnDelete,
14765-
fkData.IsNotEnforced
14766-
FROM (SELECT FK.name AS FK_Table,
14767-
FkCol.name AS FK_Column,
14768-
PK.name AS PK_Table,
14769-
PkCol.name AS PK_Column,
14770-
OBJECT_NAME(f.object_id) AS Constraint_Name,
14771-
SCHEMA_NAME(FK.schema_id) AS fkSchema,
14772-
SCHEMA_NAME(PK.schema_id) AS pkSchema,
14773-
PkCol.name AS primarykey,
14774-
k.constraint_column_id AS ORDINAL_POSITION,
14775-
CASE WHEN f.delete_referential_action = 1 THEN 1
14776-
ELSE 0
14777-
END AS CascadeOnDelete,
14778-
f.is_disabled AS IsNotEnforced,
14779-
ROW_NUMBER() OVER (PARTITION BY FK.name, FkCol.name, PK.name, PkCol.name, SCHEMA_NAME(FK.schema_id), SCHEMA_NAME(PK.schema_id) ORDER BY f.object_id) AS n
14780-
FROM sys.objects AS PK
14781-
INNER JOIN sys.foreign_keys AS f
14782-
INNER JOIN sys.foreign_key_columns AS k
14783-
ON k.constraint_object_id = f.object_id
14784-
INNER JOIN sys.indexes AS i
14785-
ON f.referenced_object_id = i.object_id
14786-
AND f.key_index_id = i.index_id
14787-
ON PK.object_id = f.referenced_object_id
14788-
INNER JOIN sys.objects AS FK
14789-
ON f.parent_object_id = FK.object_id
14790-
INNER JOIN sys.columns AS PkCol
14791-
ON f.referenced_object_id = PkCol.object_id
14792-
AND k.referenced_column_id = PkCol.column_id
14793-
INNER JOIN sys.columns AS FkCol
14794-
ON f.parent_object_id = FkCol.object_id
14795-
AND k.parent_column_id = FkCol.column_id) fkData
14796-
WHERE fkData.n = 1 -- Remove duplicate foreign keys";
14756+
SELECT m.name AS FK_Table,
14757+
p.[from] AS FK_Column,
14758+
p.[table] AS PK_Table,
14759+
p.[to] AS PK_Column,
14760+
'FK_' || TRIM(m.name) || '_' || TRIM(p.[to]) as Constraint_Name,
14761+
'main' as fkSchema,
14762+
'main' as pkSchema,
14763+
p.[to] AS primarykey,
14764+
p.id + 1 as ORDINAL_POSITION,
14765+
case when P.on_delete is 'CASCADE' then 1 else 0 end as CascadeOnDelete,
14766+
0 as IsNotEnforced
14767+
FROM sqlite_master m
14768+
JOIN PRAGMA_FOREIGN_KEY_LIST(m.name) p ON m.name != p.[table]
14769+
WHERE m.type = 'table'
14770+
ORDER BY m.name;";
1479714771
}
1479814772

1479914773
protected override string ExtendedPropertySQL()
1480014774
{
14801-
return @"
14802-
SELECT s.name AS [schema],
14803-
t.name AS [table],
14804-
c.name AS [column],
14805-
value AS [property]
14806-
FROM sys.extended_properties AS ep
14807-
INNER JOIN sys.tables AS t
14808-
ON ep.major_id = t.object_id
14809-
INNER JOIN sys.schemas AS s
14810-
ON s.schema_id = t.schema_id
14811-
LEFT JOIN sys.columns AS c
14812-
ON ep.major_id = c.object_id
14813-
AND ep.minor_id = c.column_id
14814-
WHERE class = 1
14815-
ORDER BY t.name";
14775+
return string.Empty;
1481614776
}
1481714777

1481814778
protected override string DoesExtendedPropertyTableExistSQL()
@@ -14823,34 +14783,44 @@ ORDER BY t.name";
1482314783
protected override string IndexSQL()
1482414784
{
1482514785
return @"
14826-
SELECT SCHEMA_NAME(t.schema_id) AS TableSchema,
14827-
t.name AS TableName,
14828-
ind.name AS IndexName,
14829-
ic.key_ordinal AS KeyOrdinal,
14830-
col.name AS ColumnName,
14831-
ind.is_unique AS IsUnique,
14832-
ind.is_primary_key AS IsPrimaryKey,
14833-
ind.is_unique_constraint AS IsUniqueConstraint,
14834-
CASE WHEN ind.[type] = 1 AND ind.is_primary_key = 1 THEN 1 ELSE 0 END AS IsClustered,
14835-
(
14836-
SELECT COUNT(1)
14837-
FROM sys.index_columns i
14838-
WHERE i.object_id = ind.object_id
14839-
AND i.index_id = ind.index_id
14840-
) AS ColumnCount
14841-
FROM sys.tables t
14842-
INNER JOIN sys.indexes ind
14843-
ON ind.object_id = t.object_id
14844-
INNER JOIN sys.index_columns ic
14845-
ON ind.object_id = ic.object_id
14846-
AND ind.index_id = ic.index_id
14847-
INNER JOIN sys.columns col
14848-
ON ic.object_id = col.object_id
14849-
AND ic.column_id = col.column_id
14850-
WHERE t.is_ms_shipped = 0
14851-
AND ind.ignore_dup_key = 0
14852-
AND ic.key_ordinal > 0
14853-
AND t.name NOT LIKE 'sysdiagram%'";
14786+
WITH split(TableName, IndexName, KeyOrdinal, ColumnName, csv) AS (
14787+
SELECT TableName,
14788+
IndexName,
14789+
KeyOrdinal,
14790+
'',
14791+
column_name || ','
14792+
FROM (SELECT TableName,
14793+
IndexName,
14794+
0 AS KeyOrdinal,
14795+
SUBSTR(sql, INSTR(sql, '(') + 1, INSTR(sql, ')') - INSTR(sql, '(') - 1) AS column_name
14796+
FROM (SELECT tbl_name AS TableName,
14797+
name AS IndexName,
14798+
REPLACE(REPLACE(sql, ']', ''), '[', '') AS sql
14799+
FROM sqlite_master
14800+
WHERE type = 'index'
14801+
AND name NOT LIKE 'sqlite_%'))
14802+
UNION ALL
14803+
SELECT TableName,
14804+
IndexName,
14805+
KeyOrdinal + 1,
14806+
SUBSTR(csv, 0, INSTR(csv, ',')),
14807+
SUBSTR(csv, INSTR(csv, ',') + 1)
14808+
FROM split
14809+
WHERE csv != '')
14810+
SELECT 'main' AS TableSchema,
14811+
s.TableName,
14812+
s.IndexName,
14813+
s.KeyOrdinal,
14814+
TRIM(s.ColumnName),
14815+
0 AS IsUnique,
14816+
0 AS IsPrimaryKey,
14817+
0 AS IsUniqueConstraint,
14818+
(SELECT MAX(KeyOrdinal)
14819+
FROM split x
14820+
WHERE x.TableName = s.TableName
14821+
AND x.IndexName = s.IndexName) AS ColumnCount
14822+
FROM split s
14823+
WHERE ColumnName != ''";
1485414824
}
1485514825

1485614826
public override bool CanReadStoredProcedures()
@@ -14888,27 +14858,14 @@ SELECT * FROM MultiContext.ForeignKey;";
1488814858
protected override string TriggerSQL()
1488914859
{
1489014860
return @"
14891-
SELECT S.name SchemaName, O.name TableName, T.name TriggerName
14892-
FROM sys.triggers T
14893-
LEFT JOIN sys.all_objects O
14894-
ON T.parent_id = O.object_id
14895-
LEFT JOIN sys.schemas S
14896-
ON S.schema_id = O.schema_id
14897-
WHERE T.type = 'TR'
14898-
AND T.is_disabled = 0
14899-
AND S.name IS NOT NULL
14900-
AND O.name IS NOT NULL
14901-
ORDER BY SchemaName, TableName, TriggerName;";
14861+
SELECT 'main' AS TableSchema, tbl_name as TableName, name as TriggerName
14862+
FROM sqlite_master
14863+
WHERE type = 'trigger';";
1490214864
}
1490314865

1490414866
protected override string[] MemoryOptimisedSQL()
1490514867
{
14906-
return new string[]
14907-
{
14908-
"SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME();",
14909-
"SELECT CAST(SERVERPROPERTY(N'IsXTPSupported') AS BIT) AS IsXTPSupported;",
14910-
"SELECT SCHEMA_NAME(schema_id) SchemaName, name TableName FROM sys.tables WHERE is_memory_optimized = 1;"
14911-
};
14868+
return null;
1491214869
}
1491314870

1491414871
protected override string SynonymTableSQLSetup()
@@ -14943,27 +14900,7 @@ ORDER BY SchemaName, TableName, TriggerName;";
1494314900

1494414901
protected override string DefaultSchema(DbConnection conn)
1494514902
{
14946-
try
14947-
{
14948-
var cmd = GetCmd(conn);
14949-
if (cmd != null)
14950-
{
14951-
cmd.CommandText = "SELECT SCHEMA_NAME()";
14952-
using (var rdr = cmd.ExecuteReader())
14953-
{
14954-
if (rdr.Read())
14955-
{
14956-
return rdr[0].ToString();
14957-
}
14958-
}
14959-
}
14960-
}
14961-
catch
14962-
{
14963-
// Ignored
14964-
}
14965-
14966-
return "dbo";
14903+
return "main";
1496714904
}
1496814905

1496914906
protected override string SpecialQueryFlags()

Generator.Tests.Integration/SingleDatabaseTestSQLite.cs

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,81 @@ public SingleDatabaseTestSQLite()
3030
var cmd = _masterConnection.CreateCommand();
3131
cmd.CommandText =
3232
@"
33+
PRAGMA foreign_keys = ON;
34+
3335
CREATE TABLE Efrpg
3436
(
35-
Id INTEGER PRIMARY KEY,
36-
vc varchar(12) NULL,
37-
nvc nvarchar(12) NULL,
38-
int1 INTEGER DEFAULT 123,
39-
real1 REAL,
40-
text1 TEXT,
41-
text2 TEXT(20) DEFAULT 'Hello',
42-
blob1 BLOB,
43-
blob2 BLOB(37),
44-
num1 NUMERIC,
45-
num2 NUMERIC(10, 5)
37+
Id INTEGER,
38+
39+
text1 TEXT,
40+
text2 CHARACTER(22),
41+
text3 VARCHAR(33),
42+
text4 VARYING CHARACTER(44),
43+
text5 NCHAR(55),
44+
text6 NATIVE CHARACTER(66),
45+
text7 NVARCHAR(77),
46+
text8 TEXT(88) DEFAULT 'Hello',
47+
text9 CLOB,
48+
49+
int1 INTEGER DEFAULT 123,
50+
int2 INT UNIQUE,
51+
int3 SMALLINT,
52+
int4 MEDIUMINT,
53+
int5 BIGINT,
54+
int6 UNSIGNED BIG INT,
55+
int7 INT2,
56+
INT8 INT8,
57+
58+
blob1 BLOB,
59+
blob2 BLOB(22),
60+
61+
real1 REAL CHECK (real1 > 123),
62+
real2 DOUBLE,
63+
real3 DOUBLE PRECISION,
64+
real4 FLOAT,
65+
66+
num1 NUMERIC,
67+
num2 DECIMAL(10, 5),
68+
num22 DECIMAL(10, 5),
69+
num222 DECIMAL(10, 5),
70+
num3 BOOLEAN,
71+
num4 DATE,
72+
num5 DATETIME,
73+
74+
CONSTRAINT [PK_Efrpg] PRIMARY KEY (Id)
4675
);
76+
4777
CREATE TABLE EfrpgItems
4878
(
4979
Id INTEGER PRIMARY KEY,
5080
EfrpgId INTEGER NOT NULL,
81+
Test INT NOT NULL,
5182
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
52-
FOREIGN KEY (EfrpgId) REFERENCES 'Efrpg' (Id)
53-
ON DELETE NO ACTION ON UPDATE NO ACTION
83+
FOREIGN KEY (EfrpgId) REFERENCES [Efrpg] (Id)
84+
ON DELETE CASCADE ON UPDATE NO ACTION
5485
);
55-
CREATE INDEX [IX_Efrpg_vc] ON [Efrpg] ([vc]);";
86+
87+
CREATE INDEX [IX_Efrpg] ON [Efrpg] ([TEXT3]);
88+
CREATE INDEX [IX_Efrpg_Composite] ON [Efrpg] (int1, int2);
89+
90+
CREATE VIEW ThisIsAView AS
91+
SELECT Id, text1, int1, blob1, real1, num1
92+
FROM Efrpg;
93+
94+
CREATE TRIGGER efrpg_trigger
95+
AFTER INSERT
96+
ON Efrpg
97+
BEGIN
98+
SELECT 'Test';
99+
END;
100+
101+
INSERT INTO Efrpg (Id, int1, int2)
102+
VALUES (1, 2, 3),
103+
(2, 3, 4);
104+
INSERT INTO EfrpgItems (Id, EfrpgId, Test)
105+
VALUES (1, 1, 3),
106+
(2, 2, 4);
107+
";
56108
cmd.ExecuteNonQuery();
57109
}
58110

0 commit comments

Comments
 (0)