subsonic 3.0.0.4

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