subsonic 3.0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/LICENSE.txt +41 -0
- data/lib/SubSonic.Core.dll +0 -0
- data/lib/T4 Templates/ActiveRecord/ActiveRecord.tt +620 -0
- data/lib/T4 Templates/ActiveRecord/Context.tt +295 -0
- data/lib/T4 Templates/ActiveRecord/SQLServer.ttinclude +347 -0
- data/lib/T4 Templates/ActiveRecord/Settings.ttinclude +552 -0
- data/lib/T4 Templates/ActiveRecord/StoredProcedures.tt +30 -0
- data/lib/T4 Templates/ActiveRecord/Structs.tt +67 -0
- data/lib/T4 Templates/LinqTemplates/Classes.tt +117 -0
- data/lib/T4 Templates/LinqTemplates/Context.tt +276 -0
- data/lib/T4 Templates/LinqTemplates/SQLServer.ttinclude +349 -0
- data/lib/T4 Templates/LinqTemplates/Settings.ttinclude +551 -0
- data/lib/T4 Templates/LinqTemplates/StoredProcedures.tt +30 -0
- data/lib/T4 Templates/LinqTemplates/Structs.tt +67 -0
- data/lib/T4 Templates/README.txt +7 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/ActiveRecord.tt +560 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/ActiveRecord.vb +6447 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Context.tt +258 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Context.vb +349 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/SQLServer.ttinclude +332 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Settings.ttinclude +550 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/StoredProcedures.tt +30 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/StoredProcedures.vb +55 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Structs.tt +57 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Structs.vb +1478 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Tests/FetchTests.vb +52 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/App.config +9 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Application.Designer.vb +13 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Application.myapp +10 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/AssemblyInfo.vb +35 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Resources.Designer.vb +63 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Resources.resx +117 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Settings.Designer.vb +73 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Settings.settings +7 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/SubSonic.TemplatesVB.vbproj +171 -0
- data/lib/T4 Templates/SubSonic.TemplatesVB/SubSonic.TemplatesVB.vbproj.user +5 -0
- data/lib/T4 Templates/TemplateProviders/MySQL.ttinclude +278 -0
- data/lib/T4 Templates/TemplateProviders/MySQL.ttinclude.orig +303 -0
- data/lib/T4 Templates/TemplateProviders/MySQLTest.tt +27 -0
- data/lib/T4 Templates/TemplateProviders/SQLite.ttinclude +194 -0
- data/lib/T4 Templates/TemplateProviders/SQLite.ttinclude.orig +236 -0
- data/lib/T4 Templates/TemplateProviders/SQLiteTest.tt +27 -0
- data/lib/T4 Templates/TemplateProviders/Settings.ttinclude +551 -0
- metadata +112 -0
@@ -0,0 +1,349 @@
|
|
1
|
+
<#@ include file="Settings.ttinclude" #>
|
2
|
+
<#+
|
3
|
+
|
4
|
+
IDataReader GetReader(string sql)
|
5
|
+
{
|
6
|
+
SqlConnection conn = new SqlConnection(ConnectionString);
|
7
|
+
SqlCommand cmd = new SqlCommand(sql, conn);
|
8
|
+
conn.Open();
|
9
|
+
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
|
10
|
+
}
|
11
|
+
|
12
|
+
SqlCommand GetCommand(string sql)
|
13
|
+
{
|
14
|
+
SqlConnection conn = new SqlConnection(ConnectionString);
|
15
|
+
SqlCommand cmd = new SqlCommand(sql, conn);
|
16
|
+
conn.Open();
|
17
|
+
return cmd;
|
18
|
+
}
|
19
|
+
|
20
|
+
const string FKSql=@"SELECT
|
21
|
+
ThisTable = FK.TABLE_NAME,
|
22
|
+
ThisColumn = CU.COLUMN_NAME,
|
23
|
+
OtherTable = PK.TABLE_NAME,
|
24
|
+
OtherColumn = PT.COLUMN_NAME,
|
25
|
+
Constraint_Name = C.CONSTRAINT_NAME,
|
26
|
+
Owner = FK.TABLE_SCHEMA
|
27
|
+
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
|
28
|
+
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
|
29
|
+
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
|
30
|
+
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
|
31
|
+
INNER JOIN
|
32
|
+
(
|
33
|
+
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
|
34
|
+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
|
35
|
+
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
|
36
|
+
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
|
37
|
+
)
|
38
|
+
PT ON PT.TABLE_NAME = PK.TABLE_NAME
|
39
|
+
WHERE FK.Table_NAME=@tableName OR PK.Table_NAME=@tableName";
|
40
|
+
|
41
|
+
const string TABLE_SQL=@"SELECT *
|
42
|
+
FROM INFORMATION_SCHEMA.TABLES
|
43
|
+
WHERE TABLE_TYPE='BASE TABLE'";
|
44
|
+
|
45
|
+
const string COLUMN_SQL=@"SELECT
|
46
|
+
TABLE_CATALOG AS [Database],
|
47
|
+
TABLE_SCHEMA AS Owner,
|
48
|
+
TABLE_NAME AS TableName,
|
49
|
+
COLUMN_NAME AS ColumnName,
|
50
|
+
ORDINAL_POSITION AS OrdinalPosition,
|
51
|
+
COLUMN_DEFAULT AS DefaultSetting,
|
52
|
+
IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType,
|
53
|
+
CHARACTER_MAXIMUM_LENGTH AS MaxLength,
|
54
|
+
DATETIME_PRECISION AS DatePrecision,
|
55
|
+
COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity,
|
56
|
+
COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed
|
57
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
58
|
+
WHERE TABLE_NAME=@tableName
|
59
|
+
ORDER BY OrdinalPosition ASC";
|
60
|
+
|
61
|
+
|
62
|
+
List<SPParam> GetSPParams(string spName)
|
63
|
+
{
|
64
|
+
var result = new List<SPParam>();
|
65
|
+
string[] restrictions = new string[4] { DatabaseName, null, spName, null };
|
66
|
+
using(SqlConnection conn = new SqlConnection(ConnectionString))
|
67
|
+
{
|
68
|
+
conn.Open();
|
69
|
+
var sprocs = conn.GetSchema("ProcedureParameters", restrictions);
|
70
|
+
conn.Close();
|
71
|
+
|
72
|
+
foreach(DataRow row in sprocs.Select(string.Empty, "ORDINAL_POSITION"))
|
73
|
+
{
|
74
|
+
SPParam p = new SPParam();
|
75
|
+
p.SysType = GetSysType(row["DATA_TYPE"].ToString());
|
76
|
+
p.DbType = GetDbType(row["DATA_TYPE"].ToString()).ToString();
|
77
|
+
p.Name = row["PARAMETER_NAME"].ToString().Replace("@", string.Empty);
|
78
|
+
p.CleanName = CleanUp(p.Name);
|
79
|
+
result.Add(p);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
return result;
|
83
|
+
}
|
84
|
+
|
85
|
+
List<SP> GetSPs()
|
86
|
+
{
|
87
|
+
var result = new List<SP>();
|
88
|
+
//pull the SPs
|
89
|
+
|
90
|
+
DataTable sprocs = null;
|
91
|
+
DataTable parameters = null;
|
92
|
+
|
93
|
+
using(SqlConnection conn = new SqlConnection(ConnectionString))
|
94
|
+
{
|
95
|
+
conn.Open();
|
96
|
+
sprocs = conn.GetSchema("Procedures");
|
97
|
+
conn.Close();
|
98
|
+
}
|
99
|
+
|
100
|
+
foreach(DataRow row in sprocs.Rows)
|
101
|
+
{
|
102
|
+
string spType = row["ROUTINE_TYPE"].ToString();
|
103
|
+
var sp = new SP();
|
104
|
+
sp.Name = row["ROUTINE_NAME"].ToString();
|
105
|
+
|
106
|
+
if(spType == "PROCEDURE" & !sp.Name.StartsWith("sp_"))
|
107
|
+
{
|
108
|
+
sp.CleanName = CleanUp(sp.Name);
|
109
|
+
sp.Parameters = GetSPParams(sp.Name);
|
110
|
+
result.Add(sp);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return result;
|
114
|
+
}
|
115
|
+
|
116
|
+
|
117
|
+
List<Table> LoadTables()
|
118
|
+
{
|
119
|
+
var result = new List<Table>();
|
120
|
+
//pull the tables in a reader
|
121
|
+
using(IDataReader rdr=GetReader(TABLE_SQL))
|
122
|
+
{
|
123
|
+
while(rdr.Read())
|
124
|
+
{
|
125
|
+
Table tbl = new Table();
|
126
|
+
tbl.Name = rdr["TABLE_NAME"].ToString();
|
127
|
+
tbl.Schema = rdr["TABLE_SCHEMA"].ToString();
|
128
|
+
tbl.Columns = LoadColumns(tbl);
|
129
|
+
tbl.PrimaryKey = GetPK(tbl.Name);
|
130
|
+
tbl.CleanName = CleanUp(tbl.Name);
|
131
|
+
tbl.ClassName = Inflector.MakeSingular(tbl.CleanName);
|
132
|
+
tbl.QueryableName = Inflector.MakePlural(tbl.ClassName);
|
133
|
+
|
134
|
+
//set the PK for the columns
|
135
|
+
var pkColumn = tbl.Columns.SingleOrDefault(x => x.Name.ToLower().Trim() == tbl.PrimaryKey.ToLower().Trim());
|
136
|
+
if(pkColumn != null)
|
137
|
+
pkColumn.IsPK = true;
|
138
|
+
|
139
|
+
tbl.FKTables = LoadFKTables(tbl.Name);
|
140
|
+
result.Add(tbl);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
foreach(Table tbl in result)
|
145
|
+
{
|
146
|
+
//loop the FK tables and see if there's a match for our FK columns
|
147
|
+
foreach(Column col in tbl.Columns)
|
148
|
+
{
|
149
|
+
col.IsForeignKey=tbl.FKTables.Any(x => x.ThisColumn.Equals(col.Name, StringComparison.InvariantCultureIgnoreCase));
|
150
|
+
}
|
151
|
+
}
|
152
|
+
return result;
|
153
|
+
}
|
154
|
+
|
155
|
+
List<Column> LoadColumns(Table tbl)
|
156
|
+
{
|
157
|
+
var result = new List<Column>();
|
158
|
+
var cmd = GetCommand(COLUMN_SQL);
|
159
|
+
cmd.Parameters.AddWithValue("@tableName", tbl.Name);
|
160
|
+
|
161
|
+
using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection))
|
162
|
+
{
|
163
|
+
while(rdr.Read())
|
164
|
+
{
|
165
|
+
Column col = new Column();
|
166
|
+
col.Name = rdr["ColumnName"].ToString();
|
167
|
+
col.CleanName = CleanUp(col.Name);
|
168
|
+
col.DataType = rdr["DataType"].ToString();
|
169
|
+
col.SysType = GetSysType(col.DataType);
|
170
|
+
col.DbType = GetDbType(col.DataType);
|
171
|
+
col.AutoIncrement = rdr["IsIdentity"].ToString() == "1";
|
172
|
+
col.IsNullable = rdr["IsNullable"].ToString() == "YES";
|
173
|
+
int.TryParse(rdr["MaxLength"].ToString(), out col.MaxLength);
|
174
|
+
|
175
|
+
result.Add(col);
|
176
|
+
}
|
177
|
+
|
178
|
+
}
|
179
|
+
return result;
|
180
|
+
}
|
181
|
+
|
182
|
+
List<FKTable> LoadFKTables(string tableName)
|
183
|
+
{
|
184
|
+
//this is a "bi-directional" scheme
|
185
|
+
//which pulls both 1-many and many-1
|
186
|
+
|
187
|
+
var result = new List<FKTable>();
|
188
|
+
var cmd = GetCommand(FKSql);
|
189
|
+
cmd.Parameters.AddWithValue("@tableName", tableName);
|
190
|
+
using(IDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
|
191
|
+
{
|
192
|
+
while(rdr.Read())
|
193
|
+
{
|
194
|
+
FKTable fk = new FKTable();
|
195
|
+
string thisTable = rdr["ThisTable"].ToString();
|
196
|
+
|
197
|
+
if(tableName.ToLower() == thisTable.ToLower())
|
198
|
+
{
|
199
|
+
fk.ThisTable = rdr["ThisTable"].ToString();
|
200
|
+
fk.ThisColumn = rdr["ThisColumn"].ToString();
|
201
|
+
fk.OtherTable = rdr["OtherTable"].ToString();
|
202
|
+
fk.OtherColumn = rdr["OtherColumn"].ToString();
|
203
|
+
}
|
204
|
+
else
|
205
|
+
{
|
206
|
+
fk.ThisTable = rdr["OtherTable"].ToString();
|
207
|
+
fk.ThisColumn = rdr["OtherColumn"].ToString();
|
208
|
+
fk.OtherTable = rdr["ThisTable"].ToString();
|
209
|
+
fk.OtherColumn = rdr["ThisColumn"].ToString();
|
210
|
+
}
|
211
|
+
|
212
|
+
fk.OtherClass = Inflector.MakeSingular(CleanUp(fk.OtherTable));
|
213
|
+
fk.OtherQueryable = Inflector.MakePlural(fk.OtherClass);
|
214
|
+
result.Add(fk);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
return result;
|
218
|
+
}
|
219
|
+
|
220
|
+
string GetPK(string table){
|
221
|
+
|
222
|
+
string pk = string.Empty;
|
223
|
+
DataTable pkTable = new DataTable();
|
224
|
+
string sql = @"SELECT KCU.COLUMN_NAME
|
225
|
+
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
|
226
|
+
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
|
227
|
+
ON KCU.CONSTRAINT_NAME=TC.CONSTRAINT_NAME
|
228
|
+
WHERE TC.CONSTRAINT_TYPE='PRIMARY KEY'
|
229
|
+
AND KCU.TABLE_NAME=@tableName";
|
230
|
+
|
231
|
+
var cmd = GetCommand(sql);
|
232
|
+
cmd.Parameters.AddWithValue("@tableName", table);
|
233
|
+
var result = cmd.ExecuteScalar();
|
234
|
+
cmd.Dispose();
|
235
|
+
if(result != null)
|
236
|
+
pk = result.ToString();
|
237
|
+
|
238
|
+
return pk;
|
239
|
+
}
|
240
|
+
|
241
|
+
string GetSysType(string sqlType){
|
242
|
+
string sysType="string";
|
243
|
+
switch (sqlType)
|
244
|
+
{
|
245
|
+
case "bigint":
|
246
|
+
sysType = "long";
|
247
|
+
break;
|
248
|
+
case "smallint":
|
249
|
+
sysType = "short";
|
250
|
+
break;
|
251
|
+
case "int":
|
252
|
+
sysType = "int";
|
253
|
+
break;
|
254
|
+
case "uniqueidentifier":
|
255
|
+
sysType = "Guid";
|
256
|
+
break;
|
257
|
+
case "smalldatetime":
|
258
|
+
case "datetime":
|
259
|
+
sysType = "DateTime";
|
260
|
+
break;
|
261
|
+
case "float":
|
262
|
+
sysType = "double";
|
263
|
+
break;
|
264
|
+
case "real":
|
265
|
+
case "numeric":
|
266
|
+
case "smallmoney":
|
267
|
+
case "decimal":
|
268
|
+
case "money":
|
269
|
+
sysType = "decimal";
|
270
|
+
break;
|
271
|
+
case "tinyint":
|
272
|
+
sysType = "byte";
|
273
|
+
break;
|
274
|
+
case "bit":
|
275
|
+
sysType = "bool";
|
276
|
+
break;
|
277
|
+
case "image":
|
278
|
+
case "binary":
|
279
|
+
case "varbinary":
|
280
|
+
sysType = "byte[]";
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
return sysType;
|
284
|
+
}
|
285
|
+
|
286
|
+
DbType GetDbType(string sqlType)
|
287
|
+
{
|
288
|
+
switch(sqlType)
|
289
|
+
{
|
290
|
+
case "varchar":
|
291
|
+
return DbType.AnsiString;
|
292
|
+
case "nvarchar":
|
293
|
+
return DbType.String;
|
294
|
+
case "int":
|
295
|
+
return DbType.Int32;
|
296
|
+
case "uniqueidentifier":
|
297
|
+
return DbType.Guid;
|
298
|
+
case "datetime":
|
299
|
+
return DbType.DateTime;
|
300
|
+
case "bigint":
|
301
|
+
return DbType.Int64;
|
302
|
+
case "binary":
|
303
|
+
return DbType.Binary;
|
304
|
+
case "bit":
|
305
|
+
return DbType.Boolean;
|
306
|
+
case "char":
|
307
|
+
return DbType.AnsiStringFixedLength;
|
308
|
+
case "decimal":
|
309
|
+
return DbType.Decimal;
|
310
|
+
case "float":
|
311
|
+
return DbType.Double;
|
312
|
+
case "image":
|
313
|
+
return DbType.Binary;
|
314
|
+
case "money":
|
315
|
+
return DbType.Currency;
|
316
|
+
case "nchar":
|
317
|
+
return DbType.String;
|
318
|
+
case "ntext":
|
319
|
+
return DbType.String;
|
320
|
+
case "numeric":
|
321
|
+
return DbType.Decimal;
|
322
|
+
case "real":
|
323
|
+
return DbType.Single;
|
324
|
+
case "smalldatetime":
|
325
|
+
return DbType.DateTime;
|
326
|
+
case "smallint":
|
327
|
+
return DbType.Int16;
|
328
|
+
case "smallmoney":
|
329
|
+
return DbType.Currency;
|
330
|
+
case "sql_variant":
|
331
|
+
return DbType.String;
|
332
|
+
case "sysname":
|
333
|
+
return DbType.String;
|
334
|
+
case "text":
|
335
|
+
return DbType.AnsiString;
|
336
|
+
case "timestamp":
|
337
|
+
return DbType.Binary;
|
338
|
+
case "tinyint":
|
339
|
+
return DbType.Byte;
|
340
|
+
case "varbinary":
|
341
|
+
return DbType.Binary;
|
342
|
+
case "xml":
|
343
|
+
return DbType.Xml;
|
344
|
+
default:
|
345
|
+
return DbType.AnsiString;
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
#>
|
@@ -0,0 +1,551 @@
|
|
1
|
+
<#@ template language="C#v3.5" debug="True" hostspecific="True" #>
|
2
|
+
<#@ assembly name="EnvDTE" #>
|
3
|
+
<#@ assembly name="System.Core.dll" #>
|
4
|
+
<#@ assembly name="System.Data" #>
|
5
|
+
<#@ assembly name="System.Xml" #>
|
6
|
+
<#@ assembly name="System.Configuration" #>
|
7
|
+
<#@ import namespace="System.Collections.Generic" #>
|
8
|
+
<#@ import namespace="System.Data" #>
|
9
|
+
<#@ import namespace="System.Data.SqlClient" #>
|
10
|
+
<#@ import namespace="System.Data.Common" #>
|
11
|
+
<#@ import namespace="System.Diagnostics" #>
|
12
|
+
<#@ import namespace="System.Globalization" #>
|
13
|
+
<#@ import namespace="System.IO" #>
|
14
|
+
<#@ import namespace="System.Linq" #>
|
15
|
+
<#@ import namespace="System.Text" #>
|
16
|
+
<#@ import namespace="System.Text.RegularExpressions" #>
|
17
|
+
<#@ import namespace="System.Configuration" #>
|
18
|
+
|
19
|
+
<#+
|
20
|
+
|
21
|
+
const string Namespace = "GMN.Data.WordPress";
|
22
|
+
const string ConnectionStringName = "GmnWpMu";
|
23
|
+
|
24
|
+
//This is the name of your database and is used in naming
|
25
|
+
//the repository. By default we set it to the connection string name
|
26
|
+
const string DatabaseName = "GmnWpMu";
|
27
|
+
|
28
|
+
const bool TreatTinyint1AsBool = false;
|
29
|
+
|
30
|
+
//this is a list of tables you don't want generated
|
31
|
+
string[] ExcludeTables = new string[]{
|
32
|
+
"sysdiagrams",
|
33
|
+
"BuildVersion",
|
34
|
+
};
|
35
|
+
|
36
|
+
string CleanUp(string tableName){
|
37
|
+
string result=tableName;
|
38
|
+
|
39
|
+
//strip blanks
|
40
|
+
result=result.Replace(" ","");
|
41
|
+
|
42
|
+
//put your logic here...
|
43
|
+
|
44
|
+
return result;
|
45
|
+
}
|
46
|
+
string CheckNullable(Column col){
|
47
|
+
string result="";
|
48
|
+
if(col.IsNullable && col.SysType !="byte[]" && col.SysType !="string")
|
49
|
+
result="?";
|
50
|
+
return result;
|
51
|
+
}
|
52
|
+
string GetConnectionString(string connectionStringName){
|
53
|
+
var _CurrentProject = GetCurrentProject();
|
54
|
+
|
55
|
+
string result="";
|
56
|
+
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
|
57
|
+
configFile.ExeConfigFilename = GetConfigPath();
|
58
|
+
|
59
|
+
if (string.IsNullOrEmpty(configFile.ExeConfigFilename))
|
60
|
+
throw new ArgumentNullException("The project does not contain App.config or Web.config file.");
|
61
|
+
|
62
|
+
|
63
|
+
var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
|
64
|
+
var connSection=config.ConnectionStrings;
|
65
|
+
|
66
|
+
//if the connectionString is empty - which is the defauls
|
67
|
+
//look for count-1 - this is the last connection string
|
68
|
+
//and takes into account AppServices and LocalSqlServer
|
69
|
+
if(string.IsNullOrEmpty(connectionStringName)){
|
70
|
+
if(connSection.ConnectionStrings.Count>1){
|
71
|
+
result=connSection.ConnectionStrings[connSection.ConnectionStrings.Count-1].ConnectionString;
|
72
|
+
}
|
73
|
+
}else{
|
74
|
+
try{
|
75
|
+
result=connSection.ConnectionStrings[connectionStringName].ConnectionString;
|
76
|
+
}catch{
|
77
|
+
result="There is no connection string name called '"+connectionStringName+"'";
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
return result;
|
82
|
+
}
|
83
|
+
|
84
|
+
string _connectionString="";
|
85
|
+
public string ConnectionString{
|
86
|
+
get {
|
87
|
+
if(String.IsNullOrEmpty(_connectionString)){
|
88
|
+
|
89
|
+
_connectionString=GetConnectionString(ConnectionStringName);
|
90
|
+
|
91
|
+
}
|
92
|
+
|
93
|
+
if(_connectionString.Contains("|DataDirectory|")){
|
94
|
+
//have to replace it
|
95
|
+
string dataFilePath=GetDataDirectory();
|
96
|
+
_connectionString=_connectionString.Replace("|DataDirectory|",dataFilePath);
|
97
|
+
}
|
98
|
+
|
99
|
+
return _connectionString;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
public EnvDTE.Project GetCurrentProject() {
|
104
|
+
|
105
|
+
IServiceProvider _ServiceProvider = (IServiceProvider)Host;
|
106
|
+
if (_ServiceProvider == null)
|
107
|
+
throw new Exception("Host property returned unexpected value (null)");
|
108
|
+
|
109
|
+
EnvDTE.DTE dte = (EnvDTE.DTE)_ServiceProvider.GetService(typeof(EnvDTE.DTE));
|
110
|
+
if (dte == null)
|
111
|
+
throw new Exception("Unable to retrieve EnvDTE.DTE");
|
112
|
+
|
113
|
+
Array activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
|
114
|
+
if (activeSolutionProjects == null)
|
115
|
+
throw new Exception("DTE.ActiveSolutionProjects returned null");
|
116
|
+
|
117
|
+
EnvDTE.Project dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
|
118
|
+
if (dteProject == null)
|
119
|
+
throw new Exception("DTE.ActiveSolutionProjects[0] returned null");
|
120
|
+
|
121
|
+
return dteProject;
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
private string GetProjectPath()
|
126
|
+
{
|
127
|
+
EnvDTE.Project project = GetCurrentProject();
|
128
|
+
System.IO.FileInfo info = new System.IO.FileInfo(project.FullName);
|
129
|
+
return info.Directory.FullName;
|
130
|
+
}
|
131
|
+
|
132
|
+
private string GetConfigPath()
|
133
|
+
{
|
134
|
+
EnvDTE.Project project = GetCurrentProject();
|
135
|
+
foreach (EnvDTE.ProjectItem item in project.ProjectItems)
|
136
|
+
{
|
137
|
+
// if it is the app.config file, then open it up
|
138
|
+
if (item.Name.Equals("App.config",StringComparison.InvariantCultureIgnoreCase) || item.Name.Equals("Web.config",StringComparison.InvariantCultureIgnoreCase))
|
139
|
+
return GetProjectPath() + "\\" + item.Name;
|
140
|
+
}
|
141
|
+
return String.Empty;
|
142
|
+
}
|
143
|
+
|
144
|
+
public string GetDataDirectory(){
|
145
|
+
EnvDTE.Project project=GetCurrentProject();
|
146
|
+
return System.IO.Path.GetDirectoryName(project.FileName)+"\\App_Data\\";
|
147
|
+
}
|
148
|
+
|
149
|
+
public class Table{
|
150
|
+
|
151
|
+
public List<Column> Columns;
|
152
|
+
public List<FKTable> FKTables;
|
153
|
+
public string Name;
|
154
|
+
public string CleanName;
|
155
|
+
public string ClassName;
|
156
|
+
public string PrimaryKey;
|
157
|
+
public string Schema;
|
158
|
+
public string QueryableName;
|
159
|
+
|
160
|
+
public bool HasLogicalDelete(){
|
161
|
+
return this.Columns.Any(x=>x.Name.ToLower()=="deleted" || x.Name.ToLower()=="isdeleted");
|
162
|
+
}
|
163
|
+
public Column DeleteColumn{
|
164
|
+
get{
|
165
|
+
Column result=null;
|
166
|
+
if(this.Columns.Any(x=>x.Name.ToLower()=="deleted"))
|
167
|
+
result=this.Columns.Single(x=>x.Name.ToLower()=="deleted");
|
168
|
+
if(this.Columns.Any(x=>x.Name.ToLower()=="isdeleted"))
|
169
|
+
result=this.Columns.Single(x=>x.Name.ToLower()=="isdeleted");
|
170
|
+
return result;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
public Column PK{
|
174
|
+
get{
|
175
|
+
return this.Columns.FirstOrDefault(x=>x.IsPK) ?? this.Columns[0];
|
176
|
+
}
|
177
|
+
}
|
178
|
+
public Column Descriptor{
|
179
|
+
get{
|
180
|
+
if(this.Columns.Count==1){
|
181
|
+
return this.Columns[0];
|
182
|
+
}else{
|
183
|
+
//get the first string column
|
184
|
+
Column result=null;
|
185
|
+
result=this.Columns.FirstOrDefault(x=>x.SysType.ToLower().Trim()=="string");
|
186
|
+
if(result==null)
|
187
|
+
result=this.Columns[1];
|
188
|
+
return result;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
public class Column{
|
195
|
+
public string Name;
|
196
|
+
public string CleanName;
|
197
|
+
public string SysType;
|
198
|
+
public string DataType;
|
199
|
+
public DbType DbType;
|
200
|
+
public bool AutoIncrement;
|
201
|
+
public bool IsPK;
|
202
|
+
public int MaxLength;
|
203
|
+
public bool IsNullable;
|
204
|
+
public bool IsForeignKey;
|
205
|
+
public bool IsUnsigned;
|
206
|
+
}
|
207
|
+
public class FKTable{
|
208
|
+
public string ThisTable;
|
209
|
+
public string ThisColumn;
|
210
|
+
public string OtherTable;
|
211
|
+
public string OtherColumn;
|
212
|
+
public string OtherClass;
|
213
|
+
public string OtherQueryable;
|
214
|
+
}
|
215
|
+
|
216
|
+
public class SP{
|
217
|
+
public string Name;
|
218
|
+
public string CleanName;
|
219
|
+
public string ClassName;
|
220
|
+
public List<SPParam> Parameters;
|
221
|
+
public SP(){
|
222
|
+
Parameters=new List<SPParam>();
|
223
|
+
}
|
224
|
+
public string ArgList{
|
225
|
+
get{
|
226
|
+
StringBuilder sb=new StringBuilder();
|
227
|
+
int loopCount=1;
|
228
|
+
foreach(var par in Parameters){
|
229
|
+
sb.AppendFormat("{0} {1}", par.SysType,par.CleanName);
|
230
|
+
if(loopCount<Parameters.Count)
|
231
|
+
sb.Append(",");
|
232
|
+
loopCount++;
|
233
|
+
}
|
234
|
+
return sb.ToString();
|
235
|
+
}
|
236
|
+
}
|
237
|
+
}
|
238
|
+
public class SPParam{
|
239
|
+
public string Name;
|
240
|
+
public string CleanName;
|
241
|
+
public string SysType;
|
242
|
+
public string DbType;
|
243
|
+
}
|
244
|
+
|
245
|
+
|
246
|
+
/*
|
247
|
+
* SubSonic - http://subsonicproject.com
|
248
|
+
*
|
249
|
+
* The contents of this file are subject to the New BSD
|
250
|
+
* License (the "License"); you may not use this file
|
251
|
+
* except in compliance with the License. You may obtain a copy of
|
252
|
+
* the License at http://www.opensource.org/licenses/bsd-license.php
|
253
|
+
*
|
254
|
+
* Software distributed under the License is distributed on an
|
255
|
+
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
256
|
+
* implied. See the License for the specific language governing
|
257
|
+
* rights and limitations under the License.
|
258
|
+
*/
|
259
|
+
|
260
|
+
/// <summary>
|
261
|
+
/// Summary for the Inflector class
|
262
|
+
/// </summary>
|
263
|
+
public static class Inflector {
|
264
|
+
private static readonly List<InflectorRule> _plurals = new List<InflectorRule>();
|
265
|
+
private static readonly List<InflectorRule> _singulars = new List<InflectorRule>();
|
266
|
+
private static readonly List<string> _uncountables = new List<string>();
|
267
|
+
|
268
|
+
/// <summary>
|
269
|
+
/// Initializes the <see cref="Inflector"/> class.
|
270
|
+
/// </summary>
|
271
|
+
static Inflector() {
|
272
|
+
AddPluralRule("$", "s");
|
273
|
+
AddPluralRule("s$", "s");
|
274
|
+
AddPluralRule("(ax|test)is$", "$1es");
|
275
|
+
AddPluralRule("(octop|vir)us$", "$1i");
|
276
|
+
AddPluralRule("(alias|status)$", "$1es");
|
277
|
+
AddPluralRule("(bu)s$", "$1ses");
|
278
|
+
AddPluralRule("(buffal|tomat)o$", "$1oes");
|
279
|
+
AddPluralRule("([ti])um$", "$1a");
|
280
|
+
AddPluralRule("sis$", "ses");
|
281
|
+
AddPluralRule("(?:([^f])fe|([lr])f)$", "$1$2ves");
|
282
|
+
AddPluralRule("(hive)$", "$1s");
|
283
|
+
AddPluralRule("([^aeiouy]|qu)y$", "$1ies");
|
284
|
+
AddPluralRule("(x|ch|ss|sh)$", "$1es");
|
285
|
+
AddPluralRule("(matr|vert|ind)ix|ex$", "$1ices");
|
286
|
+
AddPluralRule("([m|l])ouse$", "$1ice");
|
287
|
+
AddPluralRule("^(ox)$", "$1en");
|
288
|
+
AddPluralRule("(quiz)$", "$1zes");
|
289
|
+
|
290
|
+
AddSingularRule("s$", String.Empty);
|
291
|
+
AddSingularRule("ss$", "ss");
|
292
|
+
AddSingularRule("(n)ews$", "$1ews");
|
293
|
+
AddSingularRule("([ti])a$", "$1um");
|
294
|
+
AddSingularRule("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
|
295
|
+
AddSingularRule("(^analy)ses$", "$1sis");
|
296
|
+
AddSingularRule("([^f])ves$", "$1fe");
|
297
|
+
AddSingularRule("(hive)s$", "$1");
|
298
|
+
AddSingularRule("(tive)s$", "$1");
|
299
|
+
AddSingularRule("([lr])ves$", "$1f");
|
300
|
+
AddSingularRule("([^aeiouy]|qu)ies$", "$1y");
|
301
|
+
AddSingularRule("(s)eries$", "$1eries");
|
302
|
+
AddSingularRule("(m)ovies$", "$1ovie");
|
303
|
+
AddSingularRule("(x|ch|ss|sh)es$", "$1");
|
304
|
+
AddSingularRule("([m|l])ice$", "$1ouse");
|
305
|
+
AddSingularRule("(bus)es$", "$1");
|
306
|
+
AddSingularRule("(o)es$", "$1");
|
307
|
+
AddSingularRule("(shoe)s$", "$1");
|
308
|
+
AddSingularRule("(cris|ax|test)es$", "$1is");
|
309
|
+
AddSingularRule("(octop|vir)i$", "$1us");
|
310
|
+
AddSingularRule("(alias|status)$", "$1");
|
311
|
+
AddSingularRule("(alias|status)es$", "$1");
|
312
|
+
AddSingularRule("^(ox)en", "$1");
|
313
|
+
AddSingularRule("(vert|ind)ices$", "$1ex");
|
314
|
+
AddSingularRule("(matr)ices$", "$1ix");
|
315
|
+
AddSingularRule("(quiz)zes$", "$1");
|
316
|
+
|
317
|
+
AddIrregularRule("person", "people");
|
318
|
+
AddIrregularRule("man", "men");
|
319
|
+
AddIrregularRule("child", "children");
|
320
|
+
AddIrregularRule("sex", "sexes");
|
321
|
+
AddIrregularRule("tax", "taxes");
|
322
|
+
AddIrregularRule("move", "moves");
|
323
|
+
|
324
|
+
AddUnknownCountRule("equipment");
|
325
|
+
AddUnknownCountRule("information");
|
326
|
+
AddUnknownCountRule("rice");
|
327
|
+
AddUnknownCountRule("money");
|
328
|
+
AddUnknownCountRule("species");
|
329
|
+
AddUnknownCountRule("series");
|
330
|
+
AddUnknownCountRule("fish");
|
331
|
+
AddUnknownCountRule("sheep");
|
332
|
+
}
|
333
|
+
|
334
|
+
/// <summary>
|
335
|
+
/// Adds the irregular rule.
|
336
|
+
/// </summary>
|
337
|
+
/// <param name="singular">The singular.</param>
|
338
|
+
/// <param name="plural">The plural.</param>
|
339
|
+
private static void AddIrregularRule(string singular, string plural) {
|
340
|
+
AddPluralRule(String.Concat("(", singular[0], ")", singular.Substring(1), "$"), String.Concat("$1", plural.Substring(1)));
|
341
|
+
AddSingularRule(String.Concat("(", plural[0], ")", plural.Substring(1), "$"), String.Concat("$1", singular.Substring(1)));
|
342
|
+
}
|
343
|
+
|
344
|
+
/// <summary>
|
345
|
+
/// Adds the unknown count rule.
|
346
|
+
/// </summary>
|
347
|
+
/// <param name="word">The word.</param>
|
348
|
+
private static void AddUnknownCountRule(string word) {
|
349
|
+
_uncountables.Add(word.ToLower());
|
350
|
+
}
|
351
|
+
|
352
|
+
/// <summary>
|
353
|
+
/// Adds the plural rule.
|
354
|
+
/// </summary>
|
355
|
+
/// <param name="rule">The rule.</param>
|
356
|
+
/// <param name="replacement">The replacement.</param>
|
357
|
+
private static void AddPluralRule(string rule, string replacement) {
|
358
|
+
_plurals.Add(new InflectorRule(rule, replacement));
|
359
|
+
}
|
360
|
+
|
361
|
+
/// <summary>
|
362
|
+
/// Adds the singular rule.
|
363
|
+
/// </summary>
|
364
|
+
/// <param name="rule">The rule.</param>
|
365
|
+
/// <param name="replacement">The replacement.</param>
|
366
|
+
private static void AddSingularRule(string rule, string replacement) {
|
367
|
+
_singulars.Add(new InflectorRule(rule, replacement));
|
368
|
+
}
|
369
|
+
|
370
|
+
/// <summary>
|
371
|
+
/// Makes the plural.
|
372
|
+
/// </summary>
|
373
|
+
/// <param name="word">The word.</param>
|
374
|
+
/// <returns></returns>
|
375
|
+
public static string MakePlural(string word) {
|
376
|
+
return ApplyRules(_plurals, word);
|
377
|
+
}
|
378
|
+
|
379
|
+
/// <summary>
|
380
|
+
/// Makes the singular.
|
381
|
+
/// </summary>
|
382
|
+
/// <param name="word">The word.</param>
|
383
|
+
/// <returns></returns>
|
384
|
+
public static string MakeSingular(string word) {
|
385
|
+
return ApplyRules(_singulars, word);
|
386
|
+
}
|
387
|
+
|
388
|
+
/// <summary>
|
389
|
+
/// Applies the rules.
|
390
|
+
/// </summary>
|
391
|
+
/// <param name="rules">The rules.</param>
|
392
|
+
/// <param name="word">The word.</param>
|
393
|
+
/// <returns></returns>
|
394
|
+
private static string ApplyRules(IList<InflectorRule> rules, string word) {
|
395
|
+
string result = word;
|
396
|
+
if (!_uncountables.Contains(word.ToLower())) {
|
397
|
+
for (int i = rules.Count - 1; i >= 0; i--) {
|
398
|
+
string currentPass = rules[i].Apply(word);
|
399
|
+
if (currentPass != null) {
|
400
|
+
result = currentPass;
|
401
|
+
break;
|
402
|
+
}
|
403
|
+
}
|
404
|
+
}
|
405
|
+
return result;
|
406
|
+
}
|
407
|
+
|
408
|
+
/// <summary>
|
409
|
+
/// Converts the string to title case.
|
410
|
+
/// </summary>
|
411
|
+
/// <param name="word">The word.</param>
|
412
|
+
/// <returns></returns>
|
413
|
+
public static string ToTitleCase(string word) {
|
414
|
+
return Regex.Replace(ToHumanCase(AddUnderscores(word)), @"\b([a-z])",
|
415
|
+
delegate(Match match) { return match.Captures[0].Value.ToUpper(); });
|
416
|
+
}
|
417
|
+
|
418
|
+
/// <summary>
|
419
|
+
/// Converts the string to human case.
|
420
|
+
/// </summary>
|
421
|
+
/// <param name="lowercaseAndUnderscoredWord">The lowercase and underscored word.</param>
|
422
|
+
/// <returns></returns>
|
423
|
+
public static string ToHumanCase(string lowercaseAndUnderscoredWord) {
|
424
|
+
return MakeInitialCaps(Regex.Replace(lowercaseAndUnderscoredWord, @"_", " "));
|
425
|
+
}
|
426
|
+
|
427
|
+
|
428
|
+
/// <summary>
|
429
|
+
/// Adds the underscores.
|
430
|
+
/// </summary>
|
431
|
+
/// <param name="pascalCasedWord">The pascal cased word.</param>
|
432
|
+
/// <returns></returns>
|
433
|
+
public static string AddUnderscores(string pascalCasedWord) {
|
434
|
+
return Regex.Replace(Regex.Replace(Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1_$2"), @"([a-z\d])([A-Z])", "$1_$2"), @"[-\s]", "_").ToLower();
|
435
|
+
}
|
436
|
+
|
437
|
+
/// <summary>
|
438
|
+
/// Makes the initial caps.
|
439
|
+
/// </summary>
|
440
|
+
/// <param name="word">The word.</param>
|
441
|
+
/// <returns></returns>
|
442
|
+
public static string MakeInitialCaps(string word) {
|
443
|
+
return String.Concat(word.Substring(0, 1).ToUpper(), word.Substring(1).ToLower());
|
444
|
+
}
|
445
|
+
|
446
|
+
/// <summary>
|
447
|
+
/// Makes the initial lower case.
|
448
|
+
/// </summary>
|
449
|
+
/// <param name="word">The word.</param>
|
450
|
+
/// <returns></returns>
|
451
|
+
public static string MakeInitialLowerCase(string word) {
|
452
|
+
return String.Concat(word.Substring(0, 1).ToLower(), word.Substring(1));
|
453
|
+
}
|
454
|
+
|
455
|
+
|
456
|
+
/// <summary>
|
457
|
+
/// Determine whether the passed string is numeric, by attempting to parse it to a double
|
458
|
+
/// </summary>
|
459
|
+
/// <param name="str">The string to evaluated for numeric conversion</param>
|
460
|
+
/// <returns>
|
461
|
+
/// <c>true</c> if the string can be converted to a number; otherwise, <c>false</c>.
|
462
|
+
/// </returns>
|
463
|
+
public static bool IsStringNumeric(string str) {
|
464
|
+
double result;
|
465
|
+
return (double.TryParse(str, NumberStyles.Float, NumberFormatInfo.CurrentInfo, out result));
|
466
|
+
}
|
467
|
+
|
468
|
+
/// <summary>
|
469
|
+
/// Adds the ordinal suffix.
|
470
|
+
/// </summary>
|
471
|
+
/// <param name="number">The number.</param>
|
472
|
+
/// <returns></returns>
|
473
|
+
public static string AddOrdinalSuffix(string number) {
|
474
|
+
if (IsStringNumeric(number)) {
|
475
|
+
int n = int.Parse(number);
|
476
|
+
int nMod100 = n % 100;
|
477
|
+
|
478
|
+
if (nMod100 >= 11 && nMod100 <= 13)
|
479
|
+
return String.Concat(number, "th");
|
480
|
+
|
481
|
+
switch (n % 10) {
|
482
|
+
case 1:
|
483
|
+
return String.Concat(number, "st");
|
484
|
+
case 2:
|
485
|
+
return String.Concat(number, "nd");
|
486
|
+
case 3:
|
487
|
+
return String.Concat(number, "rd");
|
488
|
+
default:
|
489
|
+
return String.Concat(number, "th");
|
490
|
+
}
|
491
|
+
}
|
492
|
+
return number;
|
493
|
+
}
|
494
|
+
|
495
|
+
/// <summary>
|
496
|
+
/// Converts the underscores to dashes.
|
497
|
+
/// </summary>
|
498
|
+
/// <param name="underscoredWord">The underscored word.</param>
|
499
|
+
/// <returns></returns>
|
500
|
+
public static string ConvertUnderscoresToDashes(string underscoredWord) {
|
501
|
+
return underscoredWord.Replace('_', '-');
|
502
|
+
}
|
503
|
+
|
504
|
+
|
505
|
+
#region Nested type: InflectorRule
|
506
|
+
|
507
|
+
/// <summary>
|
508
|
+
/// Summary for the InflectorRule class
|
509
|
+
/// </summary>
|
510
|
+
private class InflectorRule {
|
511
|
+
/// <summary>
|
512
|
+
///
|
513
|
+
/// </summary>
|
514
|
+
public readonly Regex regex;
|
515
|
+
|
516
|
+
/// <summary>
|
517
|
+
///
|
518
|
+
/// </summary>
|
519
|
+
public readonly string replacement;
|
520
|
+
|
521
|
+
/// <summary>
|
522
|
+
/// Initializes a new instance of the <see cref="InflectorRule"/> class.
|
523
|
+
/// </summary>
|
524
|
+
/// <param name="regexPattern">The regex pattern.</param>
|
525
|
+
/// <param name="replacementText">The replacement text.</param>
|
526
|
+
public InflectorRule(string regexPattern, string replacementText) {
|
527
|
+
regex = new Regex(regexPattern, RegexOptions.IgnoreCase);
|
528
|
+
replacement = replacementText;
|
529
|
+
}
|
530
|
+
|
531
|
+
/// <summary>
|
532
|
+
/// Applies the specified word.
|
533
|
+
/// </summary>
|
534
|
+
/// <param name="word">The word.</param>
|
535
|
+
/// <returns></returns>
|
536
|
+
public string Apply(string word) {
|
537
|
+
if (!regex.IsMatch(word))
|
538
|
+
return null;
|
539
|
+
|
540
|
+
string replace = regex.Replace(word, replacement);
|
541
|
+
if (word == word.ToUpper())
|
542
|
+
replace = replace.ToUpper();
|
543
|
+
|
544
|
+
return replace;
|
545
|
+
}
|
546
|
+
}
|
547
|
+
|
548
|
+
#endregion
|
549
|
+
}
|
550
|
+
|
551
|
+
#>
|